linux 100集
P19-22 文件和目录(ls常用选项)
Linux中“./”在系统文件中表示绝对路径的意思。
linux系统中,所有的文件与目录都是由根目录/开始,不是以/开头的就是相对路径;
1、“.”表示当前目录,也可以用“./”表示;
2、“..”表示上一级目录,也可以用“../”表示;
3、“~” 代表用户自己的宿主目录;
4、“/”处于Linux文件系统树形结构的最顶端,我们称它为Linux文件系统的root,它是Linux文件系统的入口。
所有的目录、文件、设备都在/之下,它是Linux文件系统最顶层的唯一的目录;
自动不全:tab键
查看曾经用过命令:上下光标键,退出选择用ctrl+c
ls命令扩展:
最常用,.开头的文件为隐藏文件,需要-a才可以打开, ls -a才可以显示出来
.表示当前目录
..表示上级目录, cd ..返回上一个目录
ls -l以列表方式显示文件详细信息
ls -h配合-l以人性化方式显示文件大小(文件大小用k,m表示,而不是byte,人易读):ls -l -h或者 ls -lh
所以可以ls -alh
drw… 这里d是目录
P23 文件和目录(ls常用通配符)
*:任意个数字符(0或多个)
?:任意一个字符,至少一个(只一个,不可为0)
[]:可匹配字符组任意一个
ls功能: 列出非目录的文件项,然后是每一个目录中的“可显示”文件(可理解为ls命令将本目录向下展开两级)
ls用法:ls [参数] [目录名]
(如过要显示当前目录的文件可不加目录名)
ls常用参数
-a 显示所有文件,包含隐藏文件
-A 显示所有文件,包含隐藏文件,但不包含.及..
-l 显示为long format(长格式),列出文件的类型、权限、链接数、owner、group、大 小,时间,名字
-R
-d 不展开目录,只显示目录自身,一般与-l配合使用以显示目录自身的属性信息(只显示当前目录的内容)
-1 数字1,成列显示内容
-S 以文件大小排序显示,默认从大到小 -r后,从小到大
-U 按存放顺序排序显示
-X 按扩展名的首字母来排序
-t 按mtime排序(先显示时间最近的)
-ul 按atime排序(先显示时间最近的)
-ct 按ctime排序(先显示时间最近的)
补充:
关于时间戳:
atime 访问时间
mtime 数据修改时间 (写入,修改数据mtime改变,mtime改变ctime必改变)
ctime 元数据修改时间 (修改权限的时候只有ctime改变)
可过“stat 文件路径”查看全部时间戳
扩展**: 如何通过ls只显示指定格式的文件**
首先我们要了解什么是文件名通配符
Shell提供了一套完整的字符串模式匹配规则,或者称之为元字符,当s h e l l遇到上述字符时,就会把它们当作特殊字符,而不是文件名中的普通字符,这样用户就可以用它们来匹配相应的文件名,我理解这可以称为通配符。
常用通配符:
* 匹配0或多个任意字符
? 匹配任意1个字符
[ ] 当中括号内为几个确定字符时,表示匹配括号内任意一个字符,当中括号内为一个范围时表示匹配这个范围中的任意一个字符(中括号表示的是一个范围,匹配的是一个字符)
例:
[ab46e] 表示是a,b,4,6,e中的任意一个字符
[a-z] 表示aAbBcC……z(Linux中的默认编码顺序是一个小写字母一个大写字母即aAbBcC…..Z)
[A-Z] 表示AbBcC……Z
[a- Z] 表示所有大小写字母
[^ae] 表示即不是a也不是e的其他任意单一字符
[:lower:] 表示一个小写字母
[:upper:] 表示一个大写字母
[:alpha:] 表示一个大小写字母 等同于[a-Z]
[:digit:] 表示任意一个数字 等同于[0-9]
[:alnum:] 表示任意一个字母或数字 等于[a-Z0-9]或[[:digit:][:alpha:]]
[:blank:]:一个水平空白字符
[:space:]:一个水平或垂直空白字符(文件名不可能包含回车,故此处使用与[:blank:]:效果相同)
通过ls命令和通配符查找指定格式的文件:
格式:ls [参数] [目录名][通配符]
以下是一些例子:
\1. 查找/usr/share/man 目录下以m开头且以一个数字加x结尾的文件
命令:ls -d /usr/share/man/m*[0-9]x
运行结果:
解释:-d 只展开一级目录
/usr/share/man/ 目录路径
m*[0-9]x m表示以m开头,[0-9]x表示以数字加x结尾,因为对文件的中间没
有加以限制所以用代替中间部分,表示任意个数的任意字符
\2. 查找root下的隐藏文件和目录
命令: ls -d /root/.*
运行结果:
解释:-d 只展开一级目录
/root 目录路径
因为Linux下以“.”开头的文件是隐藏文件,所以用“.”加上“*”来表示隐藏文件
\3. 查找/etc下所有以k开头,以一个小写字母结尾,且中间出现至少一位数字的文件
命令:ls -d /etc/k[0-9][[:lower:]]
运行结果:
解释:-d 只展开一级目录
/etc 目录路径
k表示以k开头,[0-9]表示一个数字,[[:lower:]]表示一个小写字母,因为[:lower:]表示为小写字母,也就是abcdefg…z,所以在[:lower:]外面加
上[ ]以表示在这写子母中取任意一个,因为只规定了开头和结尾,对中间只要求至少出现一位数字,所以中间用*[0-9]*来表示
P25 文件和目录(cd常用选项)
cd
跳入test目录:
1 | [root@/root/linuxdaxue.com]#cd testDir/ |
跳至上层目录
1 | [root@/root/linuxdaxue.com/testDir]#cd .. |
跳至上上层目录
1 | [root@/root/linuxdaxue.com/testDir]#cd ../../ |
跳入用户主目录: cd ~或者cd
1 | [root@/root/linuxdaxue.com/testDir]#ls |
使用绝对路径
1 | [root@/root]#cd /root/linuxdaxue.com/testDir |
使用环境变量
1 | [root@/root]#cd $TEST_PATH |
跳入上次使用目录: cd -, 可以在最近两次工作目录间切换
1 | [root@/root]#pwd |
P26 文件和目录(相对路径绝对路径)
- 绝对路径:路径的写法一定是由根目录 / 写起的,例如 /usr/local/mysql
- 相对路径:路径的写法不是由根目录 / 写起的,例如 首先用户进入到 /home,然后再进入到test,执行的命令为 “#cd /home,#cd test”。此时用户所在的路径为 /home/test。第一个cd命令后紧跟/home,前面有斜杠;而第二个cd命令后紧跟test,前面没有斜杠。这个test是相对于/home目录来讲的,所以称为相对路径。
P27 文件和目录(mkdir和touch)
Linux touch命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。
ls -l 可以显示档案的时间记录。
语法
1 | touch [-acfm][-d<日期时间>][-r<参考文件或目录>] [-t<日期时间>][--help][--version][文件或目录…] |
- 参数说明:
- a 改变档案的读取时间记录。
- m 改变档案的修改时间记录。
- c 假如目的档案不存在,不会建立新的档案。与 –no-create 的效果一样。
- f 不使用,是为了与其他 unix 系统的相容性而保留。
- r 使用参考档的时间记录,与 –file 的效果一样。
- d 设定时间与日期,可以使用各种不同的格式。
- t 设定档案的时间记录,格式与 date 指令相同。
- –no-create 不会建立新档案。
- –help 列出指令格式。
- –version 列出版本讯息。
实例
使用指令”touch”修改文件”testfile”的时间属性为当前系统时间,输入如下命令:
1 | $ touch testfile #修改文件的时间属性 |
首先,使用ls命令查看testfile文件的属性,如下所示:
1 | $ ls -l testfile #查看文件的时间属性 |
执行指令”touch”修改文件属性以后,并再次查看该文件的时间属性,如下所示:
1 | $ touch testfile #修改文件时间属性为当前系统时间 |
使用指令”touch”时,如果指定的文件不存在,则将创建一个新的空白文件。例如,在当前目录下,使用该指令创建一个空白文件”file”,输入如下命令:
1 | $ touch file #创建一个名为“file”的新的空白文件 |
Linux mkdir命令用于建立名称为 dirName 之子目录。
语法
1 | mkdir [-p] dirName |
参数说明:
- -p 确保目录名称存在,不存在的就建一个。
实例
在工作目录下,建立一个名为 AAA 的子目录 :
1 | mkdir AAA |
在工作目录下的 BBB 目录中,建立一个名为 Test 的子目录。 若 BBB 目录原本不存在,则建立一个。(注:本例若不加 -p,且原本 BBB目录不存在,则产生错误。)
1 | mkdir -p BBB/Test |
linux中文件目录不可以重名
P28 文件和目录(rm)
rm删除的不能恢复。Linux rm命令用于删除一个文件或者目录。
rm也可以使用通配符。
格式化电脑:rm -rf *
所有数据全部删除。
语法
1 | rm [options] name... |
参数:
- -i 删除前逐一询问确认。
- -f 即使原档案属性设为唯读,亦直接删除,无需逐一确认。(没有此文件也可以删除,不会报错)
- -r 将目录及以下之档案亦逐一删除。(不加无法删目录)(用递归方法)
实例
删除文件可以直接使用rm命令,若删除目录则必须配合选项”-r”,例如:
1 | # rm test.txt |
删除当前目录下的所有文件及目录,命令行为:
1 | rm -r * |
文件一旦通过rm命令删除,则无法恢复,所以必须格外小心地使用该命令。
P29-35拷贝和移动文件
tree
Linux tree命令用于以树状图列出目录的内容。
需要此指令安装:sudo snap install tree
tree ,家目录(),全部显示出来。
执行tree指令,它会列出指定目录下的所有文件,包括子目录里的文件。
语法
1 | tree [-aACdDfFgilnNpqstux][-I <范本样式>][-P <范本样式>][目录...] |
参数说明:
- -a 显示所有文件和目录。
- -A 使用ASNI绘图字符显示树状图而非以ASCII字符组合。
- -C 在文件和目录清单加上色彩,便于区分各种类型。
- -d 显示目录名称而非内容。(常用)
- -D 列出文件或目录的更改时间。
- -f 在每个文件或目录之前,显示完整的相对路径名称。
- -F 在执行文件,目录,Socket,符号连接,管道名称名称,各自加上”*”,”/“,”=”,”@”,”|”号。
- -g 列出文件或目录的所属群组名称,没有对应的名称时,则显示群组识别码。
- -i 不以阶梯状列出文件或目录名称。
- -L level 限制目录显示层级。
- -l 如遇到性质为符号连接的目录,直接列出该连接所指向的原始目录。
- -n 不在文件和目录清单加上色彩。
- -N 直接列出文件和目录名称,包括控制字符。
- -p 列出权限标示。
- -P<范本样式> 只显示符合范本样式的文件或目录名称。
- -q 用”?”号取代控制字符,列出文件和目录名称。
- -s 列出文件或目录大小。
- -t 用文件和目录的更改时间排序。
- -u 列出文件或目录的拥有者名称,没有对应的名称时,则显示用户识别码。
- -x 将范围局限在现行的文件系统中,若指定目录下的某些子目录,其存放于另一个文件系统上,则将该子目录予以排除在寻找范围外。
cp
语法
1 | cp [options] source dest |
或
1 | cp [options] source... directory |
参数说明:
- -a:此选项通常在复制目录时使用,它保留链接、文件属性,并复制目录下的所有内容。其作用等于dpR参数组合。
- -d:复制时保留链接。这里所说的链接相当于Windows系统中的快捷方式。
- -f:覆盖已经存在的目标文件而不给出提示。
- -i:与-f选项相反,在覆盖目标文件之前给出提示,要求用户确认是否覆盖,回答”y”时目标文件将被覆盖。(常用)
- -p:除复制文件的内容外,还把修改时间和访问权限也复制到新文件中。
- -r:若给出的源文件是一个目录文件,此时将复制该目录下所有的子目录和文件。(常用)
- -l:不复制文件,只是生成链接文件。
实例
使用指令”cp”将当前目录”test/“下的所有文件复制到新目录”newtest”下,输入如下命令:
1 | $ cp –r test/ newtest |
注意:用户使用该指令复制目录时,必须使用参数”-r”或者”-R”。
例 cp ~/Desktop/a.txt . 当前文件夹下
Linux mv 命令用来为文件或目录改名、或将文件或目录移入其它位置。
mv
语法
1 | mv [options] source dest |
参数说明:
- -i: 若指定目录已有同名文件,则先询问是否覆盖旧文件;(常用)
- -f: 在 mv 操作要覆盖某已有的目标文件时不给任何指示;
mv参数设置与运行结果
命令格式 | 运行结果 |
---|---|
mv 文件名 文件名 | 将源文件名改为目标文件名 |
mv 文件名 目录名 | 将文件移动到目标目录 |
mv 目录名 目录名 | 目标目录已存在,将源目录移动到目标目录;目标目录不存在则改名 |
mv 目录名 文件名 | 出错 |
实例
将文件 aaa 更名为 bbb :
1 | mv aaa bbb |
将info目录放入logs目录中。注意,如果logs目录不存在,则该命令将info改名为logs。
1 | mv info/ logs |
再如将/usr/student下的所有文件和目录移到当前目录下,命令行为:
1 | $ mv /usr/student/* . |
P36-39查看文件内容命令
cat, more, grep
cat:
concatenate: 查看文件,创建文件,文件合并,追加文件内容等功能
cat 命令用于连接文件并打印到标准输出设备上。(适合内容少的文本内容)
使用权限
所有使用者
语法格式
1 | cat [-AbeEnstTuv] [--help] [--version] fileName |
参数说明:
-n 或 –number:由 1 开始对所有输出的行数编号。(常用)
-b 或 –number-nonblank:和 -n 相似,只不过对于空白行不编号。(常用)
-s 或 –squeeze-blank:当遇到有连续两行以上的空白行,就代换为一行的空白行。
-v 或 –show-nonprinting:使用 ^ 和 M- 符号,除了 LFD 和 TAB 之外。
-E 或 –show-ends : 在每行结束处显示 $。
-T 或 –show-tabs: 将 TAB 字符显示为 ^I。
-A, –show-all:等价于 -vET。
-e:等价于”-vE”选项;
-t:等价于”-vT”选项;
实例:
把 textfile1 的文档内容加上行号后输入 textfile2 这个文档里:
1 | cat -n textfile1 > textfile2 |
把 textfile1 和 textfile2 的文档内容加上行号(空白行不加)之后将内容附加到 textfile3 文档里:
1 | cat -b textfile1 textfile2 >> textfile3 |
清空 /etc/test.txt 文档内容:
1 | cat /dev/null > /etc/test.txt |
cat 也可以用来制作镜像文件。例如要制作软盘的镜像文件,将软盘放好后输入:
1 | cat /dev/fd0 > OUTFILE |
相反的,如果想把 image file 写到软盘,输入:
1 | cat IMG_FILE > /dev/fd0 |
注:
\1. OUTFILE 指输出的镜像文件名。
\2. IMG_FILE 指镜像文件。
\3. 若从镜像文件写回 device 时,device 容量需与相当。
\4. 通常用制作开机磁片。
more:
Linux more 命令类似 cat ,不过会以一页一页的形式显示,更方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示,而且还有搜寻字串的功能(与 vi 相似),使用中的说明文件,请按 h 。Enter键:一次滚动手册页的一行,f前滚一页,q退出,/word搜索word字符串
语法
1 | more [-dlfpcsu] [-num] [+/pattern] [+linenum] [fileNames..] |
参数:
- -num 一次显示的行数
- -d 提示使用者,在画面下方显示 [Press space to continue, ‘q’ to quit.] ,如果使用者按错键,则会显示 [Press ‘h’ for instructions.] 而不是 ‘哔’ 声
- -l 取消遇见特殊字元 ^L(送纸字元)时会暂停的功能
- -f 计算行数时,以实际上的行数,而非自动换行过后的行数(有些单行字数太长的会被扩展为两行或两行以上)
- -p 不以卷动的方式显示每一页,而是先清除萤幕后再显示内容
- -c 跟 -p 相似,不同的是先显示内容再清除其他旧资料
- -s 当遇到有连续两行以上的空白行,就代换为一行的空白行
- -u 不显示下引号 (根据环境变数 TERM 指定的 terminal 而有所不同)
- +/pattern 在每个文档显示前搜寻该字串(pattern),然后从该字串之后开始显示
- +num 从第 num 行开始显示
- fileNames 欲显示内容的文档,可为复数个数
实例
逐页显示 testfile 文档内容,如有连续两行以上空白行则以一行空白行显示。
1 | more -s testfile |
从第 20 行开始显示 testfile 之文档内容。
1 | more +20 testfile |
常用操作命令
- Enter 向下n行,需要定义。默认为1行
- Ctrl+F 向下滚动一屏
- 空格键 向下滚动一屏
- Ctrl+B 返回上一屏
- = 输出当前行的行号
- :f 输出文件名和当前行的行号
- V 调用vi编辑器
- !命令 调用Shell,并执行命令
- q 退出more
grep:文本搜索工具
Linux grep 命令用于查找文件里符合条件的字符串。
grep 指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设 grep 指令会把含有范本样式的那一列显示出来。若不指定任何文件名称,或是所给予的文件名为 -,则 grep 指令会从标准输入设备读取数据。
常用2种模式查找:
^a: 行首,以a开头的行
ke$:行尾,以ke结尾的行
例:gref ^f a.txt
语法
1 | grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][--help][范本样式][文件或目录...] |
参数:
- -a 或 –text : 不要忽略二进制的数据。
- -A<显示行数> 或 –after-context=<显示行数> : 除了显示符合范本样式的那一列之外,并显示该行之后的内容。
- -b 或 –byte-offset : 在显示符合样式的那一行之前,标示出该行第一个字符的编号。
- -B<显示行数> 或 –before-context=<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前的内容。
- -c 或 –count : 计算符合样式的列数。
- -C<显示行数> 或 –context=<显示行数>或-<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前后的内容。
- -d <动作> 或 –directories=<动作> : 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。
- -e<范本样式> 或 –regexp=<范本样式> : 指定字符串做为查找文件内容的样式。
- -E 或 –extended-regexp : 将样式为延伸的正则表达式来使用。
- -f<规则文件> 或 –file=<规则文件> : 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。
- -F 或 –fixed-regexp : 将样式视为固定字符串的列表。
- -G 或 –basic-regexp : 将样式视为普通的表示法来使用。
- -h 或 –no-filename : 在显示符合样式的那一行之前,不标示该行所属的文件名称。
- -H 或 –with-filename : 在显示符合样式的那一行之前,表示该行所属的文件名称。
- -i 或 –ignore-case : 忽略字符大小写的差别。 (常用)
- -l 或 –file-with-matches : 列出文件内容符合指定的样式的文件名称。
- -L 或 –files-without-match : 列出文件内容不符合指定的样式的文件名称。
- -n 或 –line-number : 在显示符合样式的那一行之前,标示出该行的列数编号。 (显示匹配行及行号,常用)
- -o 或 –only-matching : 只显示匹配PATTERN 部分。
- -q 或 –quiet或–silent : 不显示任何信息。
- -r 或 –recursive : 此参数的效果和指定”-d recurse”参数相同。
- -s 或 –no-messages : 不显示错误信息。
- -v 或 –revert-match : 显示不包含匹配文本的所有行。 (求反,常用)
- -V 或 –version : 显示版本信息。
- -w 或 –word-regexp : 只显示全字符合的列。
- -x –line-regexp : 只显示全列符合的列。
- -y : 此参数的效果和指定”-i”参数相同。
实例
1、在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。此时,可以使用如下命令:
1 | grep test *file |
结果如下所示:
1 | $ grep test test* #查找前缀有“test”的文件包含“test”字符串的文件 |
2、以递归的方式查找符合条件的文件。例如,查找指定目录/etc/acpi 及其子目录(如果存在子目录的话)下所有文件中包含字符串”update”的文件,并打印出该字符串所在行的内容,使用的命令为:
1 | grep -r update /etc/acpi |
输出结果如下:
1 | $ grep -r update /etc/acpi #以递归的方式查找“etc/acpi” |
3、反向查找。前面各个例子是查找并打印出符合条件的行,通过”-v”参数可以打印出不符合条件行的内容。
查找文件名中包含 test 的文件中不包含test 的行,此时,使用的命令为:
1 | grep -v test *test* |
结果如下所示:
1 | $ grep-v test* #查找文件名中包含test 的文件中不包含test 的行 |
P40-41 echo
用于字符串的输出
格式
- echo string
使用echo实现更复杂的输出格式控制
1.显示普通字符串:
1 | echo "It is a test" |
2.显示转义字符
1 | echo "\"It is a test\"" |
3.显示变量
1 | read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量 |
1 | 以上代码保存为 test.sh,name 接收标准输入的变量,结果将是: |
4.显示换行
1 | echo -e "OK! \n" # -e 开启转义 |
1 | 输出结果: |
5.显示不换行
1 | #!/bin/sh |
1 |
- 转义
\a 发出警告声;
\b 删除前一个字符;
\c 最后不加上换行符号;
\f 换行但光标仍旧停留在原来的位置;
\n 换行且光标移至行首;
\r 光标移至行首,但不换行;
\t 插入tab;
\v 与\f相同;
\ 插入\字符;
\nnn 插入nnn(八进制)所代表的ASCII字符;
1 |
6.显示结果定向至文件
1 | echo "It is a test" > myfile |
7.原样输出字符串,不进行转义或取变量(用单引号)
1 | echo '$name\"' |
8.显示命令执行结果
1 | echo `date` |
重定向
Shell 输入/输出重定向
大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。
重定向命令列表如下:
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n 的文件重定向到 file。(会覆盖) |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。(不会覆盖) |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
输出重定向
重定向一般通过在命令间插入特定的符号来实现。特别的,这些符号的语法如下所示:
1 | command1 > file1 |
上面这个命令执行command1然后将输出的内容存入file1。
注意任何file1内的已经存在的内容将被新内容替代。如果要将新内容添加在文件末尾,请使用>>操作符。
实例
执行下面的 who 命令,它将命令的完整的输出重定向在用户文件中(users):
1 | $ who > users |
执行后,并没有在终端输出信息,这是因为输出已被从默认的标准输出设备(终端)重定向到指定的文件。
你可以使用 cat 命令查看文件内容:
1 | $ cat users |
输出重定向会覆盖文件内容,请看下面的例子:
1 | $ echo "菜鸟教程:www.runoob.com" > users |
如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾,例如:
1 | $ echo "菜鸟教程:www.runoob.com" >> users |
输入重定向
和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:
1 | command1 < file1 |
这样,本来需要从键盘获取输入的命令会转移到文件读取内容。
注意:输出重定向是大于号(>),输入重定向是小于号(<)。
实例
接着以上实例,我们需要统计 users 文件的行数,执行以下命令:
1 | $ wc -l users |
也可以将输入重定向到 users 文件:
1 | $ wc -l < users |
注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。
1 | command1 < infile > outfile |
同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中。
重定向深入讲解
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
- 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
- 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
- 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。
如果希望 stderr 重定向到 file,可以这样写:
1 | $ command 2 > file |
如果希望 stderr 追加到 file 文件末尾,可以这样写:
1 | $ command 2 >> file |
2 表示标准错误文件(stderr)。
如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:
1 | $ command > file 2>&1 |
如果希望对 stdin 和 stdout 都重定向,可以这样写:
1 | $ command < file1 >file2 |
command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。
Here Document
Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
它的基本的形式如下:
1 | command << delimiter |
它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
注意:
- 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
- 开始的delimiter前后的空格会被忽略掉。
实例
在命令行中通过 wc -l 命令计算 Here Document 的行数:
1 | $ wc -l << EOF |
我们也可以将 Here Document 用在脚本中,例如:
1 | #!/bin/bash |
执行以上脚本,输出结果:
1 | 欢迎来到 |
/dev/null 文件
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
1 | $ command > /dev/null |
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到”禁止输出”的效果。
如果希望屏蔽 stdout 和 stderr,可以这样写:
1 | $ command > /dev/null 2>&1 |
注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
P41
echo和重定向一起用,例:echo hello > a, 想hello输入a文件中
例 ls -lh > a, ls结果放入a内。>> 是追加。>是覆盖
管道:
Shell 还有一种功能,就是可以将两个或者多个命令(程序或者进程)连接到一起,把一个命令的输出作为下一个命令的输入,以这种方式连接的两个或者多个命令就形成了管道(pipe)。
Linux 管道使用竖线|
连接多个命令,这被称为管道符。Linux 管道的具体语法格式如下:
command1 | command2
command1 | command2 [ | commandN… ]
当在两个命令之间设置管道时,管道符|
左边命令的输出就变成了右边命令的输入。只要第一个命令向标准输出写入,而第二个命令是从标准输入读取,那么这两个命令就可以形成一个管道。大部分的 Linux 命令都可以用来形成管道。
这里需要注意,command1 必须有正确输出,而 command2 必须可以处理 command2 的输出结果;而且 command2 只能处理 command1 的正确输出结果,不能处理 command1 的错误信息。
为什么使用管道?
我们先看下面一组命令,使用 mysqldump(一个数据库备份程序)来备份一个叫做 wiki 的数据库:
mysqldump -u root -p ‘123456’ wiki > /tmp/wikidb.backup
gzip -9 /tmp/wikidb.backup
scp /tmp/wikidb.backup username@remote_ip:/backup/mysql/
上述这组命令主要做了如下任务:
- mysqldump 命令用于将名为 wike 的数据库备份到文件 /tmp/wikidb.backup;其中
-u
和-p
选项分别指出数据库的用户名和密码。 - gzip 命令用于压缩较大的数据库文件以节省磁盘空间;其中
-9
表示最慢的压缩速度最好的压缩效果。 - scp 命令(secure copy,安全拷贝)用于将数据库备份文件复制到 IP 地址为 remote_ip 的备份服务器的 /backup/mysql/ 目录下。其中
username
是登录远程服务器的用户名,命令执行后需要输入密码。
上述三个命令依次执行。然而,如果使用管道的话,你就可以将 mysqldump、gzip、ssh 命令相连接,这样就避免了创建临时文件 /tmp/wikidb.backup,而且可以同时执行这些命令并达到相同的效果。
使用管道后的命令如下所示:
mysqldump -u root -p ‘123456’ wiki | gzip -9 | ssh username@remote_ip “cat > /backup/wikidb.gz”
这些使用了管道的命令有如下特点:
- 命令的语法紧凑并且使用简单。
- 通过使用管道,将三个命令串联到一起就完成了远程 mysql 备份的复杂任务。
- 从管道输出的标准错误会混合到一起。
上述命令的数据流如下图所示:
重定向和管道的区别
乍看起来,管道也有重定向的作用,它也改变了数据输入输出的方向,那么,管道和重定向之间到底有什么不同呢?
简单地说,重定向操作符>将命令与文件连接起来,用文件来接收命令的输出;而管道符|将命令与命令连接起来,用第二个命令来接收第一个命令的输出。如下所示:
command > file
command1 | command1
有些读者在学习管道时会尝试如下的命令,我们来看一下会发生什么:
command1 > command2
答案是,有时尝试的结果将会很糟糕。这是一个实际的例子,一个 Linux 系统管理员以超级用户(root 用户)的身份执行了如下命令:
cd /usr/bin
ls > less
第一条命令将当前目录切换到了大多数程序所存放的目录,第二条命令是告诉 Shell 用 ls 命令的输出重写文件 less。因为 /usr/bin 目录已经包含了名称为 less(less 程序)的文件,第二条命令用 ls 输出的文本重写了 less 程序,因此破坏了文件系统中的 less 程序。
这是使用重定向操作符错误重写文件的一个教训,所以在使用它时要谨慎。
Linux管道实例
【实例1】将 ls 命令的输出发送到 grep 命令:
1 | [c.biancheng.net]$ ls | grep log.txt |
上述命令是查看文件 log.txt 是否存在于当前目录下。
我们可以在命令的后面使用选项,例如使用-al
选项:
1 | [c.biancheng.net]$ ls -al | grep log.txt |
管道符|
与两侧的命令之间也可以不存在空格,例如将上述命令写作ls -al|grep log.txt
;然而我还是推荐在管道符|
和两侧的命令之间使用空格,以增加代码的可读性。
我们也可以重定向管道的输出到一个文件,比如将上述管道命令的输出结果发送到文件 output.txt 中:
1 | [c.biancheng.net]$ ls -al | grep log.txt >output.txt |
【实例2】使用管道将 cat 命令的输出作为 less 命令的输入,这样就可以将 cat 命令的输出每次按照一个屏幕的长度显示,这对于查看长度大于一个屏幕的文件内容很有帮助。
1 | cat /var/log/message | less |
【实例3】查看指定程序的进程运行状态,并将输出重定向到文件中。
1 | [c.biancheng.net]$ ps aux | grep httpd > /tmp/ps.output |
【实例4】显示按用户名排序后的当前登录系统的用户的信息。
1 | [c.biancheng.net]$ who | sort |
who 命令的输出将作为 sort 命令的输入,所以这两个命令通过管道连接后会显示按照用户名排序的已登录用户的信息。
【实例5】统计系统中当前登录的用户数。
1 | [c.biancheng.net]$ who | wc -l |
管道与输入重定向
输入重定向操作符<可以在管道中使用,以用来从文件中获取输入,其语法类似下面这样:
command1 < input.txt | command2
command1 < input.txt | command2 -option | command3
例如,使用 tr 命令从 os.txt 文件中获取输入,然后通过管道将输出发送给 sort 或 uniq 等命令:
1 | [c.biancheng.net]$ cat os.txt |
管道与输出重定向
你也可以使用重定向操作符>或>>将管道中的最后一个命令的标准输出进行重定向,其语法如下所示:
command1 | command2 | … | commandN > output.txt
command1 < input.txt | command2 | … | commandN > output.txt
【实例1】使用 mount 命令显示当前挂载的文件系统的信息,并使用 column 命令格式化列的输出,最后将输出结果保存到一个文件中。
1 | [c.biancheng.net]$ mount | column -t >mounted.txt |
【实例2】使用 tr 命令将 os.txt 文件中的内容转化为大写,并使用 sort 命令将内容排序,使用 uniq 命令去除重复的行,最后将输出重定向到文件 ox.txt.new。
1 | [c.biancheng.net]$ cat os.txt |
管道 |
linux允许讲一个命令的输出可以通过管道作为另一个命令的输入。(有用)
例: ls -lha ~| more: 用more查看
例: ls -lha ~| grep vi: 把match vi的输出,找出来。