注:这并非是一贯正确的,只是约定俗成的大多数程序的代码中都定义了-相关的代码处理。可参考相关命令的man手册。如man cat中有一行:
With no FILE, or when FILE is -, read standard input. here doc输入重定向是<,除此之外还有<<、<<<。
<<符号表示here doc。也就是说,它后面跟的是一篇文档,就像一个文件一样,只不过这个文件的内容是临时定义在<<符号后的。here doc常用于指定多行数据输入。
既然是文档,就有文档起使符号表示文档从此开始和文档终止符号表示文档到此结束。起始符和终止符中间的内容全部是文档内容。文档内容会作为标准输入的数据被读取。
文档的起始符和终止符可以随意定义,但两者前后必须一样。常见的符号是:
EOF:end of file
EOL:end of line
EOB:end of block
例如:
# here doc作为标准输入被读取,然后被cat输出 cat <<EOF hello world EOF # here doc的内容还会被cat覆盖式输出到指定文件 cat <<eof >/tmp/file hello world eof # here doc的内容还会被cat追加式输出到指定文件 cat <<eof >>/tmp/file hello world eof # here doc和重定向符号的前后位置随意 cat >>/tmp/file<<eof ... eof另外,如果将起始符用引号包围,则不会进行变量替换、命令替换、算术替换等。如果不用引号包围起始符,则会进行替换。
a=333 cat <<eof $a eof cat <<"eof" $a eof输出结果:
333 $a here string<<<表示here string。也就是说该符号后面是一个字符串,这个字符串会作为标准输入的内容。
cat <<<"www.junmajinlong.com"使用单引号包围here string时,不会进行变量替换、命令替换等,使用双引号包围时会进行替换。
$ a=3333 $ cat <<<$a 3333 $ cat <<<"hello world$a" hello world3333 $ cat <<<'hello world$a' hello world$ahere string常可以替代管道前的echo命令echo xxx|。例如:
# 下面是等价的 echo hello world | grep "llo" grep "llo" <<<"hello world" 管道管道的用法:
cmd1 | cmd2 | cmd3...每个竖线代表一个管道。上面命令行表示cmd1的标准输出会放进管道,cmd2会从管道中读取进行处理,cmd2的标准输出会放入另一个管道,cmd3会从这个管道中读取数据进行处理。后面还可以接任意数量的管道。
Shell管道是Shell中最值得称赞的功能之一,它以非常简洁的形式实现了管道的进程间通信方式,我个人认为Shell处理文本数据的半壁江山都来自于竖线形式的管道。像其它编程语言,打开管道后还要区分哪个进程写管道、哪个进程读管道,为了安全,每个进程还要关闭不用的读端或写端,总之就是麻烦,而Shell的管道非常简洁,竖线左边的就是写管道的,竖线右边的就是读管道的。
例如:
ps aux | grep 'sshd'ps命令产生的数据(标准输出)会写进管道,只要管道内一有数据,grep命令就从中读取数据进行处理。
那下面的命令中,grep从哪读数据呢?
ps aux | grep '#' /etc/fstab那想要让grep既从/etc/fstab读取数据,也从管道种读取数据呢?
ps aux | grep '#' /etc/fstab /etc/stdin ps aux | grep '#' /etc/fstab - tee命令tee命令可将一份标准输入原样拷贝到标准输出和0或多个文件中。换句话说,tee的作用是数据多重定向。
NAME tee - read from standard input and write to standard output and files SYNOPSIS tee [OPTION]... [FILE]... DESCRIPTION Copy standard input to each FILE, and also to standard output. -a, --append ppend to the given FILEs, do not overwrite如图:
例如:
$ echo hello world | tee /tmp/file1 /tmp/file2 | cat $ echo hello world | tee -a /tmp/file3 >/dev/null 进程替换Bash还支持进程替换(注:有些Shell不支持进程替换)。
进程替换的语法:
<(cmd) >(cmd)进程替换和命令替换类似,都是让cmd命令先执行,因为它们都是在Shell解析命令行的阶段执行的。
进程替换先让cmd放入后台异步执行,并且不会等待cmd执行完。
其实,每个进程替换都是一个虚拟文件,只不过这个文件的内容是由cmd命令产生的(<(cmd))或被cmd命令读取的(>(cmd))。
$ echo <(echo ) /dev/fd/63