shell 命令

Table of Contents

1 进程

1.1 ps

1.2 pgrep

2 文本处理

2.1 fgrep、egrep 和 grep

fgrep 只匹配字符,egrep 使用了扩展正则表达式,现在都整合到了 grep 里,分别通过 -F、-E 参数区别。

2.2 fmt格式化输出

如下文本:

All material created by James Mohr is copyrighted 1994-2003 by James Mohr and is licensed under a modified GNU Free Documentation License. Reproduction and distribution of material copyrighted by James Mohr or derivative of such material in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder. Distribution of substantively modified versions of material copyrighted by James Mohr is prohibited without the explicit permission of the copyright holder. Distribution of material copyrighted by James Mohr in a commercial product is prohibited without the explicitpermission of the copyright holder. Use of material copyrighted by James Mohr in any commercial endeavour is prohibited without the explicit permission of the copyright holder. A "commercial endeavour" includes, but is not limited to training or other educational courses for which a fee is required. Public education institutions (such a state universities and colleges, community colleges and similar) are except from this requirement and need only

执行后:

All material created by James Mohr is copyrighted 1994-2003 by
James Mohr and is licensed under a modified GNU Free Documentation
License. Reproduction and distribution of material copyrighted by James
Mohr or derivative of such material in any standard (paper) book form
is prohibited unless prior permission is obtained from the copyright
holder. Distribution of substantively modified versions of material
copyrighted by James Mohr is prohibited without the explicit permission
of the copyright holder. Distribution of material copyrighted by James
Mohr in a commercial product is prohibited without the explicitpermission
of the copyright holder. Use of material copyrighted by James Mohr in any
commercial endeavour is prohibited without the explicit permission of the
copyright holder. A "commercial endeavour" includes, but is not limited to
training or other educational courses for which a fee is required. Public
education institutions (such a state universities and colleges, community
colleges and similar) are except from this requirement and need only

可以指定 -w 参数设置每行行宽。

2.3 expr

执行表达式,包括正则匹配、四则运算等。

例1,字符串按下标取子字符串

$  expr substr "abcd" 1 2
ab

例2,使用正则判断 IP 地址

$  expr match "192.168.1.1" "^[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}$"
11

使用正则时要注意“{”、“}”、“(”、“)”需要转义,详细见:info expr

使用小括号配对时,打印匹配的值:

$  expr match "192.168.1.1" "^\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)$"
192.168.1.1

2.4 paste

按列合并两个文件

假如文件1:

1
2
3

文件2:

a
b
c

执行合并:

$ paste 1 2
1	a
2	b
3	c

paste 默认使用 Tab 作为分割符号,参数 -d 后面跟字符自定义分隔符。使用空格话,需要转义空格字符,如:

$ paste 1 2 -d\
1 a
2 b
3 c

2.5 tr

转换、替换和删除字符

# 删除文件中的空字符(NULL)

# 文件内容如下:
# $ hexdump /tmp/has_00
# 0000000 6261 6300
# 0000004

$ tr -d '\0' < /tmp/has_00 | hexdump
0000000 6261 0063
0000003
# 按字符集替换
$ echo 'luanx' | tr '[al]' '[41]'
1u4nx

2.6 tail

打印文件尾部内容

# 打印文件倒数 10 行
$ tail -10 /etc/passwd
# 跳过文件前 10 行的内容(从第 11 行开始打印)
$ tail -n +10 /etc/passwd

2.7 pr

在文本顶部加上title和页码,便于打印。

2.8 nl

nl 命令可以给文本每行开头加入行号

如:

[email protected]:/tmp$ cat x
test1
test2
test3
[email protected]:/tmp$ nl x
1  test1
2  test2
3  test3

2.9 shuf

从文本中随机抽取行数打印。

shuf 文件名 -n1

-n:随机显示1行

2.10 xargs

  • 它用于格式化数据流
  • 它可以转变数据流内容成程序参数

以下是测试源文件 test:

1
2 3
4 5 6
  1. 默认上数据流变成行
cat test|xargs:
1 2 3 4 5 6
  • 参数 -d 还可以指定分隔符
  • 参数 -n 指定每行最多列数
[email protected]:/tmp$ cat test | xargs -n 2
1 2
3 4
5 6
  1. 递归删除文件
find . -name '.svn' | xargs rm -rf

3 文件相关

3.1 查找文件位置

which:显示命令的绝对路径

例:

$ which cd
/usr/bin/cd

对于 alias,which 也能显示出来:

$ which ls
ls='ls --color=auto -F'
	/usr/bin/ls

whereis:查找文件、man和源码的路径

$ whereis cd
cd: /usr/bin/cd /usr/share/man/mann/cd.n.gz /usr/share/man/man1/cd.1.gz /usr/share/man/man1p/cd.1p.gz

3.2 cat

输出行号:

cat -n /etc/passwd

3.3 find

找出最近创建的文件

使用 find 命令可以找出最近创建的文件:

find ./ -mtime 0

参数 mtime,后面跟数字 n,表示最近 n×24 消失修改过的文件

查找 SUID 的程序

find 目录 -perm -4000

-perm 指定权限位,如 -perm -777

找出指定日期之后创建的文件

find . -name '*.doc' -newermt 2017-04-20

删除文件名乱码文件 有时删粗文件时,遇到文件名乱码,并且shell无法补全的情况下,就可借助find命令来删除。

找到文件的inode:ls -i

然后:find . -inum inode号 -exec rm {} \;

3.4 rename

常用于批量重命名文件。不同的发行版 rename 命令版本不一样,有些是 C 版本,有些是 Perl 版本。

Fedora 默认是 C 版本的,Ubuntu 默认是 Perl 版的。

C 版本的 rename 接受三个参数:

rename 要修改的字符串 替换后的字符串 文件列表

例,将图“1.jpg、图2.jpg…”重命名为“1.jpg、2.jpg…”:

$ rename '图_' '' *.jpg

Perl 版的 rename 可直接写正则表达式,例如某目录下有以下文件:

$ ls
2016-08-01  2016-08-02  2016-08-03

将它们批量重命名为“yyyyMMdd”格式:

rename 's/\-//g' 2016*

结果如下:

$ ls
20160801  20160802  20160803

3.5 ss

显示 socket 状态

3.6 comm

对比两个已排序过的文件

对比两个都已排序过的文件

comm file1 file2

结果分成 3 行,第一行是文件 1 中出现过的行,第二行是文件 2 出项过的行,第三行是文件 1 和文件 2 共同出项过的。

另外有两个参数:

  • 1 不显示第一个文件出现过的
  • 2 不显示第二个文件出现过的
  • 3 不显示共同部分

comm -12 file1 file2:显示 file1 和 file2 共同行,即求两个数据集的交集。

3.7 strings

打印文件中的可见字符。

上次遇到 Nginx 配置文件误丢,但 Nginx 还在运行,可用 gcore 命令将进程数据 dump 出来,再用 strings 把内存中的配置信息找出。

3.8 cd

切换目录。

小技巧:CDPATH 环境变量

设置常用路径,使用 cd 命令时,可以不用写完整路径。

3.9 rm

删除指定目录所有文件,并排除某些文件:

rm -rf `ls | grep -v 文件名`
# 或者
rm -rf `ls | grep -v '[1|2|3].php'`

3.10 mktemp

新建临时文件,随机生成临时文件名。

3.11 解决“-”开头的文件名

方法1:如果对文件名使用了“-”开头使用 cp、mv、rm 命令,用“–”参数即可:

rm -f -- -exec # 删除-exec文件
mv -- -exec new
cp -- -exec new

方法2:可以用 ls -i 获得 i 节点号,然后用 find 命令操作。

方法3:最简单,直接带上路径,如:mv ./-exec a,即可。

3.12 dd

命令非 Unix 风格,dd 的命令风格来自JCL(https://en.wikipedia.org/wiki/Job_Control_Language

磁盘写入速度测试:

sync; dd if=/dev/zero of=test_file bs=1M count=1024; sync

3.13 split

对文件分割,例如将一个 4,000 行的日志分割为 4 个 1,000 行的文件:

split -l 1000 access.log

4 系统相关

4.1 arch,查看处理器架构

$ arch
x86_64

4.2 date

日期字符串和时间戳之间户转:

$ date +%s # 当前时间戳
1461552157
$ date -d'2016-04-25 14:23' +%s
1461565380
$ date -d @1461551881 # 时间戳转字符串
2016年 04月 25日 星期一 10:38:01 CST
$ date -d @1461551881 +'%Y-%m-%d' # 自定义格式
2016-04-25

日期计算:

$ date -d '-1years'
2015年 04月 25日 星期六 10:56:09 CST
$ date -d '-1days'
2016年 04月 24日 星期日 10:56:13 CST
$ date -d '-1months'
2016年 03月 25日 星期五 10:56:16 CST

遍历某段时期的日期:

start_date=20151101
end_date=20171126

while [[ $start_date < $end_date ]]
do
    echo $start_date
    start_date=$(date -d "+1 month ${start_date}" +%Y%m%d)
done

4.3 time

time 命令可以统计一个程序的执行总时间、在用户以及内核模式的执行总时间

如:

$ time python test_case.py

Ran 1 test in 2.326s

OK

0m2.372s
0m0.044s
0m0.008s

这里可以看到执行完这个 Python 脚本所花的总时间,user 和 sys 分别是用户态和内核态执行的总时间,user+sys 的时间与 real 的时间相差较大的话,说明I/O阻塞所花费的时间比较长。sysuserreal

4.4 lsof

查看进程打开的 socket 这次遇到 urllib2 的一个坑,文档说不用手动关闭,而 close 方法却是个 pass

在多线程+高并发请求网页时候,会阻塞死,如果用 lsof -i tcp:80 可以看到大量的连接请求。

查看文件/目录被哪些进程操作

lsof 目录/文件名

查看进程使用了哪些文件

lsof -c [进程名]

如果要查看多个进程,使用多个 -c 参数就可以了。

如果要按 PID 查看:

lsof -p [PID]

查看进程占用了哪些端口

lsof -Pl +M -p [PID]

或者根据端口号查找进程:

lsof -Pl +M -i4 -i6 | grep [端口号]

4.5 chsh

更改用户的默认 shell。

sudo chsh -s /bin/zsh lu4nx

4.6 watch

周期性执行某个命令。

例,实时监控 dmesg:

watch "dmesg | tail"

5 网络相关

下载文件:

  1. curl -o [filename] http://xxx
  2. wget

6 其他

6.1 bc

四则运算

➜  echo 1+1 | bc
2
➜  echo 1*0 | bc # 需要用引号
zsh: no matches found: 1*0
➜  echo '1*0' | bc
0
➜  echo '4/2' | bc
2
➜  echo '4-2' | bc
2

二进制计算

obase=2
ibase=2
01+10
11