5.将多个命令分组:小括号或大括号可以组合多个命令
# 小括号组合的多个命令是在子Shell中执行 # 即会先创建一个新的Shell进程,在执行里面的命令 (cmd1;cmd2;cmd3) # 大括号组合的多个命令是在当前Shell中执行 # 大括号语法特殊,要求: # 1.开闭括号旁边都有空白,否则语法解析错误(解析成大括号扩展) # 2.写在同一行时,每个cmd后都要加分号结尾 # 3.多个命令可分行书写,不要求分号结尾 { cmd1;cmd2;cmd3; } { cmd1 cmd2 cmd3 } 基本重定向软件设计认为,程序应该有一个数据来源、数据出口和报告错误的地方。在Linux系统中,每个程序默认都会打开三个文件描述符(file descriptor,fd):
fd=0:标准输入,表示程序默认从哪里读取数据
fd=1:标准输出,表示程序默认将数据输出到哪里
fd=2:标准错误,表示程序默认将错误信息输出到哪里
文件描述符,说白了就是系统为了跟踪打开的文件而分配给它的一个数字,这个数字和文件有对应关系:从文件描述符读取数据,即表示从对应的文件中读取数据,向文件描述符写数据,即表示向对应文件中写入数据。
Linux中万物皆文件,文件描述符也是文件。默认:
fd=0的标准输入是/dev/stdin文件
fd=1的标准输出是/dev/stdout文件
fd=2的标准错误是/dev/stderr文件
这些文件默认又是各个终端的软链接文件:
$ ls -l /dev/std* lrwxrwxrwx 1 root root 15 Jan 8 20:26 /dev/stderr -> /proc/self/fd/2 lrwxrwxrwx 1 root root 15 Jan 8 20:26 /dev/stdin -> /proc/self/fd/0 lrwxrwxrwx 1 root root 15 Jan 8 20:26 /dev/stdout -> /proc/self/fd/1 $ ls -l /proc/self/fd/ lrwx------ 1 root root 64 Jan 16 10:40 0 -> /dev/pts/0 lrwx------ 1 root root 64 Jan 16 10:40 1 -> /dev/pts/0 lrwx------ 1 root root 64 Jan 16 10:40 2 -> /dev/pts/0 lr-x------ 1 root root 64 Jan 16 10:40 3 -> /proc/75220/fd所以,默认情况下读写数据都是终端,例如:
# 数据输出到终端 $ echo haha $ cat /etc/fstab # 从终端读取数据 $ cat hello # 在终端输入 hello # 在终端输出 world # 在终端输入 world # 在终端输出 ^C改变文件描述符对应的目标,可以改变数据的流向。比如标准输入fd=1默认流向是终端设备,若将其改为/tmp/a.log,便能让数据写入/tmp/a.log文件中而不再是终端设备中。
在Shell中,这种改变文件描述符目标的行为称为重定向,即重新确定数据的流向。
其实,文件描述符有很多类操作,包括fd的重定向、fd的分配(open,即打开文件)、fd复制(duplicate)、fd的移动(move)、fd的关闭(close)。现在只介绍基础重定向操作。
Shell中,基础重定向操作有以下几种方式:
[n]>file:覆盖式输出重定向,输出到fd=n的数据改变流向输出到file文件中,file不存在则创建,file存在则先清空再写入数据
省略n时>file,等价于1>file,即标准输出覆盖重定向到file文件中
[n]>>file:追加式输出重定向,输出到fd=n的数据改变流向输出到file文件的尾部,file不存在则创建,file存在则直接追加在文件尾部
省略n时>>file,等价于1>>file,即标准输出追加重定向到file文件中
[n]<file:输入重定向,以读取模式打开file文件并分配fd=n,file不存在则报错
省略n时<file,等价于0<file,即直接从file中读数据
通常程序都只从fd=0中读数据,所以当n不等于0时,需要多做一步操作3<file <&3,看不懂先跳过
&>file:这是特殊的重定向方式,表示将标准错误和标准输出都重定向到file文件中,等价于>file 2>&1
&>>file:这是特殊的重定向方式,表示将标准错误和标准输出都追加到file文件中,等价于>>file 2>&1
另外,经常用于输出的一个特殊目标文件是/dev/null,它是空设备,可以直接丢掉所有写入它的数据。
echo >/dev/null curl -I 2>/dev/null >/tmp/a.log cat </etc/fstab一个经常用的技巧是清空文件的方式:
$ cat /dev/null >file $ >file 区分cat <file和cat filecat是一个命令,这个命令的源代码中写了一些代码用来处理选项和参数。
cat -n /etc/fstabcat命令开始执行后,会识别-n选项,该选项会让cat输出时同时输出行号,cat同时还会识别/etc/fstab参数,cat会读取参数指定的文件然后输出。
如果没有指定cat的文件参数,则cat默认会从标准输入中读取数据。默认的标准输入是终端,所以在没有改变标准输入的流向时,会从终端读取数据,也就是用户输入什么字符,就读取什么字符,然后输出什么字符:
$ cat junmajinlong # 在终端输入 junmajinlong # 在终端输出 junma # 在终端输入 junma # 在终端输出 ^C但用户可以改变标准输入的来源。比如:
$ cat </etc/fstab表示将标准输入来源改为/etc/fstab文件,于是cat会从/etc/fstab中读取数据。
另外,约定俗成的,会使用一个-来表示标准输入或标准输出。
# 下面是等价的,都表示从标准输入中读取数据 cat - cat /dev/stdin cat