parent
035d6fb154
commit
355b3f51d8
|
@ -0,0 +1,12 @@
|
|||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
/node_modules
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear on external disk
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
![module info](https://nodei.co/npm/bash-ip.png?downloads=true&downloadRank=true&stars=true)
|
||||
|
||||
# bash-ip
|
||||
> `bash-ip` 类似于linux下的简单版的ip命令工具. 目前只实现了几个用法, 后续会慢慢完善。
|
||||
|
||||
## versions
|
||||
|
||||
- 0.0.1 (2018/05/15)
|
||||
* 发布0.0.1版
|
||||
* 实现 ip a[ddress], ip route [list|get|add|delete <item>], ip link [show <item>]
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
require('es.shim')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const pg = require('progress')
|
||||
const cp = require('child_process')
|
||||
const chalk = require('chalk')
|
||||
|
||||
const print = console.log
|
||||
const VERSION = '0.0.1'
|
||||
|
||||
let args = process.argv.slice(2)
|
||||
let af = 4
|
||||
|
||||
function run(cmd) {
|
||||
try {
|
||||
return cp.execSync(cmd).toString('utf8')
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 打印网卡接口信息
|
||||
function networkInterfaces() {
|
||||
let result = os.networkInterfaces()
|
||||
print(chalk.green.bold(os.hostname()))
|
||||
for (let k in result) {
|
||||
let info = ''
|
||||
let base = ''
|
||||
for (let it of result[k]) {
|
||||
base = `MAC ${it.mac} INTERNAL ${chalk.yellow(it.internal)}`
|
||||
info += `${it.family.padStart(12)} ${chalk.green(it.address)} NETMASK ${
|
||||
it.netmask
|
||||
} \n`
|
||||
}
|
||||
print('%s %s\n%s', chalk.blue.bold((k + ':').padEnd(8)), base, info)
|
||||
}
|
||||
}
|
||||
|
||||
function routeList() {
|
||||
let result
|
||||
if (af === 6) {
|
||||
result = run(`netstat -nr -f inet6 2>/dev/null`)
|
||||
} else {
|
||||
result = run(`netstat -nr -f inet 2>/dev/null`)
|
||||
}
|
||||
if (result === false) {
|
||||
return
|
||||
}
|
||||
result = result.split('\n')
|
||||
result.splice(0, 3)
|
||||
result[0] = chalk.blue(result[0])
|
||||
print(result.join('\n'))
|
||||
}
|
||||
|
||||
function routeGet(addr) {
|
||||
let result = run(`route -n get ${addr}`)
|
||||
let dict = {}
|
||||
result = result.split('\n')
|
||||
for (let it of result) {
|
||||
it = it.split(':')
|
||||
if (it.length < 2) {
|
||||
continue
|
||||
}
|
||||
dict[it[0].trim().replace(/\s+/g, '_')] = it[1].trim()
|
||||
}
|
||||
|
||||
let { route_to, interface, gateway } = dict
|
||||
let src = run(
|
||||
`python -c "import socket;s = socket.socket(socket.AF_INET${
|
||||
af === 6 ? '6' : ''
|
||||
}, socket.SOCK_DGRAM);s.connect(('${addr}',7));print(s.getsockname()[0])"`
|
||||
)
|
||||
src = src.trim()
|
||||
|
||||
print(
|
||||
`${route_to} ${
|
||||
gateway ? 'via ' + gateway : ''
|
||||
} dev ${interface} src ${src}`
|
||||
)
|
||||
}
|
||||
|
||||
function routeAdd(dev = 'dev', addr) {
|
||||
if (!addr) {
|
||||
return
|
||||
}
|
||||
let inet = 'inet' + (af === 6 ? '6' : '')
|
||||
let result = run(`sudo ifconfig ${dev} ${inet} add ${addr}`)
|
||||
if (result === false) {
|
||||
print(chalk.red('route add failed'))
|
||||
}
|
||||
}
|
||||
|
||||
function routeDel(dev = 'dev', addr) {
|
||||
if (!addr) {
|
||||
return
|
||||
}
|
||||
let inet = 'inet' + (af === 6 ? '6' : '')
|
||||
let result = run(`sudo ifconfig ${dev} ${inet} ${addr} remove`)
|
||||
if (result === false) {
|
||||
print(chalk.red('route delete failed'))
|
||||
}
|
||||
}
|
||||
|
||||
function parseIfconfigArr(arr) {
|
||||
let i = 0
|
||||
|
||||
for (let k of arr) {
|
||||
k = k.split(/\s{1,2}/)
|
||||
if (k.length < 3) {
|
||||
continue
|
||||
}
|
||||
if (i === 0) {
|
||||
i = 1
|
||||
k[0] = chalk.blue.bold(k[0].padEnd(8))
|
||||
} else {
|
||||
k.shift()
|
||||
if (k.length === 2) {
|
||||
k[0] = k[0].padStart(8)
|
||||
} else {
|
||||
if (k[0] === '') {
|
||||
k[0] = ' '.repeat(8)
|
||||
}
|
||||
if (k[1] === '') {
|
||||
k[1] = ' '.repeat(7)
|
||||
}
|
||||
if (k[3] === '' && k[4] === '') {
|
||||
k.splice(3, 2)
|
||||
}
|
||||
if (k[2] === '') {
|
||||
k.splice(2, 1)
|
||||
}
|
||||
if (['ether', 'inet', 'inet6'].includes(k[1])) {
|
||||
k[2] = chalk.green(k[2])
|
||||
} else if ('status:' === k[1]) {
|
||||
k[2] = chalk.yellow(k[2])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print(k.join(' '))
|
||||
}
|
||||
}
|
||||
|
||||
function doIfconfig() {
|
||||
let result = run('ifconfig')
|
||||
.replace(/\t/g, ' ')
|
||||
.trim()
|
||||
|
||||
result = result.replace(/([\w]+: flags=.*\n)/g, '=====$1').split('=====')
|
||||
!result[0] && result.shift()
|
||||
|
||||
for (let it of result) {
|
||||
it = it.split('\n')
|
||||
parseIfconfigArr(it)
|
||||
print('\n')
|
||||
}
|
||||
}
|
||||
|
||||
function doIfconfigOne(flag) {
|
||||
let result = run(`ifconfig ${flag}`)
|
||||
.replace(/\t/g, ' ')
|
||||
.trim()
|
||||
|
||||
result = result.split('\n')
|
||||
parseIfconfigArr(result)
|
||||
}
|
||||
|
||||
function doHelp() {
|
||||
print('Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }')
|
||||
print(' ', 'ip a[ddress]', '打印网卡的IP信息')
|
||||
print(' ', 'ip route [add|list|delete|get]', '路由相关信息及操作')
|
||||
print(' ', 'ip link', '打印网卡的详细信息')
|
||||
print(' ', 'ip -V[--version]', '打印版本信息')
|
||||
print(' ', 'ip -h[--help]', '打印帮助信息')
|
||||
print()
|
||||
}
|
||||
|
||||
function printVersion() {
|
||||
print('ip, v%s', VERSION)
|
||||
}
|
||||
|
||||
if (!args.length) {
|
||||
doHelp()
|
||||
process.exit()
|
||||
}
|
||||
|
||||
if (args[0] === '-6') {
|
||||
af = 6
|
||||
args.shift()
|
||||
}
|
||||
|
||||
if (args[0] === '-4') {
|
||||
af = 4
|
||||
args.shift()
|
||||
}
|
||||
|
||||
switch (args[0]) {
|
||||
case 'link':
|
||||
args.shift()
|
||||
if (args.length === 0) {
|
||||
doIfconfig()
|
||||
break
|
||||
}
|
||||
if (args[0] === 'show' && args.length === 2) {
|
||||
args.shift()
|
||||
doIfconfigOne(args[0])
|
||||
break
|
||||
}
|
||||
break
|
||||
case 'a':
|
||||
case 'address':
|
||||
networkInterfaces()
|
||||
break
|
||||
case 'route':
|
||||
args.shift()
|
||||
if (!args.length || ['list', 'show', 'lst', 'ls'].includes(args[0])) {
|
||||
routeList()
|
||||
break
|
||||
}
|
||||
if (args[0] === 'get' && args.length === 2) {
|
||||
routeGet(args[1])
|
||||
break
|
||||
}
|
||||
if (args[0] === 'add' && args.length === 3) {
|
||||
routeAdd(args[1], args[2])
|
||||
}
|
||||
|
||||
if (args[0] === 'delete' && args.length === 3) {
|
||||
routeDel(args[1], args[2])
|
||||
}
|
||||
break
|
||||
case '-V':
|
||||
case '--version':
|
||||
printVersion()
|
||||
break
|
||||
default:
|
||||
break
|
||||
doHelp()
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "bash-ip",
|
||||
"version": "0.0.1",
|
||||
"description": "类似于linux下的简单版的ip命令工具",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
"ip": "index.js"
|
||||
},
|
||||
"keywords": ["ip", "iproute2"],
|
||||
"dependencies": {
|
||||
"es.shim": "0.0.2",
|
||||
"chalk": "^2.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"os": ["darwin"],
|
||||
"author": "yutent",
|
||||
"license": "MIT"
|
||||
}
|
Loading…
Reference in New Issue