Linux学习系列三:管道符、重定向与环境变量



这个系列的Linux教程主要参考刘遄老师的《Linux就该这么学》。用的系统是RHEL8,如果遇见一些命令出现问题,请首先检查自己的系统是否一致,如果不一致,可网上查一下系统间某些命令之间的差异。

目前设计的这个Linux学习系列的目录如下:(会陆续更新~)

  1. Linux 学习系列一:Linux的简单介绍以及命令行的基本操作
  2. Linux 学习系列二:Linux中的常用命令
  3. Linux 学习系列三:管道符、重定向与环境变量
  4. Linux 学习系列四:光速掌握Vim,效率提升神器
  5. Linux 学习系列五:Shell命令脚本的基本语法
  6. Linux 学习系列六:用户身份与文件权限


\quad
\quad

管道符、重定向与环境变量

输入输出重定向

输入重定向是指把文件导入到命令中,而输出重定向则是指把原本要输出到屏幕的数据信息写入到指定文件中。

  • 标准输入重定向(STDIN,文件描述符为 0):默认从键盘输入,也可从其他文件或命令中输入。
  • 标准输出重定向(STDOUT,文件描述符为 1):默认输出到屏幕。
  • 错误输出重定向(STDERR,文件描述符为 2):默认输出到屏幕。

首先,需要知道什么是标准输出,什么是错误输出。一个命令如果报错就是错误输出。

[lucky@wz ~]$ ls -l haha.sh
-rw-rw-r--. 1 lucky lucky 46 Feb 24 21:53 haha.sh
[lucky@wz ~]$ ls -l jdpocpsodjgpo
ls: cannot access 'jdpocpsodjgpo': No such file or directory

上述命令种,haha.sh是存在的,所以其输出信息是该文件的一些相关权限,所有者等信息,这就是标准输出信息。而第二个文件是不存在的,所以显示的是该命令的错误输出信息。如果要将原本输出到屏幕上的数据转而写入到文件当中,就要区别对待这两种输出信息。

下面列举一下输入重定向和输出重定向常用的符号及其作用:

  1. 输入重定向中用到的符号及其作用
符号作用
命令 < 文件将文件作为命令的标准输入
命令 << 分界符从标准输入中读入,直到遇见分界符才停止
命令 < 文件 1 > 文件 2将文件 1 作为命令的标准输入并将标准输出到文件 2
  1. 输出重定向中用到的符号及其作用
符号作用
命令 > 文件将标准输出重定向到一个文件中(清空原有文件的数据)
命令 2> 文件将错误输出重定向到一个文件中(清空原有文件的数据)
命令 >> 文件将标准输出重定向到一个文件中(追加到原有内容的后面)
命令 2>> 文件将错误输出重定向到一个文件中(追加到原有内容的后面)
命令 >> 文件 2>&1命令 &>> 文件将标准输出与错误输出共同写入到文件中
(追加到原有内容的后面)

注意:

  1. 对于重定向中的标准输出模式,可以省略文件描述符 1 不写,而错误输出模式的文件描述符 2 是必须要写的。
  2. 上面的>>>符号的区别类似写入文件时,指定的文件打开方式wa

下面列举一些例子,来说明一下重定向的用法:

  1. 标准输出重定向到一个文件中(覆盖写入)
[root@wz lucky]# ll > readme.txt
[root@wz lucky]# cat readme.txt
total 20
drwxr-xr-x. 2 lucky lucky   6 Jan 18 11:18 Desktop
drwxr-xr-x. 2 lucky lucky   6 Jan 18 11:18 Documents
drwxr-xr-x. 2 lucky lucky   6 Jan 18 11:18 Downloads
drwxrwxr-x. 3 lucky lucky  18 Jun  9 07:47 gaga
-rw-rw-r--. 1 lucky lucky  53 Feb 22 06:32 haha
-rw-rw-r--. 1 lucky lucky  46 Feb 24 21:53 haha.sh
-rw-rw-r--. 1 lucky lucky  55 Feb 22 06:37 hoho
drwxr-xr-x. 2 lucky lucky   6 Jan 18 11:18 Music
-rw-rw-r--. 1 lucky lucky 535 Jan 19 09:47 oeasy.txt
-rw-rw-r--. 1 lucky lucky  15 Feb 25 02:36 passwd.txt
drwxr-xr-x. 2 lucky lucky   6 Jan 18 11:18 Pictures
drwxr-xr-x. 2 lucky lucky   6 Jan 18 11:18 Public
-rw-r--r--. 1 root  root    0 Jun  9 21:17 readme.txt
drwxr-xr-x. 2 lucky lucky   6 Jan 18 11:18 Templates
drwxr-xr-x. 2 lucky lucky   6 Jan 18 11:18 Videos
[root@wz lucky]# ls -l readme.txt > readme.txt 
[root@wz lucky]# cat readme.txt 
-rw-r--r--. 1 root root 0 Jun  9 21:19 readme.txt

命令 > 文件会清空文件再写入。

  1. 标准输出重定向到一个文件中(追加写入)
[root@wz lucky]# echo "aoaoaoaoao" >> readme.txt 
[root@wz lucky]# cat readme.txt 
-rw-r--r--. 1 root root 0 Jun  9 21:19 readme.txt
aoaoaoaoao
  1. 虽然都是输出重定向技术,但是不同命令的标准输出和错误输出还是有区别。 如果想把命令的报错信息写入到文件,该怎么操作呢?当用户在执行一个自动化的 Shell 脚本时,这个操作会特别有用,而且特别实用,因为它可以把整个脚本执行过程中的报错信息都记录到文件中,便于安装后的排错工作。
[root@wz lucky]# ls -l xxx
ls: cannot access 'xxx': No such file or directory
[root@wz lucky]# ls -l xxx 2> readme.txt 
[root@wz lucky]# cat readme.txt 
ls: cannot access 'xxx': No such file or directory
  1. 输入重定向的作用是把文件直接导入到命令中。接下来使用输入重定向把 readme.txt 文件导入给 wc -l 命令,统计一下文件中的内容行数。
[root@wz lucky]# wc -l < readme.txt 
1

上述命令实际上等同于cat readme.txt | wc -l的管道符命令组合。 接下来就来讲一下管道符命令。

管道命令符

管道符的执行格式为“命令A | 命令B”。命令符的作用可以用一句话来概括“把前一个命令原本要输出到屏幕的数据当作是后一个命令的标准输入”。

举一些例子:

  1. 统计被限制登录系统的用户个数: 通过grep文本搜索命令匹配关键词/sbin/nologin找出了所有被限制登录系统的用户,然后将其输入到统计文本行数的命令中,wc -l统计行数。
[root@wz lucky]# grep "sbin/nologin" /etc/passwd | wc -l
40
  1. 在修改用户密码时,通常都需要输入两次密码以进行确认,这在编写自动化脚本时将成为一个非常致命的缺陷。通过把管道符和passwd命令的--stdin参数相结合,我们可以用一条命令来完成密码重置操作:
[root@wz lucky]# echo "gaga" | passwd --stdin root
Changing password for user root.
passwd: all authentication tokens updated successfully.

此外,管道命令符在一个命令组合中可以使用多次,我们完全可以这样使用:“命令A | 命令B | 命令C”。

命令行的通配符

通配符就是通用的匹配信息的符号,比如:

  • 星号(*)代表匹配零个或多个字符;
  • 问号(?)代表匹配单个字符;
  • 中括号[]匹配指定范围内的任意单个字符,有多种特殊格式,见下表:
  • 中括号内加上数字[0-9]代表匹配 0~9 之间的单个数字的字符;
  • 中括号内加上字母[abc]则是代表匹配 abc 三个字符中的任意一个字符。

另外,下面列出一些常简的符号:

符号作用
[a-z],[A-Z]不区分大小写,表示a~z中的任意一个字母
[0-9]0~9任意一个数字
[a-z0-9]任意一个字母或任意一个数字
[[:upper:]]所有大写字母
[[:lower:]]所有小写字母
[[:alpha:]]所有字母
[[:digit:]]所有数字
[[:alnum:]]所有的字母和数字
[[:space:]]所有空白字符
[[:punct:]]所有标点符号
[^]匹配指定范围外的任意单个字符。如非大写字母外的所有字符[^[:upper:]],非数字[^[0-9]]

例子:

[root@wz dev]# ls tty*
tty    tty12  tty17  tty21  tty26  tty30  tty35  tty4   tty44  tty49  tty53  tty58  tty62  ttyS0
tty0   tty13  tty18  tty22  tty27  tty31  tty36  tty40  tty45  tty5   tty54  tty59  tty63  ttyS1
tty1   tty14  tty19  tty23  tty28  tty32  tty37  tty41  tty46  tty50  tty55  tty6   tty7   ttyS2
tty10  tty15  tty2   tty24  tty29  tty33  tty38  tty42  tty47  tty51  tty56  tty60  tty8   ttyS3
tty11  tty16  tty20  tty25  tty3   tty34  tty39  tty43  tty48  tty52  tty57  tty61  tty9
[root@wz dev]# ls tty?
tty0  tty1  tty2  tty3  tty4  tty5  tty6  tty7  tty8  tty9
[root@wz dev]# ls tty[0-9]
tty0  tty1  tty2  tty3  tty4  tty5  tty6  tty7  tty8  tty9

注意,看下面的代码:

[root@wz dev]# ls tty[1,3,5,20]
tty0  tty1  tty2  tty3  tty5

注意:[1,3,5,20]匹配不出20,只会匹配出2和0!所以其实上面的,可以省略,不过为了避免混淆,尽量写上。

一些练习的题目:

  1. 显示/var目录下所有以l开头,以一个小写字母结束,且中间出现一位任意字符的文件或目录:
ls -d /var/log/l?[[:lower:]]
  1. 显示/etc目录下。以任意一位数字开头,且以非数字结尾的文件或目录:
ls -d /etc/[0-9]*[^0-9]
  1. 显示/etc目录下,以非字母开头,后面跟一个字母及其他任意长度任意字符的文件或目录:
ls -d /etc/[^[a-z]][a-z]*
  1. 复制/etc目录下,所有以m开头,以非数字结尾的文件或目录至/tmp/m目录:
cp -r /etc/m*[^[0-9]] /etc/m/
  1. 复制/usr/share/man目录下,所有以man开头,后跟一个数字结尾的文件或目录到/tmp/man目录:
cp -r /usr/share/man/man[0-9] /tmp/man/
  1. 复制/etc目录下,所有以.conf结尾,且以m,n,r,p开头的文件或目录到/tmp/conf.d目录下:
cp -r /etc/[mnrp]*.conf /etc/conf.d/

常用的转义字符

4 个最常用的转义字符如下所示。

  • 反斜杠(\):使反斜杠后面的一个变量变为单纯的字符串。
  • 单引号(''):转义其中所有的变量为单纯的字符串。
  • 双引号(""):保留其中的变量属性,不进行转义处理。
  • 反引号(````):把其中的命令执行后返回结果。

例子: 先定义一个名为 PRICE 的变量并赋值为 5,然后输出以双引号括起来的字符串与变量信息:

[root@wz dev]# PRICE=5
[root@wz dev]# echo "Price is $PRICE"
Price is 5

注意,和类似Python这类语言不一样的是,不能写成 PRICE = 5,也就是说不能有空格!

我们希望能够输出“Price is $5”,但碰巧美元符号与变量提取符号合并后的$$作用是显示当前程序的进程ID号码。

[root@wz dev]# echo "Price is $$PRICE"
Price is 9524PRICE

这并不是我们想要的结果,如果想要显示$,可以使用反斜杠进行转义,去除其特殊功能。

t@wz dev]# echo "Price is \$PRICE"
Price is $PRICE

也可以直接使用单引号括起来,因为单引号会转义其中所有的变量为单纯的字符串。

[root@wz dev]# echo 'Price is $PRICE'
Price is $PRICE

如果只需要某个命令的输出值时,可以像命令这样,将命令用反引号括起来,达到预期的效果。例如,将反引号与uname -a命令结合,然后使用echo命令来查看本机的 Linux 版本和内核信息:

[root@wz dev]# echo `uname -a`
Linux wz 4.18.0-80.el8.x86_64 #1 SMP Wed Mar 13 12:02:46 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

重要的环境变量

变量是计算机系统用于保存可变值的数据类型。在 Linux 系统中,变量名称一般都是大写的,这是一种约定俗成的规范。

简单来说,命令在 Linux 中的执行分为 4 个步骤。

  1. 判断用户是否以绝对路径相对路径的方式输入命令(如/bin/ls),如果是的话则直接执行。
  2. Linux 系统检查用户输入的命令是否为“别名命令”,即用一个自定义的命令名称来替换原本的命令名称。
  3. Bash 解释器判断用户输入的是内部命令还是外部命令。内部命令是解释器内部的指令,会被直接执行;而用户在绝大部分时间输入的是外部命令,这些命令交由步骤4继续处理。
  4. 系统在多个路径中查找用户输入的命令文件,而定义这些路径的变量叫作 PATH,作用是告诉 Bash 解释器待执行的命令可能存放的位置,然后 Bash 解释器就会乖乖地在这些位置中逐个查找。

** 别名命令**:在使用rm命令删除文件时,Linux 系统都会要求我们再确认是否执行删除操作, 其实这就是 Linux 系统为了防止用户误删除文件而特意设置的rm别名命令。

  • 可以用alias命令来创建一个属于自己的命令别名,格式为 “alias 别名=命令”。
  • 若要取消一个命令别名,则是用unalias命令,格式为“unalias 别名

判断是内部命令还是外部命令: 使用“type 命令名称”来判断用户输入的命令是内部命令还是外部命令。

lucky@DESKTOP-VQ8KID4:~$ type help
help is a shell builtin

PATH: PATH是由多个路径值组成的变量,每个路径值之间用冒号间隔,对这些路径的增加和删除操作将影响到 Bash 解释器对 Linux 命令的查找。

Linux 系统中最重要的 10 个环境变量

变量名称作用
HOME用户的主目录,即家目录
SHELL用户在使用的 Shell 解释器名称
HISTSIZE输出的历史命令记录条数
HISTFILESIZE保存的历史命令记录条数
MAIL邮件保存路径
LANG系统语言、语系名称
RANDOM生成一个随机数字
PS1Bash 解释器的提示符
PATH定义解释器搜索用户执行命令的路径
EDITOR用户默认的文本编辑器

Linux 作为一个多用户多任务的操作系统,能够为每个用户提供独立的、合适的工作运行环境,因此,一个相同的变量会因为用户身份的不同而具有不同的值。

变量是由固定的变量名与用户或系统设置的变量值两部分组成的,我们可以自行创建变量,来满足工作需求。例如设置一个名称为 WORKDIR 的变量,方便用户更轻松地进入一个层次较深的目录:

[root@wz /]# WORKDIR=/home/lucky/Desktop/
[root@wz /]# cd $WORKDIR
[root@wz Desktop]#

这样的变量不具有全局性,作用范围也有限,默认情况下不能被其他用户使用。 如果工作需要,可以使用 export命令将其提升为全局变量,这样其他用户也就可以使用它了:

[root@wz Desktop]# export WORKDIR
[root@wz Desktop]# su lucky
[lucky@wz Desktop]$ cd /
[lucky@wz /]$ cd $WORKDIR
[lucky@wz Desktop]$ 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlphaGuaGua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值