乐趣区

关于linux:20个常用的Linux工具命令

原创:打码日记(微信公众号 ID:codelogs),欢送分享,转载请保留出处。

简介

网上有很多辅助开发的小工具,如 base64,md5 之类的,但这些小工具其实根本都能够用 Linux 命令实现,即不便又高效。

查看特殊字符

把这个放在首位,是因为这个切实太重要了,程序常常会因为非凡的看不见的字符而呈现 bug,因而一些本应该执行正确而理论出其不意的字符串解决,你都应该看看是否含有特殊字符。

$ echo 'hello'|sed -n 'l'
hello$
$ echo 'hello'|cat -A
hello$
$ echo 'hello'|od -c
0000000   h   e   l   l   o  \n
0000006

执行下面的命令会发现,echo 会给输入加一个换行符。

查看字节数

当呈现数据库字段超长谬误时,这个命令会很有用,如 oracle 的 varchar2(64)类型,示意最多存 64 字节,而业务插入的字符串是中英混合的,预计它有多少字节还挺麻烦。

$ echo -n 'hello, 张三'|iconv -t utf-8|wc -c
12

工夫戳转换

# 日期串转工夫戳
$ date -d '2020-06-08 00:13:28' +%s
1591546408
#工夫戳转日期串
$ date -d '@1591546408' +"%F %T %z"
2020-06-08 00:13:28 +0800
#带时区版本,时区很重要,要时时刻刻留神
TZ='GMT-8' date -d '2020-06-08 00:13:28' +%s
TZ='GMT-8' date -d '@1591546408' +"%F %T %z"

csv 变 json

# 应用 csvkit 中的 csvjson
csvjson -y0 -I data.csv
#应用 python
python -c "import csv,json;print(json.dumps(list(csv.reader(open('data.csv')))))"

文件服务器

python3 -m http.server 8000

urlencode,base64,md5,sha256

做开发常常会用到这些。

# urlencode,倡议增加为别名
$ alias urlencode='python3 -c"import sys;from urllib import request as rq;print(rq.quote(sys.argv[1],safe=\"\"))"'
$ urlencode 你好
%E4%BD%A0%E5%A5%BD

# urldecode,倡议增加为别名
$ alias urldecode='python3 -c"import sys;from urllib import request as rq;print(rq.unquote(sys.argv[1]))"'$ urldecode'%E4%BD%A0%E5%A5%BD'
你好

# base64 编解码
$ echo hello |base64 -w0
aGVsbG8K
$ echo aGVsbG8K|base64 -d
hello

# md5 摘要
$ echo hello |md5sum
b1946ac92492d2347c6235b4d2611184  -

# sha256 摘要
$ echo hello | sha256sum
5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03  -

# hmacWithSha256 摘要
$ echo hello | hmac256 'secret'
171b5670f7b4037fb90bef773b022130e48100fdd40ea023730097da9a68f4ff

json 格式化

$ echo '{"id":1,"name":"lisi"}' | jq .
{
  "id": 1,
  "name": "lisi"
}

字符串 escape 与 unescape

# 将 "转成 \"
$ echo 'hi,"lisi"'| jq -R'tojson'-r"hi,\"lisi\""
#将 \"转成"
$ echo '"hi,\"lisi\""'| jq -R'fromjson' -r
hi,"lisi"
#json 属性值里是 json 内容,不知你有没有遇到过这种糟糕设计
$ echo '{"code":200,"data":"{\"id\":1,\"name\":\"lisi\"}"}' | jq '.data=(.data|fromjson)'
{
  "code": 200,
  "data": {
    "id": 1,
    "name": "lisi"
  }
}

unicode 编码

开发时,也常常须要在汉字与 \u4f60 模式之间转换,上面这些命令就很有用了。

#unicode 解码
$ echo -e '\u4f60\u597d'
你好

$ echo $'\u4f60\u597d'
你好

$ echo '\u4f60\u597d'|sed 's/\\u//g'|xxd -r -ps|iconv -f ucs-2be
你好

#unicode 编码
$ echo -n '你好'|iconv -t ucs-2be|xxd -ps|sed -E 's/.{4}/\\u&/g'
\u4f60\u597d

#转换文件编码为 utf8,也很有用
enconv -L zh_CN -c -x UTF-8 file.txt

生成随机明码

# 生成随机明码
$ openssl rand -hex 16
fb9f47a7ebad6bd77be332d6b3a0bc0b

$ cat /dev/urandom |head -c 16|xxd -ps
eb297181cad546210a00118d543b78bf

$ cat /dev/urandom |tr -dc A-Za-z0-9  |head -c 32
V1NB2Oc1mCJ3mNfofDZCQB68dRde30Xz

#生成 10 以内随机数
awk -v b=$(cat /dev/urandom|tr -dc 0-9|head -c 9) 'BEGIN{srand(b);print int(rand()*10)}'
cat /dev/urandom|head -c 4|od -An -t u4 --endian=big|awk '{print int($1/2^32*10)}'

#生成 uuid
$ uuidgen
7b45c1c2-0533-45e5-9903-802ee58b6638

ip 地址转数字

家喻户晓,ip 地址理论是一个 4 字节的数字,如果把 ip 以数字的模式保留在数据库中,能够节俭空间。

#ip 转数字
$ echo 192.168.0.1|tr . '\n'|xargs printf "%02X"|xxd -r -ps|od -An -t u4 --endian=big
 3232235521
#数字转 ip
$ printf "%08X" 3232235521|xxd -r -ps |od -An -t u1
 192 168   0   1

进制转换

#printf 能够实现十进制到十六进制的转换
$ printf "%08X" 3232235521
C0A80001

#bc 能够实现任意进制之间互转
$ echo C0A80001|sed 's/^/obase=10;ibase=16;/g'|bc
3232235521

$ echo C0A80001|sed 's/^/obase=2;ibase=16;/g'|bc
11000000101010000000000000000001

查看 ascii

# 间接查看 man 文档
man ascii 
#用 od 查看
printf "%0.2X" {0..127}| xxd -r -ps | od -t x1d1ca

搜寻内容

在搜寻日志时,tac 通常比 cat 更有用,比方咱们搜寻最近产生的 10 次异样。

tac app.log|grep -iw -B 20 -m 10 'exception'|tac 

另外,当不晓得要找的内容在当前目录下的那个文件中时,应该优先应用 grep -rn 搜寻一把,比方遗记了 tomcat 的端口在哪配置。

grep -rn -w 8080 . 

查看过程日志

当你进入一个生疏的服务器环境,不晓得 java 过程产生的日志文件在哪,与其问他人,不如间接本人找。

# 应用 lsof
pid=`pidof java`
lsof -p $pid|grep .log$
#lsof 不可用时,试试这个
ls -l /proc/$pid/fd |grep .log$

反向 shell

有时,须要他人帮忙排查问题,但又不想把服务器明码通知他人,这时能够给他人一个反向 shell。

# 获取 shell 端
socat file:`tty`,rawer TCP-LISTEN:9999,bind=0.0.0.0,reuseaddr,keepalive,keepcnt=3,keepidle=600,keepintvl=600,pf=ip4
#给出 shell 端
nohup socat system:'stty rows 63 columns 207;bash -li',pty,stderr,setsid,sigint,sane,ctty TCP:192.168.0.1:9999 &

统计行数

# 统计行数
wc -l
sed -n '$='
# 分组统计行数
uniq -c

生成间断工夫片

生成间断工夫片,个别用在脚本中,比方查问一年的数据量,当数据量很大时,间接查问是出不来后果的,这时能够把 1 年拆成 1 天天的,让查问 1 天天的跑。
如下,1 年拆成 1 天天工夫范畴的 sql,丢到 mysql 命令里缓缓查。

generate_day_range(){seq $(date -d '2022-01-01' +%s) $((24*3600)) $(date -d '2022-02-01' +%s) | sed '1!{$!p}' | paste - - 
}
query_one_day(){begin_time=$(date -d "@$1" +'%F %T')
    end_time=$(date -d "@$2" +'%F %T')
    sql="select count(*) from order where create_time >='${begin_time}'and create_time <'${end_time}';";
    echo "$sql"
    mysql -N -e "$sql"
}
export -f query_one_day
generate_day_range | xargs -l -P2 bash -c 'query_one_day"$@"' -

pv 显示进度与速度管制

长时间运行的脚本,看不到进度让人很着急,于是就有了 pv 命令。
如 cp 命令,自身没有显示进度性能,复制大文件干瞪眼,这时能够应用 pv 命令代替。

pv file1 > file2 

如上节查问 1 年数据量的脚本,要查看执行进度,只须要在 mysql 命令前放入 pv 命令即可。

generate_day_query_sql(){fmt='select count(*) from order where create_time >="%s"and create_time <"%s"; \n';
    seq 0 $1 \
        |xargs -i date -d "2021-01-01 00:00:00 {} days" +'%F %T' \
        |sed '1!{$!p}' \
        |paste - - \
        |awk -F'\t' -v fmt="$fmt" '{printf fmt,$1,$2}'
}
# - l 示意计算流过 pv 的行数,pv 默认计算流过的字节
# - s 指定总行数,这样每一行文本流过 pv,pv 就能计算出以后进度了
generate_day_query_sql 365 | pv -l -s 365 | mysql -vvv

pv 还能用来管制速度,这样就能防止脚本把数据库查挂了。

# -L 2 示意文本流过速度不超过每秒 2 行
generate_day_query_sql 365 | pv -l -s 365 -L 2 | mysql -vvv

比照表构造

雷同零碎,不同环境的数据库,保持一致表构造其实是比拟艰难的,当须要找出他们的不同点时,尽量不要一个个字段去比照,效率太低了。

# 导出 db1 中所有表名
echo 'show tables' | mysql --skip-column-names -D db1 > table_names.txt
#导出 db1 与 db2 的表构造
cat table_names.txt | sed 's/.*/show create table &;/' | tee >(mysql -D db1 > db1_tables.txt) >(mysql -D db2 > db2_tables.txt)
#复原换行符
sed -i 's/\\n/\n/g' db1_tables.txt db2_tables.txt
#比照表构造
icdiff db1_tables.txt db2_tables.txt

总结

能够将这些工具命令增加为 Linux 别名,用纯熟后,你会发现你基本离不开它。

往期内容

Linux 文本命令技巧 (下)
Linux 文本命令技巧(上)
原来 awk 真是神器啊
好用的 parallel 命令
罕用网络命令总结

退出移动版