Shell脚本深入教程(1):快速入门 (2)

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 file

cat是一个命令,这个命令的源代码中写了一些代码用来处理选项和参数。

cat -n /etc/fstab

cat命令开始执行后,会识别-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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzwzjd.html