以下内容参考于书籍《The Linux Command Line》,中文版本翻译项目:快乐的 Linux 命令行
$
表示普通用户,#
表示超级用户exit
文件系统树:Linux 只有一个单一的文件系统树,不管有多少个磁盘或者存储设备连接到计算机上
工作目录:当我们首次登录系统(或者启动终端仿真器会话)后,当前工作目录是我们的家目录。每个用户都有他自己的家目录,当用户以普通用户的身份操控系统时,家目录是唯一允许用户对文件进行写入的地方
pwd
:当前工作目录
ls
:列出目录内容
-a
--all 列出所有文件,甚至包括文件名以圆点开头的默认会被隐藏的隐藏文件-d
--directory 通常,如果指定了目录名, ls 命令会列出这个目录中的内容,而不是目录本身。把这个选项与 -l 选项结合使用,可以看到所指定目录的详细信息,而不是目录中的内容-F
--classify 这个选项会在每个所列出的名字后面加上一个指示符。例如,如果名字是目录名,则会加上一个’/’ 字符-h
--human-readable 当以长格式列出时,以人们可读的格式,而不是以字节数来显示文件的大小-l
以长格式显示结果-r
--reverse 以相反的顺序来显示结果。通常, ls 命令的输出结果按照字母升序排列-S
命令输出结果按照文件大小来排序-t
按照修改时间来排序cd
:更改当前工作目录;直接 cd
是切换到自己的家目录;cd -
更改工作目录到先前的工作目录;cd ~username
更改工作目录到用户家目录
路径:
cd /usr/bin
cd ..
返回上一级目录文件命名
ls -a
来显示file
:确定文件类型
file filename
:打印出文件内容的简单描述less
:属于 “页面调度器” 程序类,这些程序允许通过页方式,在一页中轻松地浏览长长的文本文件
less filename
:查看文件内容。举例:less /etc/passwd
查看定义了系统中全部用户身份的文件Linux 常用目录
硬链接
ln file link
:使用 ln
命令创建硬链接。创建硬链接时,可以假设文件由两部分组成:文件内容的数据部分和文件名的名字部分;当创建文件硬链接的时候,实际上是为文件创建了额外的名字部分,并且这些名字都关系到相同的数据部分符号链接(创建 Windows 的快捷方式与其类似,是为了克服硬链接的局限性,可解决版本问题等)
ln -s item link
:使用 ln
命令创建符号链接,“item” 可以是一个文件或是一个目录lrwxrwxrwx 1 root root 11 2007-08-11 07:34 libc.so.6 -> libc-2.6.so
表明一个叫做“libc.so.6”的符号链接(前面一个是符号链接),指向一个叫做“libc-2.6.so”的共享库文件,而 11 为“libc-2.6.so”的文件名长度通配符
*
:匹配任意多个字符(包括零个或一个)?
:匹配任意一个字符(不包括零个)[characters]
:匹配任意一个属于字符集中的字符[!characters]
:匹配任意一个不是字符集中的字符[[:class:]]
:匹配任意一个属于指定字符类中的字符
[:alnum:]
:匹配任意一个字母或数字[:alpha:]
:匹配任意一个字母[:digit:]
:匹配任意一个数字[:lower:]
:匹配任意一个小写字母[:upper:]
:匹配任意一个大写字母*
:所有文件g*
:文件名以“g”开头的文件b*.txt
:以”b” 开头,中间有零个或任意多个字符,并以”.txt” 结尾的文件Data???
:以“Data”开头,其后紧接着 3 个字符的文件[abc]*
:文件名以”a”,”b”, 或”c” 开头的文件BACKUP.[0-9][0-9][0-9]
:以”BACKUP.” 开头,并紧接着 3 个数字的文件[[:upper:]]*
:以大写字母开头的文件[![:digit:]]*
:不以数字开头的文件*[[:lower:]123]
:文件名以小写字母结尾,或以“1”,“2”,或“3”结尾的文件mkdir
mkdir directory...
:创建目录。注意表示法: 在描述一个命令时,当有三个圆点跟在一个命令的参数后面,这意味着那个参数可以重复。举例:mkdir dir1 dir2 dir3
cp
cp item1 item2
:复制单个文件或目录 “item1” 到文件或目录”item2”cp item... directory
:复制多个项目(文件或目录)到一个目录下-a
, --archive 复制文件和目录,以及它们的属性,包括所有权和权限。通常,复本具有用户所操作文件的默认属性-i
, --interactive 在重写已存在文件之前,提示用户确认。如果这个选项不指定, cp 命令会默认重写文件(输入 “y”,文件就会被重写,其它的字符(例如, ”n”)会导致 cp 命令不理会文件)-r
, --recursive 递归地复制目录及目录中的内容。当复制目录时,需要这个选项(或者 -a 选项)-u
, --update 当把文件从一个目录复制到另一个目录时,仅复制目标目录中不存在的文件,或者是文件内容新于目标目录中已经存在的文件-v
, --verbose 显示翔实的命令操作信息cp file1 file2
复制文件 file1 内容到文件 file2。如果 file2 已经存在, file2的内容会被 file1 的内容重写。如果 file2 不存在,则会创建 file2cp -i file1 file2
这条命令和上面的命令一样,除了如果文件 file2 存在的话,在文件 file2 被重写之前,会提示用户确认信息cp file1 file2 dir1
复制文件 file1 和文件 file2 到目录 dir1。目录 dir1 必须存在cp dir1/* dir2
使用一个通配符,在目录 dir1 中的所有文件都被复制到目录 dir2 中。 dir2 必须已经存在cp -r dir1 dir2
复制目录 dir1 中的内容到目录 dir2。如果目录 dir2 不存在,创建目录 dir2,操作完成后,目录 dir2 中的内容和 dir1 中的一样。如果目录 dir2 存在,则目录 dir1 (和目录中的内容) 将会被复制到 dir2 中mv
mv item1 item2
or mv item... directory
:使用方法与 cp
相似-i
--interactive 在重写一个已经存在的文件之前,提示用户确认信息。 如果不指定这个选项, mv 命令会默认重写文件内容-u
--update 当把文件从一个目录移动另一个目录时,只是移动不存在的文件,或者文件内容新于目标目录相对应文件的内容-v
--verbose 当操作 mv 命令时,显示翔实的操作信息rm
(小技巧:最好先使用 ls
命令来确认待删除文件!)
rm item...
:“item” 代表一个或多个文件或目录-i
, --interactive 在删除已存在的文件前,提示用户确认信息。 如果不指定这个选项, rm 会默默地删除文件-r
, --recursive 递归地删除文件,这意味着,如果要删除一个目录,而此目录又包含子目录,那么子目录也会被删除。要删除一个目录,必须指定这个选项-f
, --force 忽视不存在的文件,不显示提示信息。这选项颠覆了“–interactive”选项-v
, --verbose 在执行 rm 命令时,显示翔实的操作信息rm file1
默默地删除文件rm -i file1
除了在删除文件之前,提示用户确认信息之外,和上面的命令作用一样rm -r file1 dir1
删除文件 file1, 目录 dir1,及 dir1 中的内容rm -rf file1 dir1
同上,除了如果文件 file1,或目录 dir1 不存在的话, rm 仍会继续执行什么是命令
相关命令
type command
,显示命令的类型which program
,显示可执行程序(不包括内部命令和命令别名)的位置help command
,显示shell内部命令帮助文档。对于某些可执行程序,有program --help
来显示用法man program
,是一个分页程序,用于显示手册文档;查找特定章节:man section search_term
;显示关键字匹配:man -k keyword
apropos keyword
,粗糙简单地显示手册种的关键字匹配,类似于man -k keyword
whatis ...
,显示匹配特定关键字的手册页的名字和一行命令说明info ...
,info 程序读取 info 文件, info 文件是树型结构,分化为各个结点,每一个包含一个题目。info 文件包含超级链接,它可以让你从一个结点跳到另一个结点。一个超级链接可通过它开头的星号来辨别出来,把光标放在它上面并按下 enter 键,就可以激活它alias
显示所有已有别名的命令;alias name='string'
,创建别名命令;unalias ...
删除别名命令
alias foo='cd /usr; ls; cd -'
标准输入(stdin,0)、标准输出(stdout,1)、标准错误(stderr,2)
I/O重定向
>
:... > output_file
;重定向符来重定向输出结果时,目标文件总是从开头被重写;> get_empty_file
是删除文件内容或新建一个文件的小技巧;>>
用于追加标准输出2>
:标准输入,输出和错误, shell 内部参考它们为文件描述符 0, 1 和 22>&1
,标准错误的重定向必须总是出现在标准输出重定向之后。举例:ls -l /bin/usr > ls-output.txt 2>&1
&>
来重定向标准输出和错误到文件,当然也可追加文本内容&>>
。举例:ls -l /bin/usr &> ls-output.txt
ls -l /bin/usr 2> /dev/null
<
:cat
相关命令
cat [file]
,读取一个或多个文件的内容,显示文件而没有分页,常用于显示较短的文件内容或拼接多个文件的内容cat
,而不接任何参数表示接收来自键盘的输入,从键盘输入完之后按下 Ctrl-d
表示已到达文件末尾(EOF);这种方法可用于记录简短的文本内容,例如:先输入cat > lazy_dog.txt
,再输入文本内容sort
命令),从数据列表中删除任何重复行;* -d
返回重复的数据,* -u
返回仅出现一次的数据,* -c
用于显示该行重复的次数wc -l
只显示行数,wc -w
只显示单词数,wc -c
只显示字节数;通常和管道结合使用
ls /bin /usr/bin | sort | uniq | wc -l
grep pattern [file...]
用于查找内容包含指定的范本样式的文件;* -a
表示不忽略二进制数据,* -c
计算符合样式的行数,* -e<范本样式>
指定正则表达式来查找,* -i
忽略大小写来匹配,* -l
输出包含匹配内容的文件名,* -L
输出不包含匹配内容的文件名,* -n
加上行标,* -h
在显示符合样式的那一行之前表示该行所属的文件名称* -q
隐藏文件名,* -v
显示文件名,* -c
显示字节数,* -n
显示行数* -q
隐藏文件名,* -v
显示文件名,* -c
显示字节数,* -n
显示行数,* -f
循环读取文件内容,使用Ctrl-c来结束;* --pid=PID
与-f合用,表示在进程ID,PID死掉之后结束ls /usr/bin | tee ls.txt | grep zip
管道 |
command1 | command2
:命令可以从标准输入读取数据,然后再把数据输送到标准输出,命令的这种能力被一个 shell 特性所利用,这个特性叫做管道线相关命令
echo -n
:删除输出结果末尾的换行符展开
echo *
echo [[:upper:]]*
,echo /usr/*/share
;隐藏路径名展开:echo *
不能直接显示隐藏文件,使用echo .*
可以显示隐藏文件但也可能显示出错误结果(比如带..
的当前工作目录以及它的父目录),一种可行的模式ls -d .[!.]?*
或直接用ls -A
~
用在一个单词的开头时,它会展开成指定用户的家目录名,如果没有指定用户名,则是当前用户的家echo ~
,echo ~foo
$((expression))
,算术表达式只支持整数(全部是数字,不带小数点),支持加+、减-、乘*、整数除/、取余%、取幂**。举例:echo $(((5**2) * 3))
{}
:可从花括号的模式中批量创建多个文本字符串,花括号表达式本身可包含一个由逗号分开的字符串列表,或者一系列整数,或者单个的字符串;这种模式不能嵌入空白字符。举例:echo Front-{A,B,C}-Back
,echo {Z..A}
,echo a{A{1,2},B{3,4}}b
,mkdir {2007..2009}-0{1..9} {2007..2009}-{10..12}
echo $USER
,printenv | less
ls -l $(which cp)
,file $(ls /usr/bin/* | grep zip)
,也可以使用倒引号``来替换美元符号和括号引用机制:用来删除多余的空格:echo this is a test
;用来将未定义的$1替换为空字符串: echo The total is $100.00
ls -l "two words.txt"
转义字符\
:
Ctrl-a
:移动光标到行首Ctrl-e
:移动光标到行尾Ctrl-f
:光标前移一个字符,和右箭头作用一样Ctrl-b
:光标后移一个字符,和左箭头作用一样Alt-f
:光标前移一个单词Alt-b
:光标后移一个单词Ctrl-l
:清空屏幕,类似于clear
命令Ctrl-d
:删除光标处的字符Ctrl-t
:交换光标位置的字符和光标前面(左边)的一个字符Alt-t
:交换光标位置的单词和光标前面(左边)的一个单词(整体交换)Alt-l
:把从光标位置到字尾的字符转换成小写字母Alt-u
:把从光标位置到字尾的字符转换成大写字母Ctrl-k
:剪切从光标位置(含)到行尾的文本Ctrl-u
:剪切从光标位置(不含)到行首的文本Alt-d
:剪切从光标位置到当前单词词尾的文本Alt-Backspace
:剪切从光标位置到词头的文本。如果光标在一个单词的开头,剪切前一个单词Ctrl-y
:把剪切环中的文本粘贴到光标位置(注意:是剪切环缓存的文本!) history | less
)
Ctrl-p
:移动到上一个历史条目,类似于上箭头按键Ctrl-n
:移动到下一个历史条目,类似于下箭头按键Alt-<
:移动到历史列表开头Alt->
:移动到历史列表结尾,即当前命令行Ctrl-r
:反向递增搜索。从当前命令行开始,向上递增搜索。找到某条历史命令后,可使用Ctrl-j
来继续编辑或运行当前命令Alt-p
:反向搜索,不是递增顺序。输入要查找的字符串,然后按下Enter,执行搜索Alt-n
:向前搜索,非递增顺序Ctrl-r
:执行历史列表中的当前项,并移到下一个。如果想要执行历史列表中一系列的命令,这很方便!!
:重复最后一次执行的命令(相当于按下上箭头按键和 Enter 键)!number
:重复历史列表中第 number 行的命令!string
:重复最近历史列表中,以这个字符串开头的命令!?string
:重复最近历史列表中,包含这个字符串的命令用户、组成员、其他人
id
:查看自己的身份信息文件类型(文件属性列表的第一个字符)
-
:普通文件;d
:目录;l
:符号链接,剩余的文件属性总是”rwxrwxrwx”,而且都是虚拟值。真正的文件属性是指符号链接所指向的文件的属性;c
:一个字符设备文件,这种文件类型是指按照字节流来处理数据的设备,比如终端机、调制解调器;b
:一个块设备文件,这种文件类型是指按照数据块来处理数据的设备,例如一个硬盘、CD-ROM 盘文件模式及权限修改
chmod
:更改文件或目录的模式(权限),支持八进制数字表示法或符号表示法(注意:只有文件的所有者或者超级用户才能更改文件或目录的模式);* -c
若该文件权限确实已经更改,才显示其更改动作;* -v
显示权限变更的详细资料;* -R
对目前目录下的所有文件与子目录进行相同的权限变更(即以递归的方式逐个变更)u
文件或目录的所有者;g
用户组;o
其他人;a
是”u”, ”g” 和“o”三者的联合+
表示添加一种权限;-
表示去掉一种权限;=
表示指定某些权限,并去掉其他权限u+x
为文件所有者添加可执行权限;+x
为文件所有者,用户组,和其他所有人添加可执行权限,等价于 a+x
;ugo-rw
删除用户、组、其他人的读权限和写权限;go=rw
给群组的主人和任意文件拥有者的人读写权限,若群组的主人或全局之前已经有了执行的权限,他们将被移除;u+x,go=rw
给文件拥有者执行权限并给组和其他人读和执行的权限。多种设定可以用逗号分开设置默认权限
umask
:掩码的二进制形式中,出现数字 1 的位置,相应地关掉一个文件模式属性(默认为0002或0022,若设置为0000则表示关闭所有掩码)umask 0022
(000 000 010 010),则掩码后文件的权限更改为-rw-r–r–特殊权限
s
:当应用到一个可执行文件时,它把有效用户 ID 从真正的用户(实际运行程序的用户)设置成程序所有者的 ID,这种操作通常会应用到一些由超级用户所拥有的程序;因为这会引起安全方面的问题,所有可以设置 setuid 位的程序个数,必须控制在绝对小的范围内。举例:-rwsr-xr-x
一个程序被设置为 setuid 属性g
:相似于 setuid 位,把有效用户组 ID 从真正的用户组 ID 更改为文件所有者的组 ID;如果设置了一个目录的 setgid 位,则目录中新创建的文件具有这个目录用户组的所有权,而不是文件创建者所属用户组的所有权。举例:drwxrwsr-x
具有 setgid 属性的目录t
:继承于 Unix,在 Unix 中,它可能把一个可执行文件标志为“不可交换的”。在 Linux 中,会忽略文件的 sticky 位,但是如果一个目录设置了 sticky 位,那么它能阻止用户删除或重命名文件,除非用户是这个目录的所有者,或者是文件所有者,或是超级用户。这个经常用来控制访问共享目录,比方说/tmp。举例:drwxrwxrwt
设置了 sticky 位的目录更改身份
su [-[l]] [user]
:以其他用户身份和组 ID 运行一个 shell
-l
则需指定用户,会加载此用户的 shell 环境,并且工作目录会更改到这个用户的家目录su -
表示使用超级用户,输入正确密码登录成功后,出现一个新的shell 提示符#
(而不是$
),当前工作目录更改为超级用户的家目录(通常是/root),且能执行超级用户所使用的命令;当工作完成后,输入 “exit”,则返回到原来的 shell。和仅使用su
的区别:su
只是切换了root身份,但Shell环境仍然是普通用户的Shell,pwd一下,工作目录仍然是普通用户的工作目录;su -
连用户和Shell环境一起切换成root身份,工作目录变成root的工作目录su -c 'command'
在不启动新shell的情况下,执行单条命令。举例:su -c 'ls -l /root/*'
sudo
:以另一个用户身份执行命令
更改用户
chown [owner][:[group]] file...
:用来更改文件或目录(后面这个file参数)的所有者(owner)和用户组(group),使用这个命令需要超级用户权限bob
:把文件所有者从当前属主更改为用户 bobbob:users
:把文件所有者改为用户 bob,文件用户组改为用户组 users:admins
:把文件用户组改为组 admins,文件所有者不变bob:
:文件所有者改为用户 bob,文件用户组改为,用户 bob 登录系统时,所属的用户组useradd
groupadd
ps
ps
:默认显示当前控制台下属于当前用户的进程。TTY 是 “Teletype” 的简写,是指进程的控制终端,这里Unix 展示它的年龄,若为?则表示没有控制终端。 TIME 字段表示进程所消耗的 CPU 时间数量ps -u username
查看指定用户信息ps -o pid,ppid,pgrp,session,tpgid,comm
输出指定字段ps ef
:查看系统上的运行的所有进程+命令行,System V风格;ps ef | grep ...
常用组合用法,查找特定进程ps aux
:能够显示属于每个用户的进程信息,BSD 风格;ps aux | grep ...
pstree
:以树结构来显示进程关系
pstree -p
:显示PID;pstree PID
以树状图显示进程PID为的进程以及子孙进程;pstree -p PID
如果有-p参数则同时显示每个进程的PIDtop
&
ps
查看进程,或使用jobs
命令查看此任务$!
:包含放到后台执行的最后一个任务的进程 ID 号jobs
fg %工作序号
:fg命令之后,跟随着一个百分号和工作序号(使用jobs
查看)。如果我们只有一个后台任务,那么 jobspec 是可有可无的Ctrl-c
:中断进程,发送一个叫做 TSTP(终端停止)的信号;Ctrl-z
:停止进程,发送一个叫做 TSTP(终端停止)的信号1
,HUP:挂起。发送这个信号到终端机上的前台程序,程序会终止。许多守护进程也使用这个信号,来重新初始化。这意味着,当发送这个信号到一个守护进程后,这个进程会重新启动,并且重新读取它的配置文件2
,INT:中断。实现和 Ctrl-c 一样的功能,由终端发送。通常,它会终止一个程序3
,QUIT:退出9
,KILL: 杀死。Kill 信号从不发送到目标进程,而是内核立即终止这个进程。当一个进程以这种方式终止的时候,它没有机会去做些“清理”工作,或者是保存劳动成果。因为这个原因,把 KILL 信号看作杀手锏,当其它终止信号失败后,再使用它,它不能被忽略11
,SEGV:段错误。如果一个程序非法使用内存,就会发送这个信号。也就是说,程序试图写入内存,而这个内存空间是不允许此程序写入的15
,TERM:终止。这是 kill 命令发送的默认信号。如果程序仍然“活着”,可以接受信号,那么这个信号终止18
,CONT:继续。在停止一段时间后,进程恢复运行19
,STOP:停止。个信号导致进程停止运行,而没有终止。就像 KILL 信号那样,它不被发送到目标进程,因此它不能被忽略20
,TSTP:终端停止。当按下 Ctrl-z 组合键后,终端发送这个信号。不像 STOP 信号, TSTP 信号由目标进程接收,且可能被忽略28
,WINCH:改变窗口大小。当改变窗口大小时,系统会发送这个信号。一些程序,像 top 和 less 程序会响应这个信号,按照新窗口的尺寸,刷新显示的内容kill [-signal] PID...
:用来给程序发送信号,默认情况下发送 TERM(终止)信号!需要拥有超级用户权限才能杀死别人的进程
kill -l
查看所有信号kill -u username
杀死指定用户所有进程killall [-u user] [-signal] name...
:给匹配特定程序或用户名的多个进程发送信号,与 kill 不同的是它会杀死指定名字的所有进程。需要拥有超级用户权限才能杀死别人的进程vmstat
:查看虚拟内存使用情况
xload
:一个图形界面程序,可以画出系统负载的图形tload
:与 xload 程序相似,但是在终端中画出图形。使用 Ctrl-c,来终止输出printenv | less
查看环境变量、printenv USER
查看用户set | less
查看环境变量echo $HOME
查看变量alias
查看别名:别名既不可用 set 命令也不可用 printenv 命令显示,使用 alias 命令查看~/.bashrc
可能是最重要的启动文件,因为它几乎总是被读取。非登录 shell 默认会读取它,并且大多数登录 shell 的启动文件会以能读取 ~/.bashrc 文件的方式来书写
export PATH
:让这个 shell 的子进程可以使用 PATH 变量的内容.bashrc
文件为.bashrc.bak
,常见的备份文件后缀:.bak、.sav、.old、.origsource filename
或. filename
(source
的另一种形式为一个点.
),在当前bash环境下读取并执行filename中的命令。举例:source .bashrc
u
Ctrl-r
a
在光标后一位开始添加,A
在当前行末尾开始添加o
下面插入一行,O
上面插入一行f
,再输入待查找的字符;后续按分号可继续查找下一个此字符/
,再输入待查找的字符、单词、短语、正则表达式,再按下回车;通过按 n 命令来重复先前的查找:%s/before/after/g
表示全局替换,:%4,7s/before/after/g
表示对4-7行替换
:%s/before/after/gc
,最后多加一个c;replace with Line (y/n/a/q/l/^E/^Y)?
这里用于确认每一处的操作
vi file1 file2 file3...
:同时打开多个文件:n
切换到下一个;:n!
不保存对当前文件的修改,强制切换文件:N
切换到上一个buffers
:查看VI中的所有编辑的文件列表buffer n
:切换到第n个文件;buffer! n
:不保存,强制切换:r another_file
ZZ
、:wq
:w new_file
查找软件包
apt-get update
,apt-cache search search_string
yum search search_string
安装软件包(package_name指软件包实际名称,package_file指包含在软件包中的文件名)
apt-get update; apt-get install package_name
(举例:apt-get update; apt-get install emacs
)yum install package_name
dpkg --install package_file
rpm -i package_file
(使用底层的 rpm 程序来执行安装任务,若 rpm 程序发现缺少了一个依赖,则会报错并退出。举例:rpm -i emacs-22.1-7.fc7-i386.rpm
)删除软件包
apt-get remove package_name
(举例:apt-get remove emacs
)yum erase package_name
更新软件包
apt-get update; apt-get upgrade
(举例:apt-get remove emacs
)yum erase package_name
dpkg --install package_file
(与安装的命令相同)rpm -U package_file
列出安装包
dpkg --list
rpm -qa
确认软件包状态
dpkg --status package_name
rpm -q package_name
显示软件包信息
apt-cache show package_name
yum info package_name
查找安装了某个文件的软件包(包文件识别)
dpkg --search file_name
rpm -qf file_name
mount
:用来挂载文件系统。执行这个不带参数的命令,将会显示一系列当前挂载的文件系统,其显示列表格式为:设备 on 挂载点 type 文件系统类型(可选的)。
umount
:用于卸载文件系统fdisk
:可以在设备上编辑,删除,和创建分区mkfs
dd
:d if=input_file of=output_file [bs=block_size [count=blocks]]
把数据块从一个地方复制到另一个地方(注意:由于可能会错误输入 if 或 of 的规范,导致文件数据误删,因此按下回车前必须得再三确认!)
dd if=/dev/sdb of=/dev/sdc
把第一个驱动器(或硬盘)中的所有数据复制到第二个驱动器中;dd if=/dev/sdb of=flash_drive.img
把一个驱动器的内容复制到一个普通文件中供以后恢复或复制数据md5sum
:产生一个独一无二的十六进制数字,比如:生成一个文件的 checksum 数字检查和检测网络
ping
:发送一个特殊的网络数据包,叫做 IMCP ECHO_REQUEST,到一台指定的主机,大多数接收这个包的网络设备将会回复它,来允许网络连接验证
traceroute(某些系统叫做 tracepath)
:会显示从本地到指定主机要经过的所有“跳数”的网络流量列表;对于那些提供标识信息的路由器,我们能看到它们的主机名, IP 地址和性能数据,这些数据包括三次从本地到此路由器的往返时间样本。对于那些没有提供标识信息的路由器(由于路由器配置,网络拥塞,防火墙等方面的原因),则会看到几个星号 ***netstat
:用来检查各种各样的网络设置和统计数据
netstat -ie
:查看系统中的网络接口netstat -r
:显示内核的网络路由表,展示了系统是如何配置网络之间发送数据包的文件传输
ftp
:
ftp fileserver
连接到远端ftp服务器,接着需要输入用户名(如:anonymous)以及密码(如:[email protected])lcd Desktop
在ftp服务器中,对本地目录进行切换get file
:从ftp服务器中下载文件file到本地的当前目录中bye
、quit
、exit
:退出ftp服务器lftp
wget
:许多选项允许 wget 递归地下载,在后台下载文件(你退出后仍在下载),能完成未下载全的文件(从网络和 FTP 网站两者上都能下载数据,不只能下载单个文件,多个文件,甚至整个网站都能下载)
wget http://linuxcommand.org/index.php
下载一个网页远程连接(安全通信)
ssh
:由两部分组成。 SSH 服务器运行在远端主机上运行,在端口号 22 上监听将要到来的连接,而 SSH 客户端用在本地系统中,用来和远端服务器通信。若不能成功连接,则需考虑原因(如:删除∼/.ssh/known hosts
文件中的废弃(或攻击性)密钥)
ssh remote-sys
:连接远程服务器,需要输入密码ssh username@remote-sys
:以某个用户来连接远程服务器,需要输入密码ssh remote-sys command
:在远程服务器中执行某条命令,并将结果返回到本地系统shell会话中
ssh remote-sys 'ls \*' > dirlist.txt
:在远端系统中执行 ls 命令,并把命令输出重定向到本地系统中的一个文件里面(命令中的单引号是不想让路径名展开操作在本地执行,而希望它在远端系统中被执行) ssh remote-sys 'ls * > dirlist.txt'
:在远端系统中执行 ls 命令,并重定向到远端服务器中(注意:单引号的范围)scp
:安全复制文件,与熟悉的 cp 程序非常相似。最显著的区别就是源或者目标路径名要以远端主机的名字,后跟一个冒号字符开头
scp remote-sys:document.txt .
:从远端系统 remote-sys 的家目录下复制文档 document.txt,到我们本地系统的当前工作目录下(.)scp username@remote-sys:document.txt .
:指定某个用户sftp
: 与 ftp 程序很相似。但它不用明码形式来传递数据,而使用加密的 SSH 通道。 sftp 有一个重要特性强于传统的 ftp 命令,就是** sftp 不需要远端系统中运行 FTP 服务器,仅需要 SSH 服务器,这意味着任何一台能用 SSH 客户端连接的远端机器,可当作类似于 FTP 的服务器来使用**locate
:快速搜索路径名数据库,并且输出每个与给定字符串相匹配的文件路径名
locate bin/zip
:输出任一个包含字符串“bin/zip”的路径名find
:locate 程序只能依据文件名来查找文件,而 find 程序能基于各种各样的属性,搜索一个给定目录(以及它的子目录),来查找文件
find path
:在某path下查找文件find path -type [bcdfl]
:指定文件类型来查找文件。b:块设备文件;c:字符设备文件;d:目录;f:普通文件;l:符号链接-name
:文件名条件,一般加入双引号以防止shell进行路径名展开。比如: -name "\*.JPG"
-size
:文件大小条件,文件大小参数有:b:512 个字节块(如果没有指定单位,则这是默认值);c:字节;w:两个字节的字;k:千字节(1024个字节单位);M:兆字节;G:千兆字节。==出现数值参数时,均可使用 “+”(大于数值)、“-”(小于数值) 或 不指定(精确等于数值)来进行限制。==比如: -size +1M
指大于1M的文件( expression 1 ) -op ( expression 2 )
:op有:-and
(简写-a
);-or
(简写-o
);-not
(简写!
)
find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)
用于确定是否一个目录中的所有的文件和子目录拥有安全权限(注意:圆括号需要进行转义,以防止shell解释它们!)find
搜索结果执行 预定义操作(查看find手册)
-print
:把匹配文件的全路径名输送到标准输出(如果没有指定其它操作,这是默认操作)-delete
:删除当前匹配的文件(注意:使用前再三确认,可先用-print来检查)ls
:对匹配的文件执行等同的 ls -dils 命令,并将结果发送到标准输出quit
:一旦找到一个匹配,则退出
find ~ -type f -name '*.BAK' -delete
找出用户家目录(和它的子目录)下搜索每个以.BAK 结尾的文件名,并删除它们。等价于find ~ -type f -and -name '*.BAK' -and -print
find
搜索结果执行 用户自定义操作
-exec command {} ;
:基于find搜索结果执行其他命令。command 是指一个命令的名字, {} 是当前路径名的符号表示,分号是要求的界定符表明命令结束(执行多次命令)-exec command {} +
:通过把末尾的分号改为加号,则把搜索结果结合为一个参数列表,然后执行一次所期望的命令(合并搜索结果,且仅执行一次命令)-ok command {} ;
:使用 -ok 行为来代替 -exec,在执行每个指定的命令之前,会让用户确认是否执行xargs
:将标准输入转换为一个命令的参数列表(被放置到命令行中参数个数是有限制的,–show–limits 选项的 xargs 命令,来查看命令行的最大值)
find ~ -type f -name 'foo\*' -print | xargs ls -l
find 命令的输出被管道到 xargs 命令,反过来, xargs 会为 ls 命令构建参数列表,然后执行 ls 命令-depth
:指导 find 程序先处理目录中的文件,再处理目录自身。当指定 -delete 行为时,会自动应用这个选项-maxdepth levels
:当执行测试条件和行为的时候,设置 find 程序陷入目录树的最大级别数-mindepth levels
:在应用测试条件和行为之前,设置 find 程序陷入目录数的最小级别数-mount
:指导 find 程序不要搜索挂载到其它文件系统上的目录-noleaf
:指导 find 程序不要基于搜索类 Unix 的文件系统做出的假设,来优化它的搜索touch file
:用来设置或更新文件的访问,更改,和修改时间;若文件名参数是一个不存在的文件,则会创建一个空文件
stat file
:是 ls 命令更丰富的版本,展示系统对某个文件及其属性所知道的所有信息
压缩文件(在 Linux 中 gzip 是主要的压缩程序,而 bzip2 则位居第二)
gzip
:用来压缩一个或多个文件,原始文件的压缩版会替代原始文件。gunzip
:用来把压缩文件复原为没有被压缩的版本
zcat
:解压文件并输出到标准输出,相当于带有 -c 选项的 gunzip 命令zless
:查看zip压缩文件bzip2
:与 gzip 程序相似,但是使用了不同的压缩算法,舍弃了压缩速度,而实现了更高的压缩级别
bunzip2
和 bzcat
程序来解压缩文件;bzip2 文件也带有 bzip2recover
程序,其会试图恢复受损的.bz2 文件归档文件
tar
是 tape archive 的简称,揭示了它的根源,它是一款制作磁带备份的工具。而它仍然被用来完成传统任务,它也同样适用于其它的存储设备
tar mode[options] pathname...
:注意:不需要短横线-,且必须首先指定操作模式mode,然后才是其它的选项optionfind playground -name 'file-A' | tar czf playground.tgz -T -
;find playground -name 'file-A' | tar cjf playground.tbz -T -
文件名“-”,则其被看作是标准输入或输出,正是所需(顺便说一下,使用“-”来表示标准输入/输出的惯例,也被大量的其它程序使用)tar xf archive.tar pathname
:当抽取一个归档文件(archive.tar)时,仅抽取单个文件(pathname)或若干个需要的文件(使用通配符--wildcards
)
tar xf ../playground2.tar --wildcards 'home/me/playground/dir-\*/file-A'
sudo tar cf /media/BigDisk/home.tar /home; cd /(到另一个系统的根目录下进行挂载); sudo tar xf /media/BigDisk/home.tar
借助U盘来复制家目录及其内容到另一个系统中find playground -name 'file-A' -exec tar rf playground.tar '{}' '+'
使用 find 命令来产生一个文件集合,然后这些文件被包含到归档文件中。这里是使用 find 命令来匹配 playground 目录中所有名为 file-A 的文件,然后使用 -exec 行为,来唤醒带有追加模式(r)的 tar 命令,把匹配的文件添加到归档文件 playground.tar 里面 find playground -name 'file-A' | tar cf - --files-from=- | gzip > playground.tgz
使用 find 程序产生了一个匹配文件列表,然后把它们管道到 tar 命令中。这个 --file-from 选项(也可以用 -T 来指定)导致 tar 命令从一个文件而不是命令行来读入它的路径名列表。最后,这个由 tar 命令产生的归档文件被管道到 gzip 命令中,然后创建了压缩归档文件 playground.tgzzip
:既是压缩工具,也是一个打包工具,它读取和写入.zip 文件
zip options zipfile file...
(会自动添加 .zip 扩展名,也可显示给zipfile添加后缀.zip)
store
表示没有压缩的文件;deflate
表示对文件执行压缩操作zip -r playground.zip playground
添加 -r 将会包含文件目录及其内容-@
选项:把一系列的文件名管道到 zip 命令
find playground -name "file-A" | zip -@ file-A.zip
使用 find 命令产生一系列与“file-A”相匹配的文件列表,并且把此列表管道到 zip 命令,然后创建包含所选文件的文件包 file-A.zipunzip
:抽取zip文件的内容。举例:unzip ../playground.zip
-l
选项)-p
选项)举例:unzip -p ls-etc.zip | less
同步文件与目录
rsync
:同步本地与远端的目录,通过使用 rsync 远端更新协议,此协议允许 rsync 快速地检测两个目录的差异,执行最小量的复制来达到目录间的同步
rsync options source destination
:将 source 的内容同步到 destination
-a
递归和保护文件属性;-v
冗余输出;--delete
删除可能在备份设备中已经存在但却不再存在于源设备中的文件(更新时,删除已有的旧文件)sudo rsync -av --delete /etc /home /usr/local /media/BigDisk/backup
sudo rsync -av --delete --rsh=ssh /etc /home /usr/local remote-sys:/backup
添加了 --rsh=ssh 选项,其指示 rsync 使用 ssh 程序作为它的远程 shell。以这种方式,我们就能够使用一个 ssh 加密通道,把数据安全地传送到远程主机中。其次,通过在目标路径名前加上远端主机的名字(在这种情况下,远端主机名为 remote-sys),来指定远端主机rsync -av -delete rsync://rsync.gtlib.gatech.edu/fedora-linuxcore/development/i386/os fedora-devel
使用了远端 rsync 服务器的 URI,其由协议(rsync:// ,远端主机名(rsync.gtlib.gatech.edu),和软件仓库的路径名组成grep
(global regular expression print)
grep [options] regex [file...]
-i
忽略大小写(–ignore-case);-v
不匹配的项(–invert-match);-c
匹配的数量(–count);-l
打印包含匹配项的文件名,而不是文本行本身(–files-with-matches);-L
相似于 -l 选项,但是只是打印不包含匹配项的文件名(–files-without-match);-n
在每个匹配行之前打印出其位于文件中的相应行号(–line-number);-h
应用于多文件搜索,不输出文件名(–no-filename)元字符 ^ $ . [ ] { } - ? * + ( ) | \
.
:匹配任意一个字符。举例:grep -h '.zip' dirlist*.txt
^ $
:正则表达式只有在文本行的开头(^)或末尾(KaTeX parse error: Expected group after '^' at position 17: …被找到时,才算发生一次匹配。`^̲` 将匹配空行[]
:从一个指定的字符集合中匹配一个单个的字符。举例:grep -h '[bg]zip'
匹配包含字符串“bzip”或者“gzip”的任意行^
:如果在**正则表示式中的第一个字符(在中括号表达式中,若^不在第一个位置则表示一个普通字符)**是一个插入字符,则剩余的字符被看作是不会在给定的字符位置出现的字符集合。举例:grep -h '[^bg]zip'
文件名都包含字符串“zip”,并且“zip”的前一个字符是除了“b”和“g”之外的任意字符[.-.]
:任意字符的区域都能按照这种方式表达(如:grep -h '[A-Z]'
),也可包括多个区域(如:grep -h '[A-Za-z0-9]'
);若想在一个正则表达式中单纯地包含一个连字符(-),则将其作为第一个字符(如:grep -h '[-AZ]'
)POSIX字符集
locale
:
export LANG=POSIX
:把 LANG 变量设置为 POSIX,来更改 locale,使其使用传统的 Unix 行为;也可把这条语句添加到 .bashrc 文件中,使这个更改永久有效^ $ . [ ] *
,而其它的所有字符被认为是文本字符。在 BRE 中,字符“(”,“)”,“{”,和“}”用反斜杠转义后,被看作是元字符
sed 's/regexp/replacement/' distros.txt
为例,若序列 \n
( n 是指从 1 到 9 的数字,如 \3
)出现在 replacement 中,则这个序列指的是在前面正则表达式 regexp 中相对应的子表达式(用圆括号括起来的),所以有 sed 's/([0-9]{2})/([0-9]{2})/([0-9]{4})$/\3-\1-\2/' distros.txt
的实例^ $ . [ ] *
+ ( ) { } ? + |
。在 ERE 中,在任意元字符之前加上反斜杠会导致其被看作是一个文本字符egrep
相当于grep -E
(GUN 版本的 grep 程序也支持扩展的正则表达式,当使用了 -E 选项之后)Alternation机制
|
为标记,grep -E
相当于egrep
echo "AAA" | grep -E 'AAA|BBB|CCC'
匹配字符串 AAA 或者是字符串 BBB 或者是字符串 CCCgrep -Eh '^(bz|gz|zip)' dirlist*.txt
将会在列表中匹配以“bz”,或“gz”,或“zip”开头的文件名,而 rep -Eh '^bz|gz|zip' dirlist*.txt
则会匹配任意以“bz”开头,或包含“gz”,或包含“zip”的文件名限定符
?
:匹配零个或一个元素
^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$
在圆括号之后加上一个问号,来表示它们将被匹配零次或一次,又因为通常圆括号都是元字符(在 ERE 中),所以我们在圆括号之前加上了反斜杠,使它们成为文本字符。此正则表达式可用来匹配这两种电话号码:(nnn) nnn-nnnn 或 nnn nnn-nnnn,n 代表数字*
:匹配任意多个元素(包括零个)
[[:upper:]][[:upper:][:lower:] ]*.
这个表达式由三个元素组成:一个包含 [:upper:] 字符集的中括号表达式,一个包含[:upper:] 和 [:lower:] 两个字符集以及一个空格的中括号表达式,和一个被反斜杠字符转义过的圆点。第二个元素末尾带有一个 * 元字符,所以在开头的大写字母之后,可能会跟随着任意数目的大写和小写字母和空格。将匹配 “This works.” 与 “This Works.” ,而不匹配 “this does not”(因为不是大写字母开头)+
:匹配一个或多个元素{ }
:匹配特定个数的元素
n
:匹配前面的元素,如果它确切地出现了 n 次n,m
:匹配前面的元素,如果它至少出现了 n 次,但是不多于 m 次n,
:匹配前面的元素,如果它出现了 n 次或多于 n 次,m
:匹配前面的元素,如果它出现的次数不多于 m 次^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$
是 ^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$
的简化版本正则表达式的一些应用
find . -regex '.*[^-\_./0-9a-zA-Z].*'
使用 find 扫描出包含空格和其它潜在不规范字符的路径名(因为find需要精确的路径名)locate --regex 'bin/(bz|gz|zip)'
在 locate 中使用正则表达式less
中应用正则表达式:/^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$
vim
中应用基本的正则表达式:/([0-9]\{3\}) [0-9]\{3\}-[0-9]\{4\}
;:hlsearch
可打开 vim 的高亮模式zgrep
:允许 grep 来读取压缩文件
cat
:用于连接文件并打印到标准输出设备上
-n 或 --number
:由 1 开始对所有输出的行数编号-b 或 --number-nonblank
:和 -n 相似,只不过对于空白行不编号-v 或 --show-nonprinting
:显示不可打印字符,使用 ^ 和 M- 符号,除了 LFD 和 TAB 之外-s 或 --squeeze-blank
:将有连续两行以上的空白行,就代换为一行的空白行-E 或 --show-ends
:在每行结束处显示 $-T 或 --show-tabs
:将 TAB 字符显示为 ^I-A, --show-all
:等价于 -vET-e
:等价于"-vE"选项-t
:等价于"-vT"选项cat > xxx_file
直接从命令行中输入一些内容到xxx_file文件,使用 Ctrl-d
完成输入cat -Ans xxx_file
显示文件中的各种非打印字符、超过连续两行的空白行被换成一个空白行、显示行标号等sort
:对标准输入的内容,或命令行中指定的一个或多个文件进行排序,然后把排序结果发送到标准输出
| sort -nr -k 5 |
使用第5个字段来排序-k 1,1 -k 2n
是使用了两个键来排序,第一个键开始并结束于第一个字段,第二个键使用第二个字段且按照数值来排序(一些选项字母添加在键值说明符的末尾,用来指定排序的种类,如:b(忽略开头的空格), n(数值排序), r(逆向排序)等) sort -k 3.7nbr -k 3.1nbr -k 3.4nbr
指定键值字段中的偏移量,-k 3.7nbr 是指使用第三个字段中的第七个字符作为键,并且忽略空格,实现一个逆序数值排序sort -t ':' -k 7
指定分隔符为冒号(:)sort > xxx_file
直接从命令行中输入一些内容到xxx_file文件,并完成排序工作,使用 Ctrl-d
完成输入uniq
:给定一个排好序的文件(包括标准输出), uniq 会删除相邻的任意重复行,并且把结果发送到标准输出;常和 sort 程序一块使用,来清理重复的输出
uniq > xxx_file
直接从命令行中输入一些内容到xxx_file文件,并完成去重工作(若有序),使用 Ctrl-d
完成输入cut
:从文本行中抽取文本,并把其输出到标准输出,它能够接受多个文件参数或者标准输入
-c char_list
:从文本行中抽取由 char_list 定义的文本,这个列表可能由一个或多个逗号分隔开的数值区间组成-b byte
:以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志-f field_list
:从文本行中抽取一个或多个由 field_list 定义的字段,这个列表可能包括一个或多个字段,或由逗号分隔开的字段区间-d delim_char
:当指定 -f 选项之后,使用 delim_char做为字段分隔符(默认使用 tab 字符)--complement
:抽取整个文本行,除了那些由 -c 和/或 -f 选项指定的文本b c f
list的范围:N
表示第N个(字符c、字节b、字段f);N-
表示从第N个到最后一个;N-M
表示从第N个到第M个;-M
表示从第一个到第M个cut -d ':' -f 1,3 distros.txt | cut -c 7-10
paste
:把每个文件以列对列(或行)的方式,一列列(或行)地加以合并 ,他就是相当于把两个不同的文件内容粘贴在一起,形成新的文件
-d
:指定分隔符-s
:不使用平行的行目输出模式,而是每个文件占用一行(类似于转置,把每个文件当作一行)。举例:paste -s -d '*' file1 file2
join
:把来自于多个基于共享关键域的文件的数据结合起来(类似于关系型数据库中的 join)
join [OPTION]... FILE1 FILE2
join testfile_2 testfile_1
comm
:比较两个(已排序的)文本文件,并且会显示每个文件特有的文本行和共有的文本行
-1/2/3
:不显示第一/二/三列,也可以多个结合使用:如 -12
表示仅显示第三列comm file1 file2
;comm -13 file1 file2
diff
:逐行来比较文件之间的差异;如果指定要比较目录,则 diff 会比较目录中相同文件名的文件,但不会比较其中子目录
- -c
:上下文格式;-C NUM
:指明多少行(默认为3行)
- -u
:统一格式;-U NUM
:指明多少行(默认为3行)
- -y
:并列格式;-W
:在使用-y参数时,指定栏宽
- -r
:比较子目录的文件
- -q
:仅返回两文件是否相同的结果
- -a
:把所有文件视为文本
- -b
:不检查空格字符
- -B
:不检查空白行
- -i
:忽略大小写
- -w
:忽略全部的空格
- -t
:输出时以tab字符展开;-T
:在每行前面加上前导的tab字符
- 差异说明
- 正常模式:change,"5c5" 指两个文件的第5行不同;append,"12a13,14"指第一个文件比第二个文件少了13行和14行;delete,"13,14d12"的含义是第一个文件比第二个文件多了13行和14行
- 上下文格式:+,表示增加一行;-,表示减少一行;!,表示不相同的两行
- 并列格式:<,表示第一个文件多一行;>,表示第二个文件多一行;|,表示不相同的两行
patch
:把更改应用到文本文件中(使用补丁文件完成打补丁操作),一般是搭配 diff
命令完成版本更新操作
diff -Naur old_file new_file > diff_file
,再打补丁对 old_file 进行更新(把 old_file 变成 new_file) patch < diff_file
;撤销补丁:patch -R < diff_file
,添加 -R
选项tr
:基于字符的查找和替换操作
echo "lowercase letters" | tr a-z A-Z
把小写字母转换成大写字母;echo "lowercase letters" | tr [:lower:] A
把多个字符转换为单个字符Atr -d '\r' < dos_file > unix_file
除了换字之外, tr 命令能允许字符从输入流中简单地被删除,这里是删除每行末尾的回车符 echo "aaabbbccc" | tr -s ab
使用 -s
选项, tr 命令能“挤压”(删除)重复的字符(注意:重复的字符必须是相邻的,不相邻则没有效果)sed
(stream editor):流式编辑器,对文本流进行编辑,文本可来自文件、标准输入
-n
:不自动打印(不要默认地打印每一行)-f
:使用脚本文件来执行命令-i
:原地修改文本(不输出到标准输出)s/regexp/replacement/
:仅第一次替换。只要找到一个 regexp 匹配项,就替换为 replacement 的内容。在末尾添加 /g
进行全局替换,如:echo "aaabbbccc" | sed 's/b/B/g'
。 replacement 可能包括特殊字符 &,其等价于由 regexp匹配的文本。另外, replacement 可能包含序列 \1 到 \9,其是 regexp 中相对应的子表达式的内容y/set1/set2
:执行字符转写操作,通过把 set1 中的字符转变为相对应的 set2 中的字符。注意不同于 tr 程序, sed 要求两个字符集合具有相同的长度=
:输出当前的行号a
:在当前行的下一行追加文本。用法:sed 'a/特定字符串/新行字符串
or sed '/特定字符串/a 新行字符串'
d
:删除当前行i
:在当前行的上一行插入文本。用法:sed 'i/特定字符串/新行字符串
or sed '/特定字符串/i 新行字符串'
c
:取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行(n1,n2 指某些行,可能未指定)p
:打印当前行。默认情况下, sed 程序打印每一行,并且只是编辑文件中匹配指定地址的文本行。通过指定 -n 选项,这个默认的行为能够被忽略q
:退出 sed,不再处理更多的文本行。如果不指定 -n 选项,输出当前行Q
:退出 sed,不再处理更多的文本行\
、\_
等),其后跟着查找和替代字符串。举例: echo "front" | sed 's/front/back/'
与 echo "front" | sed 's\_front\_back\_'
等价sed -i 's/lazy/laxy/; s/jumped/jimped/' foo.txt
aspell
:一款交互式的拼写检查器(能够智能地检查各种类型的文本文件,包括 HTML 文件, C/C++ 程序,电子邮件和其它种类的专业文本),也可以作为一个独立的命令行工具使用
aspell check textfile
拼写检查一个包含简单的文本文件split
:将大文件分割成较小的文件,在默认情况下将按照每1000行切割成一个小文件
-l NUM
or -NUM
:指定每个小文件NUM行。举例:split -l 100 date.file
-n NUM
:指定分成NUM个小文件。举例:split -n 33 date.file
把文件分成33个小文件-b
:指定每个小文件多少个字节。举例:split -b 10k date.file
-d
:指定数字后缀,默认从0开始。举例:split -b 10k date.file -d 110
以110为后缀名的开始-a
:指定后缀的长度。举例:split -b 10k date.file -d -a 4
以0为后缀名的开始,且长度为4split file SUFFIXES
:指定前缀SUFFIXES。举例:split -b 10k date.file -d -a 4 SSS
指定前缀为SSS,后缀长度为4的数字后缀awk
nl
:对输出文本进行一些自定义,比如:添加文本行号,类似于 cat -n
;接收多个文件输入或标准输入
fold
:限制文件行宽;接收多个文件或标准输入
-w NUM
:限制每行的字符列数为NUM列-s
:基于空格断开-b
:基于字节数来分隔echo "The quick brown fox jumped over the lazy dog." | fold -w 12 -s
fmt
:文本格式化,重新格式化文件中的每一个段落,将结果写到标准输出
pr
:让文本为打印做好准备
find /usr/bin/ -executable -type f | pr -T -4 | column -t
多列显示printf
:模仿了C语言中的printf()函数。主要作用是输出文本,按照我们指定的格式输出文本
make
、make install
./configure
Shell 脚本注意点
#!
:shebang 被用来告诉操作系统将执行此脚本所用的解释器的名字,每个 shell 脚本都应该把这一文本行作为它的第一行chmod 755/700 file
权限为 755 的脚本,则每个人都能执行,和权限为 700 的脚本,只有文件所有者能够执行echo $PATH
查看PATH中是否有 /home/USERNAME/bin 则可以在当前用户USERNAME下新建 bin 目录并将脚本文件 file 移动至 bin 中,即 mkdir bin; mv file bin
,再直接使用脚本文件名即可 file
export PATH=~/bin:"$PATH"
,保存退出后使用 source 命令强制刷新 source .bashrc
Shell 编程习惯
\
∼/.vimrc
变量与常量
variable=value
;使用变量:$var
a=z # Assign the string "z" to variable a.
b="a string" # Embedded spaces must be within quotes.
c="a string and $b" # Other expansions such as variables can be expanded into the assignment
d=$(ls -l foo.txt) # Results of a command
e=$((5 * 7)) # Arithmetic expansion
f="\t\ta string\n" # Escape sequences such as tabs and newlines
a=5 b="a string"
可在同一行中对多个变量赋值{}
屏蔽上下文的用法:已有 filename="myfile"; touch $filename
,那么直接对文件改名会报错 mv $filename $filename1
,而应该使用花括号 {} 来实现 mv $filename ${filename}1
declare -r TITLE=“Page Title”
强制常量的不变性, shell 会阻止之后给 TITLE 的任意赋值(比如:将一个变量强制赋值为整型)$HOSTNAME
这台机器的网络名称Here Documents:一种 I/O 重定向形式,在脚本文件中嵌入正文文本,然后把它发送给一个命令的标准输入
Shell 函数:是更为完美的别名 alias 替代物,实际上是创建较小的个人所用命令的首选方法(别名 alias 非常局限于命令的种类和它们支持的 shell 功能,然而 shell 函数允许任何可以编写脚本的东西)
if 分支结构
退出状态 $?
:命令(包括我们编写的脚本和 shell 函数)执行完毕后,会给系统发送的一个值,叫做退出状态
$?
用来检查退出状态,比如:当一条命令执行完成之后,再使用 echo $?
来检测退出状态true
返回0,总是执行成功;false
返回非0,总是执行失败exit
:接受一个单独的、可选的参数,其成为脚本的退出状态(在一个行动执行完之后,可使用 exit 来阻止脚本执行不必要的代码,但在程序中出现多个 exit 可能会使得程序逻辑较难理解)。举例:exit 1
失败退出return
:类似于 exit
命令,但在 shell 函数中使用。举例:return 1
失败退出测试
两种等价语法:test expression
or [ expression ]
,这里的 expression 是一个表达式,其执行结果是 true 或者是 false
测试:字符串表达式
注意:当与 test
一起使用的时候, > 和 < 表达式操作符必须用引号引起来(或者是用反斜杠转义),防止被 shell 解释为重定向操作符,造成潜在地破坏结果
[[ expression ]]
复合命令(加强的 test 命令):除了 test 命令的所有表达式,
=~
字符串表达式操作符。举例: string1 =~ regex
如果 string1 匹配扩展的正则表达式 regex,那么其返回值为真==
操作符来匹配类型,如同路径名展开。举例:if [[ $FILE == foo.* ]]; then .. fi
则会匹配出 foo.bar 等(( expression ))
复合命令,专门用于对整数进行操作,支持一套完整的算术计算
逻辑操作符:结合表达式
-a
、&&
与运算(先执行 command1,如果并且只有如果 command1执行成功后,才会执行 command2);-o
、||
或运算(先执行 command1,如果并且只有如果 command1 执行失败后,才会执行 command2);!
、!
非运算 mkdir temp && cd temp
这会创建一个名为 temp 的目录,并且若它执行成功后,当前目录会更改为 temp[ -d temp ] || mkdir temp
测试目录 temp 是否存在,并且只有测试失败之后,才会创建这个目录(这种构造类型非常有助于在脚本中处理错误)[ -d temp ] || exit 1
如果这个脚本要求目录 temp,且目录不存在,然后脚本会终止,并返回退出状态 1举例:if [ -x "$FILE" ]; then ... fi
参数 $FILE 的引号不是必须的,但是为了防范空参数会加上引号(如果 $FILE 的参数展开是一个空值,就会导致一个错误(操作符将会被解释为非空的字符串而不是操作符))
read
:从标准输入读取单行数据,可以用来读取键盘输入,当使用重定向的时候,读取文件中的一行数据
read [-options] [variable...]
:options 可选一个或多个,且 variable 是用来存储输入数值的一个或多个变量名
read var1 var2 var3 var4 var5
使用5个变量来接收输入REPLY
,将会包含所有的输入-a array
:把输入赋值到数组 array 中,从索引号零开始-d delimiter
:用字符串 delimiter 中的第一个字符指示输入结束,而不是一个换行符-e
:使用 Readline 来处理输入。这使得与命令行相同的方式编辑输入-n num
:读取 num 个输入字符,而不是整行-p prompt
:为输入显示提示信息,使用字符串 prompt-r
:Raw mode. 不把反斜杠字符解释为转义字符-s
:Silent mode. 不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这会很有帮助-t seconds
:超时. 几秒钟后终止输入。 read 会返回一个非零退出状态,若输入超时-u fd
:使用文件描述符 fd 中的输入,而不是标准输入read
命令!(因为 read 在 shell 的子 shell 环境中,把某些值赋值给变量 REPLY,但是当命令退出后,子 shell 和它的环境将被破坏掉,这样赋值的影响就会消失)if read -t 10 -sp "Enter secret pass phrase > " secret_pass; then ... fi
IFS (Internal Field Separator):内部字符分隔符,一个shell 内部变量(默认值包含一个空格,一个 tab 和一个换行符,每一个都会把字段分割开)
IFS=":" read user pw uid gid name home shell <<< "$file_info"
这一行由三部分组成:一个IFS变量赋值(临时生效),一个带有一串参数的 read 命令,一个 here 字符串(<<<
)。针对IFS赋值也可以这样分开写:先写一行 IFS=":"
,再写一行 read user pw uid gid name home shell <<< "$file_info"
,最后再写一行重新还原IFS变量的值 IFS="$OLD_IFS"
(但第一种方法更简洁…)while 循环:当…进行循环
until 循环:直到…停止循环
case 多选复合命令
for 循环
for variable [in words]; do commands; done
:传统的 shell 格式 for 循环,variable 是一个变量的名字,这个变量在循环执行期间会增加, words 是一个可选的条目列表,其值会按顺序赋值给 variable, commands 是在每次循环迭代中要执行的命令
for i in A B C D;
;for i in {A..D};
花括号展开;for i in distros*.txt;
路径名展开;for i in $(strings $1);
这里是命令行替换,用到了 strings
命令(为每一个文件产生一个可读的文本格式的“words”列表)for i;
for (( expression1; expression2; expression3 )); do commands; done
:C 语言格式 for 循环,这里的 expression1(用于初始化循环条件),expression2(用于决定循环结束的时间)和 expression3(在每次循环迭代的末尾会执行)都是算术表达式,commands 是每次循环迭代时要执行的命令
for (( i = 0; i < 5; i += 1 )); do echo $i; done
>&2
)#!/bin/bash -x
。追踪开始后,行首的加号(+)表明追踪的迹象,使其与常规输出结果区分开来;加号是追踪输出的默认字符,它包含在 PS4(提示符 4) shell 变量中,可修改,如:先执行命令 export PS4='$LINENO + '
(追踪执行到的当前行的行号),再执行脚本文件set -x
:在脚本文件中,先写一行 set -x # Turn on tracing
,中间是需追踪的代码块,最后再写一行 set +x # Turn off tracing
位置参数变量集合
$0
到 $9
$0
总会包含命令行中出现的第一个单词,也就是已执行程序的路径名(也即使这个命令行不带参数)${10}
, ${55}
, ${211}
,等等$#
:确定参数数量;对参数使用 shift
后参数数量会变化shift
:使所有的位置参数“向下移动一个位置”,访问多个参数
$0
)basename
去除文件路径的前缀部分,返回最后一个文件的基本名称。举例:basename /usr/bin/sort
会返回 sort
;basename include/stdio.h .h
会返回 stdio
shell 函数中使用位置参数
集体位置参数
参数展开(编写脚本文件时可使用,以提高脚本文件等的运行效率,通过 time
命令验证)
$a
展开后,会变成变量 a 所包含的值;简单参数也可能用花括号引起来:${a}
。举例:对于字符串变量 a="foo"
,可使用花括号来展开 echo "${a}_file"
,而不是 echo "$a_file"
(shell 会试图展开变量 a_file,而不是变量 a)${11}
${parameter:-word}
:若 parameter 没有设置(例如,不存在)或者为空,展开结果是 word 的值。若 parameter 不为空,则展开结果是 parameter 的值${parameter:=word}
:若 parameter 没有设置或为空,展开结果是 word 的值。另外, word 的值会赋值给 parameter(上一种不会)。若 parameter 不为空,展开结果是 parameter 的值(注意:位置参数或其它的特殊参数不能以这种方式赋值)${parameter:?word}
:若 parameter 没有设置或为空,这种展开导致脚本带有错误退出,并且 word 的内容会发送到标准错误(若使用 $?
来查看退出状态,展开正确则有状态 1,发生错误则有状态 0)。若 parameter 不为空,展开结果是 parameter 的值${parameter:+word}
:若 parameter 没有设置或为空,展开结果为空。若 parameter 不为空,展开结果是 word 的值会替换掉 parameter 的值;然而, parameter 的值不会改变(若 parameter 为空则输出空,若 parameter 有值则输出 word 的值,但不会改变 parameter 的值)。举例: echo ${foo:+"substitute value if set"}
返回变量名的参数展开
${!prefix*}
or ${!prefix@}
:返回以 prefix 开头的已有变量名。举例:echo ${!BASH*}
列出了所有以 BASH 开头的环境变量名${#parameter}
:展开成由 parameter 所包含的字符串的长度(类似于 python 的 len);如果 parameter 是 @ 或者是 * 的话,则展开结果是位置参数的个数。举例:若 foo="This string is long."
,则 echo ${#foo}
结果为 20, echo ${foo:5}
结果为 string is long.
,echo ${foo:5:6}
结果为 string
;echo ${foo: -5}
结果为 long.
;echo ${foo: -5:2}
结果为 lo
${parameter:offset}
or ${parameter:offset:length}
:提取的字符始于第 offset 个字符(从字符串开头算起)直到字符串的末尾,可指定提取的长度 length;若 offset 的值为负数,则认为 offset 值是从字符串的末尾开始算起,而不是从开头,而且负数前面必须有一个空格,为防止与 ${parameter:-word}
展开形式混淆;length 若出现,则必须不能小于零。若 parameter 是 @,展开结果是 length 个位置参数,从第 offset 个位置参数开始${parameter#pattern}
or ${parameter##pattern}
:这种展开会从 paramter 所包含的字符串中清除开头一部分与 patten 通配符模式相匹配的文本;一个 # 清除最短的匹配结果,两个 # 清除最长的匹配结果。举例:若有foo=file.txt.zip
,则echo ${foo#*.}
结果为 txt.zip
,而echo ${foo##*.}
结果为 zip
${parameter%pattern}
or ${parameter%%pattern}
:和上面的 # 和 ## 展开一样,但清除的将从末尾开始,而不是开头${parameter/pattern/string}
,只有第一个匹配项会被替换掉;${parameter//pattern/string}
,所有的匹配项都会被替换掉;${parameter/#pattern/string}
,仅当匹配项出现在字符串的开头才替换(仅当开头才替换);${parameter/%pattern/string}
,仅当匹配项出现在字符串的末尾才替换(仅当末尾替换)。举例:若 foo=JPG.JPG
,则 echo ${foo/JPG/jpg}
结果为 jpg.JPG
,echo ${foo//JPG/jpg}
结果为 jpg.jpg
,echo ${foo/#JPG/jpg}
结果为 jpg.JPG
,echo ${foo/%JPG/jpg}
结果为 JPG.jpg
declare
:用于声明 shell 变量,如:-u
大写变量,-l
小写变量,-a
数组变量,-i
整型变量。${parameter„}
,把 parameter 的值全部展开成小写字母;${parameter,}
,仅把 parameter 的第一个字符展开成小写字母,${parameterˆˆ}
,把 parameter 的值全部转换成大写字母;${parameterˆ}
,仅把 parameter 的第一个字符转换成大写字母(首字母大写)算术求值与展开
$((expression))
这里的 expression 是一个有效的算术表达式,与复合命令 (( )) 有关0number
在算术表达式中,以零开头的数字被认为是八进制数;0xnumber
十六进制;base#number
此 number 以 base 为底。举例:echo $((0xff))
与 echo $((2#11111111))
均输出 255+
、-
、*
、/
整数除法、**
乘方、%
取模=
:给变量一个值就执行了一次赋值运算;也能在算术表达式中执行赋值运算。举例:if (( foo = 5 ));then echo "It is true."; fi
,此 if 代码块执行完后,会输出 It is true.(这里的条件表达式 foo = 5
已经给 foo 赋值为 5,且测试条件计算为真,因为 foo 的值非零)
==
:计算等价性(注意:test 命令接受单个 = 运算符来测试字符串等价性,因此这也是使用更现代的 [[ ]] 和 (( )) 复合命令来代替 test 命令的另一个原因)+=
…:parameter += value
等价于 parameter = parameter + value
parameter++
、parameter--
:参数返回后自加、减一++parameter
、--parameter
:参数返回前自加、减一(对于大多数 shell 应用来说,可能更常用,相当于上一条)<<=
)
~
:按位取反。对一个数字所有位取反(没有赋值运算符!)<<
:位左移. 把一个数字的所有位向左移动>>
:位右移. 把一个数字的所有位向右移动&
:位与。对两个数字的所有位执行一个 AND 操作|
:位或。对两个数字的所有位执行一个 OR 操作^
:位异或。对两个数字的所有位执行一个异或操作<=
:小于或相等>=
:大于或相等<
:小于>
:大于==
:相等!=
:不相等&&
:逻辑与||
:逻辑或expr1?expr2:expr3
:条件(三元)运算符。操作三个算术表达式(字符串不会起作用),并且若第一个表达式为真(或非零),则执行第二个表达式,否则,执行第三个表达式a=0; ((a<1?a+=1:a-=1))
这样赋值会报错,需要用括号把赋值表达式括起来 ((a<1?(a+=1):(a-=1)))
bc
:一种高精度计算器语言
创建数组
a[1]=foo
,使用 echo ${a[1]}
(使用花括号是必需的,以便防止 shell 试图对数组元素名执行路径名展开操作)declare -a arr
数组赋值
name[subscript]=value
:这里的 name 是数组的名字, subscript 是一个大于或等于零的整数(或算术表达式);注意数组第一个元素的下标是 0,而不是 1;数组元素的值可以是一个字符串或整数name=(value1 value2 ...)
:这里的 name 是数组的名字, value. . . 是要按照顺序赋给数组的值,从元素 0 开始,如:days=(Sun Mon Tue Wed Thu Fri Sat)
;也可指定下标来赋值,如:days=([0]=Sun [1]=Mon [2]=Tue [3]=Wed [4]=Thu [5]=Fri [6]=Sat)
访问数组元素
@
表示法),与计算字符串长度的方式几乎相同。举例:对于arr[100]=foo
,echo ${#arr[@]}
会得到数组含有的元素个数 1(而未赋值的元素 0-99 不会计入),而 echo ${#arr[100]}
会输出数组元素 100 的长度 3${!array[*]}
or ${!array[@]}
:和其它使用符号 * 和 @ 的展开一样,用引号引起来的 @ 格式是最有用的,因为它能展开成分离的词。举例:for i in "${!arr[@]}"; do echo $i; done
arr=(a b c)
,末尾添加元素 arr+=(d e f)
sort
命令来间接实现:a_sorted=($(for i in "${a[@]}"; do echo $i; done | sort))
unset
:删除一个数组 unset arr
;删除一个数组元素 unset 'arr[3]'
(注意:数组下标从 0 开始,且添加引号来防止路径名展开)foo=(a b c d e f)
再执行 foo=
,而 echo ${foo[@]}
的结果是 b c d e f(去掉第一个元素 a)关联数组:使用字符串而不是整数作为数组索引
declare -A colors
:使用带有 -A 选项的 declare 命令创建。举例:declare -A colors
,colors["red"]="#ff0000"
,colors["blue"]="#0000ff"
echo ${colors["blue"]}
命令组合(用于管理重定向,在重定向中合并流)
{ command1; command2; [command3; ...] }
,鉴于 bash 实现组命令的方式,花括号与命令之间必须有一个空格,并且最后一个命令必须用一个分号或者一个换行符终止。举例:{ ls -l; echo "Listing of foo.txt"; cat foo.txt; } > output.txt
(command1; command2; [command3;...])
。举例:(ls -l; echo "Listing of foo.txt"; cat foo.txt) > output.txt
{ ls -l; echo "Listing of foo.txt"; cat foo.txt; } | lpr
echo <(echo "foo")
,输出结果为 /dev/fd/63
(表明子 shell 的输出结果,由一个名为 /dev/fd/63
的文件提供)<(list)
,另一种适用于接受标准输入的进程 >(list)
,这里的 list 是一串命令列表read
命令在一个子 shell 中执行,当该子 shell 终止的时候,它的 REPLY 副本被毁掉的问题(因为管道线中的命令总是在子 shell 中执行,任何给变量赋值的命令都会遭遇这样的问题)陷阱,trap
(用于程序响应与处理信号)
trap argument signal [signal...]
:argument 是一个字符串(普通字符串、shell 函数名等),它被读取并被当作一个命令;signal 是一个信号的说明,它会触发执行所要解释的命令trap "echo 'I am ignoring you.'" SIGINT SIGTERM
,当脚本运行的时候,这个陷阱每当接受到一个 SIGINT 或 SIGTERM 信号时(比如:当用户试图通过按下 Ctrl-c 组合键终止脚本运行的时候),就会执行一个 echo 命令来输出字符串 “I am ignoring you.”异步执行
wait [-n] [id ...]
:等待作业完成并返回退出状态;使一个父脚本暂停运行,直到一个特定的进程(例如,子脚本)运行结束命名管道(用来在两个进程之间建立连接,也可以像其它类型的文件一样使用)
mkfifo named_pipe
:使用 mkfifo
命令(通过 ls
命令查看 named_pipe 文件,可发现其属性字段的第一个字母是“p”,表明它是一个命名管道)process1 > named_pipe
(按下 Enter 按键之后,命令将会挂起,这是因为在管道的另一端没有任何接受数据,也就是管道阻塞;一旦我们绑定一个进程到管道的另一端,该进程开始从管道中读取输入的时候,这种情况会消失,此时需要使用第二个终端窗口),然后在另一个终端窗口让数据流出 process2 < named_pipe
(表现出来就像 process1 | process2
),通过这样两个步骤则完成了命名管道的使用。举例:先 ls -l pipe1
,再 cat < pipe1