将输出重定向到文件或程序
标准输入、标准输出和标准错误
构建了一个带有用编号标记通道(文件描述符)的进程结构来管理打开的文件。进程连接到文件,从而到达这些文件所代表的数据内容或设备。通过用于通道0、1、2(称为标准输入、标准输出、标准错误)的默认连接创建进程。进程使用3号及以上编号的通道连接其他文件。
编号 | 通道名称 | 描述 | 默认连接 | 用法 |
---|---|---|---|---|
0 | stdin | 标准输入 | 键盘 | 仅读取 |
1 | stdout | 标准输出 | 终端 | 仅写入 |
2 | stderr | 标准错误 | 终端 | 仅写入 |
3+ | filename | 其他文件 | 无 | 读取或写入 |
[root@linuxprobe dev]# ll std*
lrwxrwxrwx 1 root root 15 Jun 4 22:03 stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun 4 22:03 stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jun 4 22:03 stdout -> /proc/self/fd/1
[root@linuxprobe dev]#
重定向输出到文件
通道重定向将默认通道目标位置替换为代表输出文件或设备的文件名。利用重定向,进程输出和错误消息可以捕获为文件内容,发送到设备,或者丢弃。
重定向stdout可以阻止进程输出显示在终端上。如下表所示,仅重定向stdout不会阻止stderr错误消息显示在终端上。特殊文件**/dev/null**以静默方式丢弃重定向到其中的通道输出。
用法 | 说明 | 视觉辅助 |
---|---|---|
>file | 重定向stdout到文件(1) | |
>>file | 重定向stdout到文件,附加到当前文件内容后面(2) | |
2>file | c重定向stderr到文件(1) | |
2>/dev/null | j将stderr错误消息重定向到/dev/null从而将它丢弃 | |
&>file | j将stdout和stderr合并到一个文件(1) | |
>>file 2>&1 | h合并stdout和stderr并且附加到当前文件内容后面(2)(3) | |
注: | (1)覆盖现有文件,如果为新文件则予以创建。 (2)追加到现有文件,如果为新文件则予以创建。 (3)重定向顺序很重要,可避免出现意外的命令行为。2>&1将stderr发送到与stdout相同的位置。要使其生效,在向stdout中添加stderr之前,需要首先重定向stdout。尽管&>>是向文件中附加stdout和stderr的备选方法,但2>&1是通过管道同时发送stdout和stderr所需要的方法。 |
输出重定向示例
- 保存时间戳,供以后参考
[root@linuxprobe Desktop]# date +%F,%T > test.txt
[root@linuxprobe Desktop]# cat test.txt
2019-05-30,14:27:36
[root@linuxprobe Desktop]#
- 将一个日志文件的最后100行复制到另一文件
[root@linuxprobe Desktop]# tail -5f /var/log/yum.log > test.txt &
[2] 9064
[root@linuxprobe Desktop]# cat test.txt
Feb 20 22:39:08 Installed: 1:openssl-libs-1.0.1e-34.el7.i686
Feb 20 22:39:09 Installed: libssh2-1.4.3-8.el7.i686
Feb 20 22:39:09 Installed: libcurl-7.29.0-19.el7.i686
Feb 20 22:39:09 Installed: pam_pkcs11-0.6.2-17.el7.i686
Feb 20 22:39:09 Installed: pam_krb5-2.4.8-4.el7.i686
[root@linuxprobe Desktop]#
- 将四个文件连接为一个
[root@linuxprobe Desktop]# cat test1.txt test2.txt test3.txt > test.txt
[root@linuxprobe Desktop]# cat test.txt
i am 11111 file
i am 22222 file
i am 33333 file
[root@linuxprobe Desktop]#
- 将文件列表列出到文件中
[root@linuxprobe Desktop]# ll > test.txt
[root@linuxprobe Desktop]# cat test.txt
total 16
drwxr-xr-x 3 root root 17 May 21 23:10 dir1
-rw-r--r-- 1 root root 16 May 30 14:44 test1.txt
-rw-r--r-- 1 root root 16 May 30 14:45 test2.txt
-rw-r--r-- 1 root root 16 May 30 14:45 test3.txt
-rw-r--r-- 1 root root 0 May 30 15:29 test.txt
-rw-r--r-- 1 root root 101 May 30 10:25 test.txt~
[root@linuxprobe Desktop]#
- 将输出附加到现有文件
[root@linuxprobe Desktop]# echo "$(date +%F,%T)" > test.txt
[root@linuxprobe Desktop]# cat test.txt
2019-05-30,15:31:37
[root@linuxprobe Desktop]#
- 下列示例中将产生错误,因为普通用户对系统目录的访问会被拒绝。在终端上查看普通命令输出时,将错误重定向到文件。
[linuxprobe@linuxprobe Desktop]$ touch error.txt
[linuxprobe@linuxprobe Desktop]$ find /etc -name passwd 2> error.txt
/etc/passwd
/etc/pam.d/passwd
[linuxprobe@linuxprobe Desktop]$ cat error.txt
find: ‘/etc/pki/CA/private’: Permission denied
find: ‘/etc/pki/rsyslog’: Permission denied
find: ‘/etc/lvm/archive’: Permission denied
find: ‘/etc/lvm/backup’: Permission denied
find: ‘/etc/lvm/cache’: Permission denied
find: ‘/etc/audit’: Permission denied
find: ‘/etc/ntp/crypto’: Permission denied
find: ‘/etc/selinux/targeted/modules/active’: Permission denied
find: ‘/etc/polkit-1/rules.d’: Permission denied
find: ‘/etc/polkit-1/localauthority’: Permission denied
find: ‘/etc/cups/ssl’: Permission denied
find: ‘/etc/dhcp’: Permission denied
find: ‘/etc/firewalld’: Permission denied
find: ‘/etc/grub.d’: Permission denied
find: ‘/etc/ipsec.d’: Permission denied
find: ‘/etc/libvirt’: Permission denied
find: ‘/etc/audisp’: Permission denied
find: ‘/etc/sudoers.d’: Permission denied
[linuxprobe@linuxprobe Desktop]$
- 将进程输出和错误保存到单独的文件中
[linuxprobe@linuxprobe Desktop]$ find /etc -name passwd >output.txt 2> error.txt
[linuxprobe@linuxprobe Desktop]$ cat output.txt
/etc/passwd
/etc/pam.d/passwd
[linuxprobe@linuxprobe Desktop]$ cat error.txt
find: ‘/etc/pki/CA/private’: Permission denied
find: ‘/etc/pki/rsyslog’: Permission denied
find: ‘/etc/lvm/archive’: Permission denied
find: ‘/etc/lvm/backup’: Permission denied
find: ‘/etc/lvm/cache’: Permission denied
find: ‘/etc/audit’: Permission denied
find: ‘/etc/ntp/crypto’: Permission denied
find: ‘/etc/selinux/targeted/modules/active’: Permission denied
find: ‘/etc/polkit-1/rules.d’: Permission denied
find: ‘/etc/polkit-1/localauthority’: Permission denied
find: ‘/etc/cups/ssl’: Permission denied
find: ‘/etc/dhcp’: Permission denied
find: ‘/etc/firewalld’: Permission denied
find: ‘/etc/grub.d’: Permission denied
find: ‘/etc/ipsec.d’: Permission denied
find: ‘/etc/libvirt’: Permission denied
find: ‘/etc/audisp’: Permission denied
find: ‘/etc/sudoers.d’: Permission denied
[linuxprobe@linuxprobe Desktop]$
- 忽略并丢弃错误消息
[linuxprobe@linuxprobe Desktop]$ find /etc -name passwd >output.txt 2> /dev/null
[linuxprobe@linuxprobe Desktop]$
- 将输出和生成的错误消息存储在一起
[linuxprobe@linuxprobe Desktop]$ find /etc -name passwd &> saveboth.txt
[linuxprobe@linuxprobe Desktop]$
- 将输出和生成的错误消息追加到现有文件
[linuxprobe@linuxprobe Desktop]$ find /etc -name passwd >> saveboth.txt 2>&1
[linuxprobe@linuxprobe Desktop]$
标准输入
- 假如我们使用
cat
命令,后面什么都不接,那么键盘会等待输入,然后按Ctrl+C中断,输入的内容就会重定向到文件中
[root@linuxprobe Desktop]# cat > test.txt
hello world,im kbd
^C
[root@linuxprobe Desktop]# cat test.txt
hello world,im kbd
[root@linuxprobe Desktop]#
- 我们还可以用下面的方式展示标准输入,输入的内容来自于test1.txt
[root@linuxprobe Desktop]# cat test1.txt
i am 11111 file
[root@linuxprobe Desktop]# cat > test.txt < test1.txt
[root@linuxprobe Desktop]# cat test.txt
i am 11111 file
[root@linuxprobe Desktop]#
- 第三种展示标准输入的方式,使用
eof
,进行多行输入,最后以eof
结束
[root@linuxprobe Desktop]# cat > test.txt << eof
> hello
> world
> im fine
> eof
[root@linuxprobe Desktop]# cat test.txt
hello
world
im fine
[root@linuxprobe Desktop]#
构建管道
重定向控制的是至/自文件的通道输出,而管道则是将通道输出发送到另一进程。
进程传送重定向示例
- 分页命令的长输出
[linuxprobe@linuxprobe Desktop]$ ls -a | less
- 计算输出列表的行数
[linuxprobe@linuxprobe Desktop]$ ls | wc -l > output.txt
[linuxprobe@linuxprobe Desktop]$ cat output.txt
3
[linuxprobe@linuxprobe Desktop]$
- 抓取命令输出的前几行或者后几行
[linuxprobe@linuxprobe Desktop]$ ls | tail -2f > output.txt
[linuxprobe@linuxprobe Desktop]$ cat output.txt
output.txt
saveboth.txt
[linuxprobe@linuxprobe Desktop]$
使用tee
命令进行传送的示例
tee
显示或重定向通常因为传送而被隐藏的中间结果。在终端上查看ls
列表,同时将该列表存储到文件中
[linuxprobe@linuxprobe Desktop]$ ls | tee output.txt
error.txt
output.txt
saveboth.txt
[linuxprobe@linuxprobe Desktop]$ cat output.txt
error.txt
output.txt
saveboth.txt
[linuxprobe@linuxprobe Desktop]$
从shell提示符编辑文本文件
使用Vim编辑文件
Linux的一个重要设计原则是信息存储在基于文本的文件中。文本文件包括无格式文件(内有多行相似的信息,如/etc中的配置文件)和可扩展标记语言(XML)文件(通过文本标记定义数据结构,如/etc 和 /usr中的应用配置文件)。文本文件的有点是它们可以在系统间移动或共享,无需转换,而且可通过任何简单文本编辑器进行查看和编辑。
Vim是随Linux和Unix系统分发的vi编辑器的改进版本。Vim对于有经验的用户而言具有很高的可配置性和效率,其包含分屏编辑、颜色格式和突出显示编辑文本等功能。
第一次打开时,Vim以命令模式启动,可用于导航、复制、剪切和粘贴,以及其他文本操作。通过单字符击键进入各个其他模式,访问特定的编辑功能:
- 按i键,进入插入模式,其中键入的所有文本将变为文件的内容。按Esc键返回到命令模式。
- 按v键,进入可视模式,可在其中选择多个字符进行文本操作。
- 按V键,进入可视模式,可在其中选择多行字符进行文本操作。
- 按Ctrl+v键,进入可视模式,可在其中选择文本块进行文本操作。
- 按:键,启动扩展命令模式,可以执行的任务包括写入文件并进行保存,以及退出Vim编辑器等,例如:
扩展命令 | 作用 |
---|---|
:wq | 保存并退出(写入并退出) |
:q | 退出 |
:q! | 文本已编辑不保存强制退出 |
:set number | 显示行号 |
:/string | 查找字符串string,按n查看下一个,N查看上一个 |
Vim中,复制和粘贴称为拖拉和放置,使用的命令字符是y(yanked)和p。
例如,在可视模式中
按键 | 作用 |
---|---|
yy | 复制光标所在行 |
p | 粘贴到下一行 |
3yy | 复制3行 |
dd | 删除行 |
x | 剪切 |