学习目标:通过命令行输出或编辑器中创建、查看和编辑文件
掌握知识点:
- 通过shell重定向将命令输出或错误保存到文件中,并利用管道通过多个程序处理命令输出。
- 使用vim编辑器创建和编辑文本文件。
- 使用shell变量来帮助运行命令,并编辑Bash启动脚本以设置环境变量。
一、输出重定向
1.1 标准输入、标准输出和标准错误
一个运行的程序(或称为进程)需要从某位置读取输入并将输出写入某位置。从shell提示符运行的 命令通常会从键盘读取其输入,并将输出发送到其终端窗口。
进程使用称为文件描述符的编号通道来获取输入并发送输出。所有进程在开始时至少要有三个文件 描述符。标准输入(通道0)从键盘读取输入。标准输出(通道1)将正常输出发送到终端。标准错 误(通道2)将错误消息发送到终端。如果程序打幵连接至其他文件的单独连接,则可能要使用更 大编号的文件描述符。
1.2 输出重定向到文件
I/O重定向可更改进程获取其输入或输出的方式。该进程并不是从键盘获取输入,也不是将输出和错误发送到终端,而是执行文件读取或写入。重定向允许您将消息保存到通常发送给终端窗口的文 件中。或者,也可以使用重定向来丢弃输出或错误,这样它们就不会显示在终端上或保存下来。
重定向stdout可以阻止进程输出显示在终端上。如下表所示,仅重定向stdout不会阻止 stderr错误消息显示在终端上。如果文件不存在,则会创建文件。如果文件确实存在,但是所需 的重定向没有附加到文件,则该文件的内容将被覆盖。
如果想丢弃消息,特殊文件/dev/null以静默方式丢弃重定向到其自身的通道输出,并且始终是 空文件。
# 将日期存储到文件中 date > /tmp/saved-timestamp # 将某日志文件后10行复制到另一文件 tail -n 10 /var/log/Xorg.9.log > /tmp/last-10-Xorg.9.messages # 将文件列表存储到文件中 ls -a > /tmp/my-file-name
# 将多个文件合成一个文件 echo "0000" > 00.txt echo "1111" > 01.txt echo "2222" > 02.txt echo "3333" > 03.txt cat 00.txt 01.txt 02.txt 03.txt > /tmp/all-four-in-one
# 将内容附加到现有文件中 echo "aaaaaaaa" >> /tmp/many-info echo "bbbbbbbb" >> /tmp/many-info
接下来的几个命令会生成错误消息,因为普通用户无法访问某些系统目录。观察错误消息如何被重定向。在终端上查看普通命令输出时,将错误重定向到文件。
# 在 /etc 目录下查找 passwd find /etc -name passwd 2> /tmp/errors # 查看上面命令出错的信息 cat /tmp/errors # 将显示内容与错误保存到指定文件 find /etc -name passwd > /tmp/output 2> /tmp/errors # 查看显示文件 cat /tmp/output # 查看上面命令出错的信息 cat /tmp/errors # 忽略并丢弃错误消息 find /etc -name passwd > /tmp/output 2> /dev/null # 查看显示文件 cat /tmp/output # 将输出和生成的错误消息存储在一起 find /etc -name passwd &> /tmp/save-both # 查看显示内容 cat /tmp/save-both # 将输出和生成的错误附加到现有文件 find /etc -name passwd >> /tmp/save-both 2>&1
1.3 构建管道
管道是一个或多个命令的序列,用竖线字符(|)分隔。管道将第一个命令的标准输出连接到下一个命 令的标准输入。
在某个进程输出到终端之前,管道允许另一个进程操作和格式化该进程的输出。为便于理解,可以 这样想象一下:数据正在通过管道从一个进程“流”向另一个进程,并且在其流过的管道中每个命令都会略微对其做些改动。
# 以长格式显示 /usr/bin 下所有文件 ls -l /usr/bin # 取 ls 命令的输出并使用 less 在终端上以一次一屏的方式显示输出。 ls -l /usr/bin | less # 显示当前目录下的目录及文件 ls # 将显示当前目录下的目录及文件列中内容,统计出行数 ls | wc -l
1.4 管道、重定向和tee命令
当重定向与管道组合时,shell会首先设置整个管道,然后重定向输入/输出。如果在管道的中间使 用了输出重定向,则输出将转至文件,而不是前往管道中的下一个命令。
# ls命令的输出将转至文件,并且less不会在终端上显示任何内容。 ls > /tmp/saved-output | less
tee命令克服了这个限制。在管道中,tee将其标准输入复制到其标准输出中,并且还将标准输出 重定向到指定为命令参数的文件。如果将数据想象成流经管道的水,那么可将tee视觉化为管道中的T形接头,它负责输出在两个方向上的流向。
# 将ls命令的输出重定向到文件,并且将输出传递到less以便在终端上以一次一屏的方式显示 ls -l | tee /tmp/saved-output | less # 如果在管道末尾使用了 tee,则可以保存命令的最终输出并且同时输出到终端 ls -t | head -n 10 | tee /tmp/ten-last-files
二、从SHELL提示符编辑文本文件
Linux的一个重要设计原则是信息和配置设置通常都存储在基于文本的文件中。这些文件可以采用各 种结构方式,如设置列表、类似于INI的格式、结构化XML或YAML等等。但是,文本文件的优点在于能用任何简单的文本编辑器进行查看和编辑。
Vim有几个运行模式,包括命令模式、扩展命令模式、编辑模式和可视模式。
第一次打开Vim时,它会以命令模式启动,可用于导航、剪切和粘贴,以及其他文本操作。通过单字符击键操作进入各个其他模式,访问特定的编辑功能:
- 按i键进入插入模式,其中键入的所有文本将变为文件内容。按Esc键返回到命令模式。
- 技v键进入可视模式,可在其中选择多个字符进行文本操作。使用Shift+V选择多行,使用 Ctrl+V可选择文本块。用于进入可视模式的击键操作(v、Shift+V或Ctrl+V)也可用于退出。
- 按:键启动扩展命令模式,可以执行的任务包括写入文件(进行保存),以及退出Vim编辑器等。
Vim具有高效的组合击键操作,可进行高级编辑任务。接下来说一下一般文件的操作流程。
i键可使Vim进入插入模式。在此之后输入的所有文本都将被视为文件内容,直到退出插入模式。Esc键可退出插入模式,并让Vim返回到命令模式。u键可撤销最近的编辑。按x键可删除单个字符。:w命令可写入(保存)文件,并保留在命令模式中以进行更多编辑。:wq命令可写入(保 停)文件并退出Vim。:q!命令可退出Vim,同时放弃上次写入以来进行的所有更改。Vim用户必须学习这些命令才能完成任何编辑任务。
三、更改SHELL环境
Bash shell允许设置shell变量,可以使用这些变量来帮助运行命令或修改shell的行为。还可以将shell变量导出为环境变量,它们会在程序启动时自动复制到从该shell运行的程序中。可以使用变量来帮助更轻松地运行带有长参数的命令,或者将常用设置应用于从该shell运行的命令。
Shell变量对于特定shell会话是唯一的。如果打开了两个终端窗口,或者通过两个独立的登录会话登录同一远程服务器,那么在运行两个shell。每个shell都有自己的一组shell变量值。
使用以下语法将值分配给shell变量:
变量名=值
变量名称可以包含大写或小写字母、数字和下划线字符(_)。例如,以下命令可设置shell变量:
C0UNT=40 first_name=John file1=/tmp/abc _ID=RH123
请记住,此更改仅影响在其中运行命令的shell,而不影响在该服务器上运行的任何其他 shell。
可以使用set命令列岀当前设置的所有shell变量。(它还会列出所有shell函数,可以忽略它们)此列表足够长,可能希望将输出通过管道传输到less命令,以便可以一次查看一页。
# 查看 shell 变量,并一次查看一页的方式展示 set | less
接下来展示一下变量的应用。
# 设置变量 COUNT=40 # 输出变量名 echo COUNT # 输出变量的值 echo $COUNT