7.3 重定向和管道

系列 - LINUX VIM和Shell基础

本实验手册主要讲解了Linux中的标准输出和标准错误重定向。实验过程包括标准输出重定向、标准错误重定向和重定向到空设备。通过本实验,学生可以了解到Linux中输出和错误的重定向方法,以及空设备的使用。

1、在 /root/bin 目录下创建 myprogram 文件

Note

Linux 中一切皆文件,命令也是文件

bash

mkdir /root/bin
touch /root/bin/myprogram

文件内容如下:

text

#!/bin/bash

# 输出正常信息到标准输出
echo "这是正常的输出信息"
echo "程序正在运行..."

# 输出错误信息到标准错误
echo "发生了一个错误" >&2

# 制造一个真实的错误
cat 不存在的文件.txt

2、更新 PATH 环境变量

bash

PATH="$PATH:/root/bin"
思考
可以把双引号换成单引号吗?

1、把ls -l /tmp 的结果重定向到当前目录的 tmp-list 文件中:

bash

ls -l /tmp > ./tmp-list

验证:

bash

cat ./tmp-list

2、将 /etc 目录的详情以追加的方式重定向到刚刚的文件中

bash

ls -ld /etc >> ./tmp-list

验证:

bash

cat ./tmp-list

3、利用重定向和wc计算系统中的用户数量

bash

wc < /etc/passwd
警告
一定要注意<符号的方向!!!

结果有三个数字,哪个是用户数?

笔记

wc 命令的全称是 Word Count 用来统计文本的行数、单词数、字节数和字符数 它有以下几个常用参数:

-l 只统计行数(lines)

-w 只统计单词数(words)

-c 只统计字节数(bytes)

-m 只统计字符数(chars)

4、将命令 myprogram 的错误信息保存在当前目录下的err_file文件中

bash

myprogram 2>err_file
# 验证
cat err_file

Tip

系统中并不存在 myprogram 这个命令,所以错误信息是“找不到myprogram命令”

5、接下来按照《准备工作》中的内容,手动创建 myprogram 这条命令

1、执行 myprogram 命令

bash

myprogram

绿色的两行内容是正常输出(标准输出),红色的两行内行是错误输出

2、将标准输出重定向到当前目录的 stdout 文件

bash

myprogram > stdout
# 查看文件
cat stdout

如下图所示,标准输出被重定向到了 stdout 文件中,错误输出直接打印到了屏幕上

3、将标准错误重定向到当前目录下的 stderr 文件中

bash

myprogram 2> stderr
# 查看文件
cat stderr

如下图所示,跟刚才的情况相反:标准输出直接显示在屏幕 🖥️ 上,标准错误被重定向到了文件中

思考
假如 myprogram 没有报错,stderr 文件会发生什么呢? 如果 stderr 文件不存在,又会发生什么呢?

4、多学一招:空设备

有时我们不希望看到错误信息,例如一般情况下 findgrep命令的错误信息没有太大意义,这时可以将错误信息重定向到空设备中。

bash

grep delegate  /etc/* 2>/dev/null

Tip

自己试试,不重定向的话,命令的结果是什么样的?

我们运行命令who来找出已经登录进入系统的用户。该命令的输出结果是每个用户对应一行数据,其中包含了一些有用的信息,为了统计这些信息,我们将这些信息保存在临时文件中。

bash

who > tmpfile

查看文件内容:

bash

cat tmpfile

统计登录数量:

bash

wc -l < tmpfile

如果使用管道的话,可以一条命令做成以上的事情:

bash

who | wc -l

如果想要查看 root 出现了多少次,可以这样写命令(多级管道):

bash

who | grep root | wc -l

注意
管道只接收标准输出流(1号水管)
  1. 将命令 ls -l /etc 的输出保存到当前目录的 list.txt 文件中
  2. 将命令 myprogram 的错误信息保存到 error.log 文件中,正常输出仍显示在屏幕上
  3. 将命令 wc -l /etc/passwd 的输出追加到 list.txt 文件末尾
  4. 运行 myprogram 命令,将所有输出(包括错误)都保存到 all.log 文件中

作为系统管理员,需要分析系统用户的登录情况,生成一份简单报告。

任务要求

  1. 查看当前系统中所有登录用户数量
  2. 统计root用户的登录次数
  3. 查看是否有用户从pts/0终端登录(远程登录)
  4. 统计上午10点之前登录的用户数量
  5. 将以上信息通过管道组合,生成一份简单报告

参考

将命令补全到 $() 内部

bash

# 1.统计所有登录用户
echo "当前登录用户数:" $()

# 2.统计root登录次数
echo "root登录次数:" $()

# 3.检查远程登录情况,pts/0 代表远程登录
echo "远程登录用户:" $(who | grep pts/0)

# 4.统计早上登录用户
echo "上午10点前登录用户数:" $()

# 5.生成报告(保存到文件)
{
    echo "=== 系统用户活动报告 ==="
    echo "生成时间: $()"
    echo "当前登录用户数:" $()
    echo "root登录次数:" $()
    echo "远程登录用户:" $()
    echo "早上登录用户数:" $()
} > report.txt