[TOC]
0x00 快速入门 主要介绍管道符与输出重定向的基础知识
1. 多命令执行 多命令顺序执行符列表 :
多命令执行符
格式
作用
;
命令1 ; 命令2
多个命令顺序执行,命令之间没有任何逻辑联系
&&
命令1 && 命令2
逻辑与,命令1正确执行才会执行命令2,命令1不正确执行,则命令2不会执行
shift+\shift+\ =ll
命令1 ll 命令2
逻辑或,当命令1执行不正确,则命令2才会执行,当命令1正确执行,则命令2不会执行。注释:其中shift+\意味着
例如:date ; tar -zcvf etc.tar.gz /etc ; date可以计算中间打包压缩命令执行的耗时 再如:ls && echo yes || echo no,第一个命令正确执行,输出yes,错误执行输出no
2. 管道符 命令格式: 命令1 | 命令2,有一定的编程思想在里面 命令1的正确输出作为命令2的操作对象,和逻辑与不一样
实际案例:
[TOC]
0x00 快速入门 主要介绍管道符与输出重定向的基础知识
1. 多命令执行 多命令顺序执行符列表 :
多命令执行符
格式
作用
;
命令1 ; 命令2
多个命令顺序执行,命令之间没有任何逻辑联系
&&
命令1 && 命令2
逻辑与,命令1正确执行才会执行命令2,命令1不正确执行,则命令2不会执行
shift+\shift+\ =ll
命令1 ll 命令2
逻辑或,当命令1执行不正确,则命令2才会执行,当命令1正确执行,则命令2不会执行。注释:其中shift+\意味着
例如:date ; tar -zcvf etc.tar.gz /etc ; date可以计算中间打包压缩命令执行的耗时 再如:ls && echo yes || echo no,第一个命令正确执行,输出yes,错误执行输出no
2. 管道符 命令格式: 命令1 | 命令2,有一定的编程思想在里面 命令1的正确输出作为命令2的操作对象,和逻辑与不一样
实际案例:1 2 3 ls -l /etc | more netstat -an | grep ESTABLISHED netstat -an | grep ESTABLISHED | wc -l
3. 标准输入输出 linux启动后会默认打开3个文件描述符:
设备
设备文件名
类型
文件描述符
内存文件名
使用符号
键盘
/dev/stdin
标准输入/读取数据
0
/proc/self/fd/0
使用 < 或 <<
显示器
/dev/stdout
标准输出数据
1
/proc/self/fd/1
使用 > 或 >>
显示器
/dev/stderr
标准错误输出
2
/proc/self/fd/2
使用 2> 或 2>>
一条shell命令执行,都会继承父进程的文件描述符因此,所有运行的shell命令,都会有默认3个文件描述符。 即对于任何一条linux 命令执行它会是这样一个过程:
先有一个输入:输入可以从键盘,也可以从文件得到 命令执行完成:成功了就会把成功结果输出到屏幕:standard output默认是屏幕 命令执行有错误:会把错误也输出到屏幕上面:standard error默认也是指的屏幕
weiyigeek.top-标准输入输出
(1)输出重定向
类型
符号
作用
标准输出重定向
命令 > 文件
以覆盖的方式,把命令的正确的输出,输出到指定文件或者设备中
标准输出重定向
命令 >> 文件
以追加的方式,把命令的正确输出,输出到指定文件或者设备之中
标准错误输出重定向
错误命令 2 > 文件
以覆盖的方式,把命令的错误的输出,输出到指定文件或者设备中
标准错误输出重定向
错误命令 2 >> 文件
以追加的方式,把命令的错误输出,输出到指定文件或者设备之中
(2)正确和错误输出同时保存
类型
符号
作用
正确输出和错误输入同时保持
命令 > 文件 2>&1 或者 命令 &> 文件
以覆盖方式,把suc与err输出都保存到同一个文件中
命令 >> 文件 2>&1 或者 命令 &>> 文件
以追加方式,把suc与err输出都保存到同一个文件中+
命令 >> suc文件 2>>err文件
把正确的输出追加到文件1中,把错误的输出追加到文件2中
实际示例: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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 command -line1 [0-2] > file &[n] 代表是已经存在的文件描述符,&1 代表输出 &2代表错误输出 &-代表关闭与它绑定的描述符 $任意命令 > /dev/sda ifconfig > ~/desktop/test.log $ls test.sh test1.shls: test1.sh: 没有这个文件和目录 test.sh $ls test.sh test1.sh 1>suc.txt 2> err.txt $cat suc.txt err.txttest.sh ls: 无法访问test1.sh: 没有那个文件或目录 $ls test.sh test1.sh 1>>suc.txt 2>>err.txt $ls test.sh test1.sh &>/dev/null $ls test.sh test1.sh >/dev/null 2>&1 $ls test.sh test1.sh &>file.txt$ls test.sh test1.sh 2>&-test.sh $ls test.sh test1.sh 2>/dev/nulltest.sh $ls test.sh test1.sh 1>&- 2>&-
注意事项:
特别注意错误输出大于号和文件之间不能有空格!!!
1、shell遇到”>”操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件,不存在直接创建, 无论左边命令执行是否成功,右边文件都会变为空
2、“>>”操作符,判断右边文件,如果不存在就先创建。以添加方式打开文件,会分配一个文件描述符[不特别指定,默认为[1,2]然后,与左边的标准输出(1)或错误输出(2) 绑定
3、当命令:执行完,绑定文件的描述符也自动失效0,1,2又会空闲
4、一条命令启动,命令的输入,正确输出,错误输出,默认分别绑定0,1,2文件描述符
5、一条命令在执行前,先会检查输出是否正确,如果输出设备错误,将不会进行命令执行
(3)输入重定向 1 2 3 4 5 command -line [n] <file n >& m 将输出文件 m 和 n 合并 n <& m 将输入文件 m 和 n 合并
实际案例:1 2 3 4 5 6 7 8 9 $cat < catfile testing $cat > filecat >catfile <test.sh
weiyigeek.top-示例2/3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $cat >catfile <<eoftest a filetest !eof $wc < test.log 1 3 54 $wc <<ddy >test.log This is a input content; ddy $cat test.log1 5 27
补充知识点:
EOF字符前面可以采用一个-,后面连接的EOF结束字符不用一定在首行(但是需要采用Tab键功能进行缩进)
4. exec 命令 描述:在上面讲的输入输出重定向,是将输入输出绑定文件或设备后。只对当前那条指令是有效的。如果需要在绑定之后,接下来的所有命令都支持的话,就需要用exec命令来绑定重定向;1 2 exec 文件描述符[n] <或> file或文件描述符或设备
实际案例: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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 $exec 6>&1$ls /proc/self/fd/ 0 1 2 3 6 $exec 1>suc.txtls -al $exec 1>&6 $exec 6>&-$ls /proc/self/fd/0 1 2 3 $exec ps auxroot 84387 0.0 0.0 155372 1868 pts/0 Rs+ 09:22 0:00 ps aux LOGFILE=/var/log /weiyigeek-$(date +%Y%m%d-%s).log exec \ 3>&1 \ 4>&2 \ 5>> "${LOGFILE} " \ > >(tee -a "${LOGFILE} " ) \ 2> >(tee -a "${LOGFILE} " >&2) printf "[$(date +'%Y-%m-%dT%H:%M:%S') ]-\033[31mERROR: ${MSG} \033[0m \n" >&5printf "[$(date +'%Y-%m-%dT%H:%M:%S') ]-\033[31mERROR: ${MSG} \033[0m \n" >&3
weiyigeek.top-删除文件描述符
补充知识点: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 可能有朋友会这样用:exec 1>suc.txt ,接下来所有输出都绑定到suc.txt 文件 exec 1>&2 exec 3<>test.shwhile read line<&3 do echo $line ; done exec 3>&-exec 3<&->& 将一个句柄的输出写入到另一个句柄的输入中 <& 从一个句柄读取输入并将其写入到另一个句柄输出中 exec <a.logwhile read linedo echo $line done
总结重定向应用通常就以下两点:
1、重新设置命令的默认输入、输出,指向到自己文件(文件,文件描述符,设备其实都是文件,因为linux就是基于设备也是文件,描述符也指向是文件)
2、扩展自己新的描述符,对文件进行读写操作
0x02 高级管道命令 <<EOF 描述:Here Document(”嵌入文档“)是 Shell 中的一种特殊的重定向方式,它的基本的形式如下:1 2 3 4 5 6 << delimiter 将开始标记 delimiter 和结束标记 delimiter 之间的内容作为输入,当遇到 delimiter则结束输入 #它的作用是将两个 delimiter(分隔符号)之间的内容(document) 作为输入传递给 command. command << delimiter document delimiter
实际案例: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 28 29 30 31 $wc -l << EOF This is a simple lookup program for good (and bad) restaurants 餐厅 in Cape Town. EOF #!/bin/bash cat << EOF This is a simple lookup program for good (and bad) restaurantsin Cape Town.EOF FTP_SERVER=ftp.n1.dabian.org FTP_PATH=/debian/dists/lenny/main/installer-i386/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz ftp -n << EOF open $FTP_SERVER user anonymous me@linuxbox cd $FTP_PATH hash get $REMOTE_FILE bye EOF ls -l $REMOTE_FILE
注意:
开始的delimiter前后的空格会被忽略掉\
结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进
mkfifo 模块 mkfifo 使用指定的文件名创建FIFO(也称为”命名管道”),它是一种特殊的文件类型,它允许独立的进程通讯(反弹Shell你懂的) 一个进程打开FIFO文件进行写操作,而另一个进程对之进行读操作, 然后数据便可以如同在shell或者其它地方常见的的匿名管道一样流线执行. 默认情况下,创建的FIFO的模式为0666(‘a+rw’)减去umask中设置的位1 2 3 4 5 6 7 8 9 mkfifo [options] file -m mode, --mode=mode:设置创建的FIFO的模式为 mode, 这可以是 chmod(1) 中的符号模式,并使用默认模式作为起始点,其实就是rwx权限 GNU STANDARD OPTIONS(GNU标准选项) --help :在标准输出上打印一条用法信息,并以成功状态退出. --version:在标准输出上打印版本信息,然后以成功状态退出. --:终止选项列表.
实际案例:1 2 3 4 5 6 7 8 mkfifo -m 777 myfifo cat /etc/passwd > myfifo & [10] 6285 cut -d: -f1-3 < myfifo root:x:0 bin:x:1