Linux自动化运维:Shell与Ansible(微课版)
上QQ阅读APP看书,第一时间看更新

1.2.3 控制命令的输入和输出信息

在Linux操作系统中,有一句话被广泛使用,即“一切皆文件”。这句话的意思是,在Linux中,几乎所有东西都可以被视为文件,包括硬件设备(如磁盘、网络接口、键盘等)、软件设备(如随机数生成器、时钟等)和系统资源(如进程、内存等)。这意味着,用户可以使用标准文件操作命令(如cat、less、cp等)来操作这些“文件”。这种“一切皆文件”的设计使得Linux操作系统非常灵活,因为用户可以使用相同的命令操作各种不同的资源。

可以使用cat命令查看硬件设备(如CPU)的状态。此命令会输出CPU的信息,包括型号、速度、缓存大小等。例如:

V1-3 控制命令的输入和输出信息


cat /proc/cpuinfo

还可以使用less命令来查看软件设备(如随机数生成器)的内容。此命令会生成并输出随机数。例如:


less -f /dev/random

在大多数系统中,通常会默认将输出信息显示在屏幕上,而标准的输入信息通过键盘获取。例如,以上命令执行完毕后,输出的结果会显示在屏幕上。但在编写脚本时,有时我们不希望某些命令的输出信息显示在屏幕上。此时,可以先把输出的信息暂时写入文件,等需要使用的时候再读取文件,提取需要的信息。

1. 文件描述符

在Linux操作系统中,文件描述符(File Descriptor,FD)是用于表示打开的文件、网络套接字、管道等资源的整数。FD可以用于标识一个打开的文件,并在程序中用于读写文件内容。FD有如下几个特点。

(1)FD是整数,每个打开的文件都有一个唯一的整数FD。

(2)FD从0开始,在Linux操作系统中,第一个打开的文件的FD是0,第二个是1,以此类推。

(3)FD是进程私有的,每个进程只能访问自己打开的文件,不能访问其他进程的文件。

使用FD的好处在于,它可以简化文件操作流程,即在程序中,给出FD即可对文件进行读写操作,而无须打开文件或者指定文件路径。此外,FD还可以用于标识其他类型的资源,如网络套接字、管道等。使用FD可以将不同类型的资源统一起来,方便进行读写操作。

Linux操作系统有3个预定义的FD:0表示标准输入(stdin)、1表示标准输出(stdout)、2表示标准错误输出(stderr)。

这些特殊的FD可以方便程序访问系统的标准输入、标准输出和标准错误输出,并且可以方便地将它们重定向到其他文件、管道或网络套接字中。在Linux操作系统中,FD可以与输入输出重定向、管道符等功能结合起来使用。

2. 输入输出重定向与管道符

在Linux操作系统中,标准输入通常是指键盘,标准输出通常是指屏幕,标准错误输出通常也是指屏幕。

通过使用输入输出重定向可以改变命令的输入或输出的来源或目的地,进而改变命令的输入或输出方式。重定向可以让命令行中执行的命令从标准输入或标准输出转移到其他位置。

例如,可以使用输入重定向将文件作为命令的输入,或者使用输出重定向将命令的输出保存到文件中。这可以让用户在执行命令时灵活地控制它们的输入和输出。此外,输入输出重定向还可以让用户将命令的输出作为另一个命令的输入,从而实现命令串联。这是在Linux操作系统中执行复杂任务的一种常用方法。常见的输入输出重定向符号和示例如表1-1所示。

表1-1 常见的输入输出重定向符号和示例

在Linux操作系统中,可以使用>和<符号来实现输入输出重定向。具体来说,<符号可以将标准输入重定向到文件中,而>符号可以将标准输出重定向到文件中。

使用<符号将输入重定向到文件中,例如:


sort < input.txt

此命令会将文件input.txt中的内容作为sort命令的输入。

使用>符号将输出重定向到文件中,例如:


ls > output.txt

此命令会将ls命令的输出写入文件output.txt。如果该文件不存在,则会创建文件;如果该文件已存在,则会覆盖文件中的内容。

使用>>符号将输出追加到文件末尾,例如:


ls >> output.txt

此命令会将ls命令的输出追加到文件output.txt的末尾,之前已经存在的内容不会被覆盖。

在Linux操作系统中,可以使用管道来实现程序之间的通信。管道是一种特殊的文件,它可以在程序之间传输数据。例如,可以使用管道将一个程序的输出作为另一个程序的输入,这样就可以使用多个命令来实现更复杂的功能。

使用管道符将输出传递给其他命令,例如:


ls | grep txt

此命令会将ls命令的输出传递给grep命令,此后grep命令会搜索输入中的txt字符串。这样就可以通过两个命令的结合来实现更复杂的功能。

3. 特殊文件/dev/null和/dev/zero

在Linux操作系统中,字符类型的文件通常为设备文件。设备文件是指表示输入或输出设备的特殊文件,它们不存储数据,而是存储特定的信息,这些信息对应设备的输入输出。字符类型的文件可以用于表示如终端、串行端口、打印机等设备。这些文件可以通过文件系统调用来读取或写入数据。与普通文件不同的是,设备文件的内容由设备本身的特性决定。因此,设计字符类型文件的目的是方便系统管理员和程序员通过文件系统调用来操作设备,为其他程序提供某些特定的输入或输出操作,而不必直接和设备交互。

/dev/null是一个特殊的字符类型文件,也被称为“黑洞文件”,写入它的内容都会被丢弃,并且读取它时会返回空,通常用于丢弃不需要的输出或者忽略不需要的输入。/dev/null常被用来作为命令的输出或输入的“垃圾桶”,用于丢弃不需要的数据。使用以下命令将命令的输出重定向到/dev/null:


echo"This message will be discarded" > /dev/null
# 忽略命令的输出信息

/dev/null文件还可以用来忽略错误信息,例如:


command 2> /dev/null
# 忽略命令的错误信息

/dev/null也被用于丢弃不需要的输出,例如:


ls -l /non-existent-dir 2>/dev/null
# 使用2>/dev/null进行输出重定向,表示将标准错误输出重定向到 /dev/null,这样就可以忽略ls命
# 令的错误输出

/dev/zero是一个特殊的设备文件,它可以产生无限的空字符(即0值字节)。因此,/dev/zero经常用来初始化缓冲区或者占位。可以使用与操作/dev/null相似的方法来操作/dev/zero。/dev/zero在被读取时会提供无限的空字符,其典型用法包括用它提供的字符流来覆盖信息,以及产生一个特定大小的空白文件。

/dev/zero通常用于初始化数据,例如,创建一个名为file.bin、大小为1MB的文件,以美国信息交换标准代码(American Standard Code for Information Interchange,ASCII)值为0的字符填充:


dd if=/dev/zero of=file.bin bs=1M count=1

在上面的命令中,使用了if=/dev/zero和of=file.bin进行输入输出重定向,表示将/dev/zero的内容作为输入写入file.bin文件,这样就可以创建一个大小为1MB的二进制文件。

4. EOF

文件结束标志(End of File,EOF)是一个特殊的字符串,表示文件的末尾或者输入流的结束,可以作为一种特殊的输入重定向符号,通常用来将多行文本传递给命令,而不用将文本保存到文件中。在Shell脚本中,EOF常用于在脚本中嵌入多行文本,而不需要使用多个echo命令或使用其他文件来存储文本。

在Shell脚本中,EOF可以用在以下场景中:从标准输入中读取多行文本、将多行文本输出到文件中、将多行文本追加到文件中、将多行文本作为参数传递给命令。

使用以下命令将多行文本输入cat命令,例如:


cat << EOF >> eof-stdin.txt
This is line 1
This is line 2
This is line 3
EOF
# 查看eof-stdin.txt文件的内容
cat eof-stdin.txt
This is line 1
This is line 2
This is line 3

在上面的命令中,EOF前面的 << 是输入重定向符号,表示从这里开始的输入都将被重定向到cat命令,>> eof-stdin.txt表示将输入的内容输出到eof-stdin.txt文件中。

注意:后一个EOF必须独占一行,且前面不能有任何字符。

若在脚本中包含一个结构化查询语言(Structure Query Language,SQL)语句,则可以使用EOF来嵌入该语句,例如:


mysql -u username -p password << EOF
USE mydatabase;
SELECT * FROM mytable;
EOF

这个脚本会打开MySQL命令行工具,使用用户名和密码登录数据库,并在mydatabase数据库中执行SELECT语句,输出mytable表中的所有数据。