Shell Tutorial 04

Shell input/output redirection. Modified: 2023-07-18 22:28:26 Created: 2021-08-22 09:50:08 Tags: #linux #shell

Shell 命令通常有输入输出。默认从标准输入设备(stdin)获取输入,结果输出到标准输出设备(stdout)显示。通常:

  • 标准输入设备:键盘
  • 标准输出设备:终端,即显示器

Shell 命令运行时都会打开三个文件:

  • 标准输入文件(stdin):文件描述符0,从stdin读取数据
  • 标准输出文件(stdout):文件描述符1,向stdout输出数据
  • 标准错误文件(stderr):文件描述符2,向stderr流中写入错误信息

但是输入输出也可来自其它地方,这就是输入输出重定向。

1 输出重定向

1.1 标准输出重定向

将命令的标准输出写到文件里:

command 1> log_a.txt # 直接输出,覆盖之前的文件
command 1>> log_b.txt # 添加到之前文件的后面

需要注意command后面的1>1>>,在1>>>之间是没有空格的。如果按照下面写法,则1command的参数。

command 1 > log_a.txt

由于默认是标准输出,也可以去掉1

command > log_a.txt
command >> log_a.txt

1.2 标准错误重定向

标准错误的文件描述符是2

command 2>log_a.txt
command 2>>log_a.txt

标准错误中的2一定要放置在>或者>>前,且中间没有空格

1.3 同时重定向

command >log.txt 2>&1 # 把标准错误和标准输出同时输出到一个文件
command 1>log_a.txt 2>log_b.txt # 将两者输出到不同的文件

输出文件合并

n >& m # 将输出文件 m 和 n 合并。

1.4 特殊的/dev/null

/dev/null是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。(看起来像个黑洞。)但/dev/null文件非常有用,将命令的输出重定向到它,会起到禁止输出的效果。

command > /dev/null
command 2> /dev/null
command > /dev/null 2>&1

2 输入重定向

可以理解和输出重定向相反,输入来自于文件。

2.1 输入重定向

标准输入是键盘,其实也可以从文件输入:

shell_command < filea.txt # 将filea.txt的内容作为标准输入

2.2 输入文件合并

n <& m #将输入文件 m 和 n 合并。

2.3 Here document

就是在命令行中输入多行文字:

command << delimiter
document
delimiter

它将两个delimiter之间的内容(document) 作为输入传递给 command

  • 结尾的delimiter一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
  • 开始的 delimiter 前后的空格会被忽略掉。

也可将Here Document用在脚本中:

#!/bin/bash
cat << EOF
This is a simple lookup program for good (and bad) restaurants
in Cape Town.
EOF

3 输入输出重定向

同时处理输入和输出的情况。

command < file1 >file2 # 把file1作为标准输入,file2作为标准输出

4 管道命令

4.1 |命令

管道命令(|)将一个命令的输出,转换为另外一个命令的输入。

常见情形如筛选文件夹(如.)中包含特定名字(如y)的文件:

ls . | grep y

这里就使用了管道命令|,将ls .的输出转换为grep命令的输入。管道命令可以连续使用,则是ls . | grep y | grep -v x:筛选出所有包含y但是不包含x的文件。

管道命令会开启新的线程来执行。比如说grep y就和ls .并不在同一个线程。

4.2 xargs对输出进行操作

管道命令的输出并不一定满足下一个命令的输入,有时候需要对管道命令进行一些操作再传递为输入,此时就需要xargs命令。xargs(extended arguments),可以实现:

  1. 参数处理
  2. 从文件中读取信息作为输入

xargs后需要接后续处理的命令,如果没有显示指定,则默认为echo。虽然xargs的输入可以包含空格和换行,但是经过echo的处理,都会变成空格。

ls . | ls -l

这里报错原因是ls -l的输入不对,需要用xargs命令来转换一下:

ls . | xargs ls -l

常见参数如下,为了说明问题,这里构建了例子文件。

 cat x.txt
shell_00.md
shell_01.md
shell_02.md
shell_03.md
shell_04.md
shell_05.md
  • -a xx 从文件获取输入
 xargs -a x.txt file
shell_00.md: Unicode text, UTF-8 text
shell_01.md: Unicode text, UTF-8 text
shell_02.md: Unicode text, UTF-8 text
shell_03.md: Unicode text, UTF-8 text
shell_04.md: Unicode text, UTF-8 text
shell_05.md: Unicode text, UTF-8 text
  • -p 每执行一个参数时询问一次用户,需要输入y+回车键 或者 yes+回车键表示确定,单独输入回车键表示不执行:
 xargs -a x.txt -p file
file shell_00.md shell_01.md shell_02.md shell_03.md shell_04.md shell_05.md?...yes
shell_00.md: Unicode text, UTF-8 text
shell_01.md: Unicode text, UTF-8 text
shell_02.md: Unicode text, UTF-8 text
shell_03.md: Unicode text, UTF-8 text
shell_04.md: Unicode text, UTF-8 text
shell_05.md: Unicode text, UTF-8 text
  • -n num,命令执行时一次用的参数个数,默认用所有的,如果已经有的参数超过了这个数目,则会分行执行。
 xargs -a x.txt -p -n 2 file
file shell_00.md shell_01.md?...yes
shell_00.md: Unicode text, UTF-8 text
shell_01.md: Unicode text, UTF-8 text
file shell_02.md shell_03.md?...yes
shell_02.md: Unicode text, UTF-8 text
shell_03.md: Unicode text, UTF-8 text
file shell_04.md shell_05.md?...yes
shell_04.md: Unicode text, UTF-8 text
shell_05.md: Unicode text, UTF-8 text
  • -t 先打印具体执行的命令,再执行

  • -i-I,将xargs的每项名称,一般是一行一行赋值给{},可以用{}代替

  • -r no-run-if-empty 当 xargs 的输入为空的时候则停止 xargs,不再去执行

  • -L-l num 从标准输入一次读取 num 行送给后面的命令
 xargs -a x.txt -t -L 2 file
file shell_00.md shell_01.md
shell_00.md: Unicode text, UTF-8 text
shell_01.md: Unicode text, UTF-8 text
file shell_02.md shell_03.md
shell_02.md: Unicode text, UTF-8 text
shell_03.md: Unicode text, UTF-8 text
file shell_04.md shell_05.md
shell_04.md: Unicode text, UTF-8 text
shell_05.md: Unicode text, UTF-8 text

需要和前面-n做一个区别。这里指的是输入的行数,而-n指的是输出的参数的个数。

  • -d delimeter 分隔符,默认分隔符是空格,是 xargs 的输入的分隔
 echo "ambmcmdm" | xargs -dm
a b c d
  • -e-E flag, e 是 end 的意思,flag 必须是一个以空格分隔的标志,当 xargs 分析到含有 flag 这个标志的时候就停止
  • -s num 命令行的最大字符数,xargs 后面那个命令的最大命令行字符数
  • -x exit,配合-s使用
  • -P 修改最大的进程数,默认是 1,为 0 时候尽可能多。

4.3 tee命令

t 读取标准输入的数据,并将其内容输出成文件。常见参数如下:

  • -a 或--append  附加到既有文件的后面,而非覆盖它.
  • -i 或--ignore-interrupts  忽略中断信号。

总结

本文介绍了 Shell 中输入输出重定向,以及通过管道命令来实现前一命令的输出作为后一命令的输入。以此介绍了xargstee命令。