Contents

在Bash中写入文本文件

1. 简介

我们有时会遇到想要保存命令输出的情况。能够直接从终端写入文件是 Linux 提供的重要功能之一。这使得生成可以进一步处理的文件变得非常容易。当我们运行脚本时,写入文件也很方便。我们的脚本需要一个地方来发送数据、存储数据并保存它在执行过程中产生的错误。

**在本教程中,我们将了解利用直接从 Bash 终端写入文件的功能的各种方法。**我们将首先了解如何将信息保存到文件而不是将其发送到终端,以及如何将输出发送到终端和文件。稍后,我们将编写一个兼具两者的小脚本。

2.标准输入/输出重定向

Linux bash 有不同的选项来接收命令的输入和保存命令的输出。最常用的方法之一是输入/输出重定向。重定向是我们可以使 shell 改变命令的标准输入来自哪里以及标准输出去哪里的过程。

重定向具有三个数据* *:

标准输入(stdin) ——这是程序从中获取信息的地方。**默认情况下,shell 从键盘接收标准输入。我们可以更改此默认行为,以便程序从不同的源(如文件)接收数据。<运算符表示标准输入重定向。在本教程中,我们不会关注stdin

标准输出(stdout) – 是程序将其生成的信息发送到的地方。**首先,终端接收输出。> 运算符表示标准输出。当我们使用输出重定向时,我们应该小心,因为它会破坏文件。如果文件存在,shell 将覆盖它并销毁其内容。如果没有,它会创建文件。

标准错误(stderr) ——**当我们运行命令时,我们有可能遇到错误。**这些错误可以发送到终端或写入单独的文件。或者,我们也可以将stderr称为错误消息

2.1.标准输出和标准错误重定向示例

要重定向标准输出,我们在命令后使用*> 运算符并在符号后键入文件名。当我们使用标准输出*时,我们还可以通过包含文件名的路径来指定我们想要保存文件的目录,如下所示:

$ uname -a > compinfo.txt

早些时候,我们曾提到输出重定向可能会损坏文件。如果文件已经存在,我们使用*» 符号*附加到文件,这是可以避免的:

$ date >> compinfo.txt

我们可以通过启用noclobber来防止文件被覆盖:

$ set -o noclobber

当我们运行命令并在执行过程中遇到错误时,我们可以使用stderr将该错误发送到文件中。为了重定向stderr,我们使用stdout操作符,在它前面加上 2:

$ fdisk -l 2> errors.txt

要将stderrstdout发送到同一个文件,我们使用&>

3. 其他写入文件的命令

除了标准输出和标准错误,我们还有*tee 命令。此命令从标准输入读取以显示到屏幕并写入一个或多个文件。如果我们在tee上使用-a*标志,它会附加。

我们可以通过将标准输出发送到/dev/null 来阻止tee在终端上显示输出:

$ uname -a | tee systeminfo.txt
$ date | tee  systeminfo.txt systeminfo2.txt
$ date | tee -a systeminfo.txt
$ uname -a | tee systeminfo.txt > /dev/null

4. 从脚本写入文件

通常,我们编写的脚本执行不同的功能。其中一些功能非常关键,以至于我们不希望每个人都能够查看产生的输出。在执行过程中,这些脚本也可能会遇到可能泄露机密信息的错误。因此,最好为此类错误定义一个位置而不是终端。

现在让我们编写一个简单的脚本来生成计算机的系统信息并将其发送到文件中。我们还将为错误指定一个单独的文件。让我们创建一个名为 sysinfo.sh 的文件并输入以下内容:

#!/usr/bin/bash
mkdir info;
( date; echo ; uname -a; echo ; free -h;fdisk -l; echo ; ) > info/systeminfo.txt 2> info/systeminfoerror.txt;

( echo -e "\n DISK INFORMATION. \n"; sudo fdisk -l;echo ; ) >> info/systeminfo.txt; 
lscpu | tee info/cpu_info_1.txt #output sent to both screen and file
lscpu | tee info/cpuinfo_2.txt > /dev/null; #no output is sent to screen
echo -e "\t\t\t Located in:$HOME/info/ \t\t\t";

如果我们不希望输出tee发送到屏幕,我们可以将标准输出重定向到*/dev/null*。此外,为了对命令进行分组,我们可以将它们括在括号或花括号中。这使我们能够将它们作为一个单元执行。最后,让我们保存文件,运行它并查看输出:

$ bash sysinfo.sh
$ ls info/
cpu_info_1.txt  cpuinfo_2.txt  systeminfoerror.txt  systeminfo.txt