每天一条 linux 命令

Linux Command Line

正式开始工作了,尽管有很多需要提升的地方,其实一直没有找到一个合适的方向.
想来想去还是决定从 Linux 的命令行入手吧,这大概是学习和效用可以直接最大化的一种方式了.学习快捷键也是同理,提高生产效率,可以把更多的时间投入在思考上.

计划从 201803 起每日更新(争取 (:з」∠)

主要参考资料为
菜鸟教程 Linux 命令大全
每天一个 Linux 命令
以及其他互联网资料 lol

以下操作全部基于 mac, 使用命令行程序 iTerm2, 用的是 .zsh 插件为 oh-my-zsh
大部分操作 Linux 平台应该通用

文件目录操作命令

ls

最常见的一个命令了算是,就是 list (列举) 所有内容的意思

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ls -a # 显示所有文件及目录 (ls内定将文件名或目录名称开头为"."的视为隐藏档,不会列出)
ls -l # 除文件名称外,亦将文件型态、权限、拥有者、文件大小等资讯详细列出
ls -r # 将文件以相反次序显示(原定依英文字母次序)
ls -t # 将文件依修改时间之先后次序列出
ls -A # 同 -a ,但不列出 "." (目前目录) 及 ".." (父目录)
ls -F # 在列出的文件名称后加一符号;例如可执行档则加 "*", 目录则加 "/"
ls -R # 若目录下有文件,则以下之文件亦皆依序列出


# 高级示例
ls -ltr s*
# 列出目前工作目录下所有名称是 s 开头的文件,越新的排越后面
# -l 是所有文件, -t 是按文件修改的时间顺序, -r 是相反时序

ls -lh
# 列出详细文件 大小是 -human readable 的, 也可以使用 ll 代替

cd & pwd

cd 也是简单的目录命令,就是 change directory 的缩写
一般用法就是 cd + [directory name]

pwd 就更简单了,只是显示当前的路径 printing the current working directory

1
2
3
4
5
6
7
cd ~/Desktop

cd - # 用于进入上一个目录
# 在 oh-my-zsh 的支撑下似乎直接用 '-' 也是可行的
# 一般也可以配合 pwd 使用
➜ demo pwd
~/Desktop/Jeremy/demo

mkdir

mkdir 对应的就是 make directory,也就是创建文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
mkdir folder_name # 创建目录

mkdir -p folder/sub_folder # 创建连续的目录

mkdir -m 777 folder # 创建权限为777的目录
# 这里有必要解释一下,ll 显示的结果
# 第一列 - 是文件,d 是目录
# 后面九位 rwx 代表的是权限等级,r = 4, w = 2, x = 1
# 因此 777 对应的就是 rwx,权限可以用 chmod 进行修改

mkdir -p scf/{lib/,bin/,doc/{info,product},logs/{info,product},service/deploy/{info,product}}
# 花式生成目录, 可以用 tree 进行目录树查看

➜ Linux-Command-Lines tree scf
scf/
├── bin
├── doc
│   ├── info
│   └── product
├── lib
├── logs
│   ├── info
│   └── product
└── service
└── deploy
├── info
└── product

rm & rmdir

rm 也就是 remove,删除
这是一个极其危险的命令,如果在错误的目录执行了,或者错误删除了文件,后果不但严重而且非常麻烦,根据过来人的意见,最后多使用 mv 命令,把要删除的内容移动到某个临时文件夹,再定期对该文件夹进行清理
rmdir 则是用于删除空目录

1
2
3
4
5
6
rm file
rmdir folder # rmdir 只能移除空的文件夹

rm -i folder # 交互式的删除, -i 即 interactive,输入 y -> yes, n -> no
rm -r folder # -r 即 recursive, 可以删除该 folder 下所有目录和文件,慎用!
rm -rf * # 删除所有内容, -f 即 force, 绝对慎用!!!!

mv

mv 即 move (rename) file, 可用于移动文件/文件夹 或者改名

1
2
3
4
5
6
7
mv a b # 把文件夹 a 改名 为 b
mv -i a/a.txt b # 把 a 目录下的 a.txt 复制到 b 目录下,启用 interactive 模式以防直接 overwrite,主要如果没有 -i 则会是默认 -f 的情况

mv * ../ # 把当前目录下所有内容往上级目录移动

# 两个小补充 -v 即 verbose, 操作完会解说具体的内容, 这是一个 general 的指令对所用命令几乎都适用
# -b 本意为 backup, 看到资料有写但 使用 man mv 查看后发觉对 mv 没有这个命令

cp

cp 即 copy files, 是简单的复制命令

1
2
3
4
5
6
7
cp a.txt b.txt # 在同目录下复制文件 a.txt 并将复制文件命名为 b.txt
cp a.txt bb # 把 a.txt 复制到子目录 bb 下面

# 可选参数
# -r 用于复制目录
# -a 类似于 -r, 会保持同样的权限? 具体还不是特别理解, 不建议用
# -i -v 等很常规了 就不多少了

cat

cat – concatenate and print files, 本意为连接文件并打印到标准输出设备上
之前上 CC 的时候经常使用该命令, 坦白说效果挺强的哈哈

1
2
3
4
5
6
7
8
9
10
11
cat 1.txt # 直接 cat 就是显示该文件的所有内容, 缺点在于不如 less 和 vi 可以翻阅甚至编辑, 只是单纯的列出所有内容

# 可选参数
# -n, 输出的每一行都加序号, 多个文件则每个都从1开始标行号
# -b, 同 -n 一样标行号, 不同点在于空白行是不会标出的
# -s, 多个空白行会被压缩成一行
# -t -v 显示一些没办法打印的字符 比如回车 Non-ASCII 字符等

cat -b 5.txt 6.txt > 8.txt # 把两个 txt 文件合并, 并标明行号, 空白行会被保留但无行号, 生成文件 8.txt

cat *.txt > all.txt # 把所有 txt 文件合并为一个 all.txt, 个人测试觉得这里是按 alphabet 序排列的

less

less 这个命令的解释很迷, 简单来说就是 less > more 也是很皮了
大概是因为 more 是之前一个看文件内容的命令
于是 less 就变成了 更强大的 看文件内容的命令 LOL
好处是 less 是分段读取的, 所以在面对大文件时比 vi 之类的更有优势 毕竟只读不写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
less a.txt # 展示 a.txt 的内容

ps -ef | less # 前者是查看进程信息, | 是管道用法, 奇技淫巧很多稍后再介绍
# 简单来说就是用 less 的方式查看进程信息

history | less # 查看所有的 CLI 历史记录, 天知道居然能存 1w+

less a.txt b.txt # 查看多个文件, 用 :n :p 进行切换

# 用 less 查看时操作
# 按键 u d 对应的是 up/down, 向上/向下翻半页
# 按键 f b 则是向前/向后翻一页
# 按键 g G 则是对应第一行/最后一行, G 用 shift + g 输入

# m 进入 mark 模式
# 跟一个字母?表达用?标记当前位置
# ' 进入 goto mark 模式, 输入字母?跳转到刚才标记的位置

# & 进入匹配模式 -> 这个功能感觉很强大
# v -> 编辑文件, vim

head & tail

用于显示文件开头和结尾的内容

1
2
3
4
5
6
7
8
head a.txt # 默认显示文件的前 10 行
head -n 20 a.txt # 指定显示前 20 行
head -c 100 a.txt # 指定显示前 100 字符

tail -n 20 a.txt # 指定显示倒数 20 行
tail -f a.txt # 循环查看文件内容, 这个其实很好用, 适用于查看 log 的实时情况
tail -n +60 a.txt # 从第 60 行开始显示, 一直到文件结尾
tail -c 10 a.txt # 显示倒数的 15 个字符

文件查找命令

which, whereis

这两个命令都是用于搜索其他命令/执行文件的位置, 比如

1
2
3
4
5
which git # 显示 git 的位置
whereis git # 显示 git 的位置
/usr/local/bin/git

which -a git # 显示所有 git 的位置

这个是真的没啥用-.-
除了判断一下究竟执行了哪一个

find

find 基础

这个命令怕不是比较复杂了的, 尽管主要功能就是 查找
可以用来查找很多东西, 以及有很强大的扩张命令

语法:

1
find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} ;

options:
-name 按照文件名查找文件
-perm 按照文件权限来查找文件
-prune 使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略
-user 按照文件属主来查找文件
-group 按照文件所属的组来查找文件
-mtime -n +n 按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前, 对应还有 -atime, -ctime. acm 分别表示 访问, 改变文件状态, 改变文件数据. 同时也可以有 -amin, -cmin, -mmin

-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计
-depth:在查找文件时, 首先查找当前目录中的文件, 然后再在其子目录中查找

-type 查找某一类型的文件, 诸如:
b - 块设备文件
d - 目录
c - 字符设备文件
p - 管道文件
l - 符号链接文件
f - 普通文件

更多参看看这里http://www.cnblogs.com/peida/archive/2012/11/16/2773289.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
find . -name "a.txt" # 找出当前目录下所有的 a.txt 文件 (包括子目录下的)
find / -name "a.txt" # 找出根目录下所有的 a.txt 文件 (包括子目录下的)
find . -name "*.txt" # 找出当前目录下所有的以后缀为 .txt 命名 文件 (包括子目录下的)

find . -mtime 3 # 找出当前目录下所有的过去 3 天被改变过文件数据的文件
find . -newer 8.txt # 找出当前目录下所有 比 8.txt 更新的文件

find . -perm 777 # 找出当前目录下权限为 777 的文件

find . -type d # 找出当前目录下所有目录文件

find . -size +1000c -print # 找出当前目录下字符数大于 1000 的文件 (不包含1000字符的)
# 此处对于 +1000c 有几个补充
# +是大于, 不带的话似乎是默认大于等于(也有说法是等于,但暂时的实验结果并不是)
# c 对应的是字符数, 如果不带 c 则是默认按 block 记, 1 个 block 对应 512字符
find exec

-exec 参数后面跟的是command命令,它的终止是以;为结束标志的,所以这句命令后面的分号是不可缺少的,考虑到各个系统中分号会有不同的意义,所以前面加反斜杠.

{} 花括号代表前面find查找出来的文件名.

使用find时,只要把想要的操作写在一个文件里,就可以用exec来配合find查找,很方便的.在有些操作系统中只允许-exec选项执行诸如l s或ls -l这样的命令.大多数用户使用这一选项是为了查找旧文件并删除它们.建议在真正执行rm命令删除文件之前,最好先用ls命令看一下,确认它们是所要删除的文件. exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{ },一个空格和一个\,最后是一个分号.为了使用exec选项,必须要同时使用print选项.如果验证一下find命令,会发现该命令只输出从当前路径起的相对路径及文件名.

1
2
3
4
5
6
7
8
9
10
11
find . -type f -exec ls -l {} \; # 列出当前目录下所有普通文件 (其实此处不用 -exec 也无所谓)

find . -type f -mtime +14 -exec rm {} \; # 删除当下目录下的 更改在 14 天以前的所有普通文件

find . -type f -ctime +2 -ok rm {} \; # 把 -exec 改为 ok 则会询问是否删除每个文件
"rm ./n"? n
"rm ./s"? y

find . -name "*.log" -exec grep "error" {} \; # 找出所用文件中包含 error 的部分 (讲真有点鸡肋, 还不如直接 grep "error" *.log)

# 对应也可以把 grep 替换为 cp, mv, 但暂时真的没看出来有啥优势

文件打包压缩解压命令

tar

首先先区分清打包和压缩的不同 -> 打包是把一堆文件变成一个文件, 压缩是把大文件变成小文件
一般用 tar 命令打包, 再用 gzip/其他压缩方式 进行压缩, tar 本身没有压缩功能
tar[必要参数][选择参数][文件]
注意参数的大小写有差别的

常用必要参数
-B 设置区块大小
-c 建立新的压缩文件 (单纯有 -c 似乎不能生成文件=.=)
-t 显示压缩文件的内容
-z 支持gzip解压文件
-j 支持bzip2解压文件
-Z 支持compress解压文件
-v 显示操作过程

常用可选参数
-b 设置区块数目
-C 切换到指定目录
-f 指定压缩文件 (讲真我觉得这个是必备的, 如果不置指定生成的文件, 压缩意义何在? 显示一下压缩结果搞笑吗???)

还有太多乱七八糟的就不附上了
详参此处

1
2
3
4
5
6
7
8
tar cvf a.tar a # 把文件或者文件夹 a 打包, 此处名字可以任意, 习惯用 *.tar 进行命名
tar xvf a.tar # 解包 a.tar

tar zcvf a.tar.gz a # 把文件或者文件夹 a 打包后用 gzip 形式进行压缩
tar zxvf a.tar.gz # 解压文件 a.tar.gz
tar tzvf a.tar.gz #

# 把 z 替换成 j/Z 对应不同的压缩方式

gzip

gzip 是典型的压缩命令, 一般结尾是 .gz

-a或–ascii  使用ASCII文字模式
-d或–decompress或—-uncompress  解开压缩文件
-f或–force  强行压缩文件 不理会文件名称或硬连接是否存在以及该文件是否为符号连接
-l或–list  列出压缩文件的相关信息
-n或–no-name  压缩文件时,不保存原来的文件名称及时间戳记
-N或–name  压缩文件时,保存原来的文件名称及时间戳记
-r或–recursive  递归处理,将指定目录下的所有文件及子目录一并处理
-S<压缩字尾字符串>或—-suffix<压缩字尾字符串>  更改压缩字尾字符串
-t或–test  测试压缩文件是否正确无误
-v或–verbose  显示指令执行过程
-V或–version  显示版本信息
-num 用指定的数字num调整压缩的速度 -1或–fast表示最快压缩方法(低压缩比)-9或–best表示最慢压缩方法(高压缩比),系统缺省值为6

1
2
3
4
gzip * # 把当前目录下所有文件直接压缩, 注意会替换掉原文件
gzip -dv * # 解压目录下所有 .gz 格式的文件, 显示详细过程
gzip -l * # 显示目录下每个压缩文件的信息, 并不解压
gzip -r a # 把子目录 a 下面所有的文件都压缩, 但并不会有和 tar 一样的打包效果

文件权限设置

chmod

要了解文件的访问权限, 先要理解对应的涵义

1
2
drwxr-xr-x  10 admin  staff    320 Apr 12 21:40 a
-rw-r--r-- 1 admin staff 932 Apr 10 00:43 aa.gz

如上, 第一位的 d 和 - 代表的是目录或者文件
后面 9 位对于三个用户组: 文件所有者, 同组用户, 其他用户
每组里面的 3 位分别对应 只读(read) 只写(write) 可执行(execute) 权限

可选参数并不多, 主要有以下几个:
-c 当发生改变时,报告处理信息
-f 错误信息不输出
-R 处理指定目录以及其子目录下的所有文件 (注意不是 -r)
-v 运行时显示详细处理信息

对应的修改方式有两种, 数字/字母的方式:
数字: r=4, w=2, x=1
对应把相应的数字和赋值给文件即可 比如

1
2
3
chmod 763 a

drwxrw--wx 10 admin staff 320B Apr 12 21:40 a

可以看到 7 对应的文件所有者权限为 rwx, 同组用户为 rw, 而其他用户只是 wx

字母: 三个用户组分别写作 u g o, 还有 a 用于所有用户
写的时候用 + - = 符号对应权限

1
2
3
chmod u+x a # 给文件 a 的所有者加上可执行的权限
chmod ug+w, o-x a # 给文件 a 的所有者和同组用户加上写权限, 取消其他用户的可执行权限
chmod ug=wx a # 把文件 a 的所有者和其他用户的权限设为写 + 可执行权限

其他权限相关的命令感觉一时之间用不上… 先略过了

磁盘储存相关

df & du

df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况.可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息

-a 全部文件系统列表
-h 方便阅读方式显示 -H 等于“-h” 但是计算式 1K=1000 而不是1K=1024
-k 区块为1024字节 -m 区块为1048576字节 (默认是512k 的 block)
-l 只显示本地文件系统 (可能有联网的)
-P 输出格式为POSIX

1
2
3
4
5
6
➜  Linux-Command-Lines df -Plh
Filesystem Size Used Avail Capacity Mounted on
/dev/disk1s1 234Gi 218Gi 10Gi 96% /
/dev/disk1s4 234Gi 5.0Gi 10Gi 34% /private/var/vm

# 参数看似很多, 但真正用的不多

du 针对的不是整个磁盘, 而是对某个文件或目录的查看

1
2
3
4
5
6
7
8
9
10
du -h # 以可读方式显示当前目录下所有目录级别的大小

➜ Linux-Command-Lines du -h
1.4M ./a
12M ./d
4.0K ./b/bb
4.0K ./b
14M . # 这个 14M 是子目录及文件的大小总和

du -ah # 把所有文件都列出来

性能监控命令

top

top 用于查看系统的运行情况 类似于 windows 里面的任务管理器
参考资料里面很多都不 work, 建议直接看 man top 学习即可
或者更简单的方式是 按下 top 之后直接 tab, 装了 oh-my-zsh 之后就有超级多方便的提示 lol

1
2
3
4
5
6
7
8
9
10
11
12
13
14
top -o mem # 以占用内存排序

Processes: 335 total, 4 running, 331 sleeping, 1932 threads 22:57:57
Load Avg: 3.83, 3.38, 4.58 CPU usage: 57.96% user, 21.47% sys, 20.55% idle
SharedLibs: 136M resident, 41M data, 22M linkedit.
MemRegions: 300919 total, 2254M resident, 46M private, 605M shared. PhysMem: 8162M used (2225M wired), 29M unused.
VM: 1538G vsize, 1098M framework vsize, 318913440(0) swapins, 326951642(0) swapouts.
Networks: packets: 69918108/79G in, 42298654/11G out. Disks: 53391990/1801G read, 35824286/1550G written.

PID COMMAND %CPU TIME #TH #WQ #PORTS MEM PURG CMPRS PGRP PPID STATE BOOSTS
0 kernel_task 8.7 62:05:45 139/5 0 2 1106M 0B 0B 0 0 running 0[0]
2856 idea 44.6 16:49.68 48 1 465 603M- 0B 862M 2856 1 sleeping *0[7290]
68674 Google Chrom 0.0 45:48.10 14 1 133 346M 0B 211M 68657 68657 sleeping *0[11]
81288 WeChat 41.1 08:11:20 30 11 36235 304M+ 27M 423M- 81288 1 sleeping *0[21759]

查了一下资料发现 Mac 下的 top 和一般 Linux 长得还不一样
推荐用 htop 彩色界面, 更加酷炫😂

1
2
brew install htop
htop

lsof

list open files 是一个列出当前系统打开文件的工具, 这和 Linux 的机制相关 -> 所有程序都是打开的文件, 所以直接 lsof 会出现很多 乱七八糟的东西 并不能看懂
这个算是比较冷门的命令 但特殊情况下很好用 仅举几个例子

1
2
lsof -i :4000 # 查看正在使用端口号 4000 的程序
lsof -p 2333 # 查看 进程号 2333 对应的文件信息

ping

看是看完了, 但是临时有个想法是, 这样子抱着字典学, 其实意义不是特别大 -> 就像念书不必每个字都认识一样, 需要的时候才查, 也许是更好的一种方式
学字典固然有进步, 但却不是效率最高的一种
多看一些工作中会常用的小技巧 会比较重要 比如 zgrep, vim 操作等等
ping 的具体内容就略过啦哈哈哈哈

scp

代表 secure copy
scp [参数] [原路径] [目标路径]
scp 是加密传输, 所以可能会慢一些

-r 递归复制目录
-i 指定秘钥文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 复制文件例子如下
scp local_file remote_username@remote_ip:remote_folder

scp local_file remote_username@remote_ip:remote_file

scp local_file remote_ip:remote_folder

scp local_file remote_ip:remote_file

# 复制目录
scp -r local_folder remote_username@remote_ip:remote_folder

scp -r local_folder remote_ip:remote_folder

# 以上情况在指定用户名时需输入密码, 否则需要用户名和密码

scp -i k.pem -r ./undertow-server ubuntu@ec2.aws.com:~/ # 利用秘钥 k.pem 把 目录 undertow-server 传到 ec2 上

# 远程到本地 把两个路径的位置交换顺序即可

其他命令

ln

意为链接 link, 看上去和 cp 有点类似, 但实际上是功能非常强大的命令
首先分两种 软链接 (类似于指针的指向而已, 几乎不占空间)和 硬链接 (类似于真的拷贝文件, 但两者绑定)

1
2
3
4
5
6
7
8
➜  z ln -s z.txt softlink-z # softlink
➜ z ln z.txt hardlink-z # hardlink

➜ z ll
total 16
-rw-r--r-- 2 mostranger staff 72B Apr 21 18:10 hardlink-z
lrwxr-xr-x 1 mostranger staff 5B Apr 21 18:09 softlink-z -> z.txt
-rw-r--r-- 2 mostranger staff 72B Apr 21 18:10 z.txt

可以看出 hardlink 的文件大小一致, 而 softlink 的很小
据说 hardlink 的文件时不占用实际空间的, 但我对此表示怀疑😂
hardlink 只能对文件不能对目录 而 softlink 两者都行

diff

这个命令感觉现在比较鸡肋了 直接 git diff 功能怕不是更强

diff 的normal 显示格式有三种提示:
a - add
c - change
d - delete
“|”表示前后2个文件内容有不同
“<”表示后面文件比前面文件少了1行内容
“>”表示后面文件比前面文件多了1行内容
diff fileA fileB # 显示两个文件的不同之处

date & cal

分别代表日期和日历
我个人觉得极其废铁… 有兴趣的自己试试好了

grep

超级强大的文本搜索工具 grep全称是Global Regular Expression Print
grep [option] pattern file
支持所有正则表达式的处理方式

-c 计算符合样式的行数
-n 显示行数
-r recursive 常见递归用法
^a 以 a 开头的内容
z$ 以 z 结尾的内容

1
2
3
grep -n 'linux' a.txt b.txt # 显示 a.txt, b.txt 中所有包含 linux 的行数, 并标明行号

cat t.txt| grep '1' # 显示 t.txt 中所有带 1 的行, 此处使用了 "|" 管道命令

wc

word count 统计各种数目
-c 字节数
-l 行数
-m 字符数(不能和 -c 同时使用)
-w 统计字数(一个字是空白 跳格 换行字符分隔的字符串)
可结合管道线做更多 fancy 的东西

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
➜  a wc a.txt
57 86 498 a.txt
➜ a wc -c a.txt
498 a.txt
➜ a wc -m a.txt
498 a.txt
➜ a wc -w a.txt
86 a.txt
➜ a wc -l a.txt
57 a.txt

ls -l | wc -l # 统计文件个数 + 1, 因为 ls -l 有一行 total
```

#### ps

即 process status, 查看进程的情况
有特定需求还是应该翻字典, 一般不太用的上 也就是看看进程 id 而已

ps -A # 显示所有进程
ps -ef # 显示所有进程信息
ps -u root # 显示 root 用户的所有进程

ps -ef | grep ssh # 结合 | 和 grep 查找特定进程
```

更新了快一个月, 四周时间也算是告一段路了
感谢自己的坚持哈哈 我觉得还是学习到了很多有趣的东西
不过更重要的恐怕是学以致用
还是多看看同事都怎么操作的 grep less 的各种技巧
以及 vim 的操作 感觉可以学习一波?

记得投食_(:з」∠)_