管道符、重定向与环境变量
文件读写操作有关的重定向技术的 5 种模式
— 标准覆盖输出重定向、标准追加输出重定向、错误覆盖输出重定向、错误追加输出重定
向以及输入重定向,让读者通过实验切实理解每个重定向模式的作用,解决输出信息的保存
问题。
管道命令符,帮助读者掌握命令之间的搭配使用方法,进一步提高命令输出值的处理效率。
输入输出重定向
输入重定向是指把文件导入到命令中,而输出重定向则是指把原本要输出到屏幕的数据信息写入到指定文件中。
输出重定向分为了标准输出重定向和错误输出重定向两种不同的技术,以及清空写入与追加写入两种模式。
➢ 标准输入重定向(STDIN,文件描述符为 0):默认从键盘输入,也可从其他文件或命
令中输入。
➢ 标准输出重定向(STDOUT,文件描述符为 1):默认输出到屏幕。
➢ 错误输出重定向(STDERR,文件描述符为 2):默认输出到屏幕。
对于输入重定向来讲,用到的符号及其作用:
命令 < 文件 将文件作为命令的标准输入
命令 << 分界符 从标准输入中读入,直到遇见分界符才停止
命令 < 文件 1 > 文件 2 将文件 1 作为命令的标准输入并将标准输出到文件 2
对于输出重定向来讲,用到的符号及其作用:
命令 > 文件 将标准输出重定向到一个文件中(清空原有文件的数据)
命令 2> 文件 将错误输出重定向到一个文件中(清空原有文件的数据)
命令 >> 文件 将标准输出重定向到一个文件中(追加到原有内容的后面)
命令 2>> 文件 将错误输出重定向到一个文件中(追加到原有内容的后面)
命令 >> 文件 2>&1 或 命令 &>> 文件
将标准输出与错误输出共同写入到文件中(追加到原有内容
的后面)
命令 >>file1 2>>file2
以追加的方式,把正确的输出结果输出到 file1 文件中,把错误信息输出到 file2 文件中。
命令 &>/dev/null
如果你既不想把命令的输出结果保存到文件,也不想把命令的输出结果显示到屏幕上。
大家可以把 /dev/null 当成 Linux 系统的垃圾箱,任何放入垃圾箱的数据都会被丢弃,不能恢复。
# echo "Welcome to LinuxProbe.Com" > readme.txt
# echo "Quality linux learning materials" >> readme.txt
# ls -l linuxprobe 2> /root/stderr.txt
# nohup java -jar /usr/sbin/lb-agent.jar >>/var/log/lb-agent.log 2>&1 &
将jar执行的结果写入到lb-agent.log中
# nohup java -jar /usr/sbin/lb-agent.jar &>/dev/null &
我建议把正确结果和错误信息分开保存到不同的文件中
# ls -l >>out.log 2>>err.log
说明:
在命令最后加上&符号,表示让这个进程到后台去执行,这样立刻返回到提示符状态,我们可以接着做下面的事。如:command &。
这种“后台”进程在shell一直打开的情况下是没有问题的,如果我们关了shell窗口甚至退出ssh登录或vnc登录,那么进程自动就结束了。所以如果想退出窗口乃至退出登录仍然保持程序运行,再加上nohup,形如:nohup command 1>output 2>&1 &
管道命令符
其执行格式为“命令 A | 命令 B”。管道命令符的作
用也可以用一句话来概括“把前一个命令原本要输出到屏幕的标准正常数据当作是后一个命
令的标准输入”。
我们通过匹配关键词/sbin/nologin 找出了所有被限制登录系统的用户
# grep "/sbin/nologin" /etc/passwd | wc -l
命令行的通配符
顾名思义,通配符就是通用的匹配信息的符号,比如星号(*)代
表匹配零个或多个字符,问号(?)代表匹配单个字符,中括号内加上数字[0-9]代表匹配 0~
9 之间的单个数字的字符,而中括号内加上字母[abc]则是代表匹配 a、b、c 三个字符中的任意
一个字符。
匹配所有在/dev 目录中且以 sda 开头的文件
# ls -l /dev/sda*
如果只想查看文件名为 sda 开头,但是后面还紧跟其他某一个字符的文件的相关信息
# ls -l /dev/sda?
除了使用[0-9]来匹配 0~9 之间的单个数字,也可以用[135]这样的方式仅匹配这三个指定
数字中的一个,若没有匹配到,则不会显示出来
# ls -l /dev/sda[0-9]
# ls -l /dev/sda[135]
常用的转义字符
4 个最常用的转义字符如下所示。
➢ 反斜杠(\):使反斜杠后面的一个变量变为单纯的字符串。
➢ 单引号(’’):转义其中所有的变量为单纯的字符串。
➢ 双引号(""):保留其中的变量属性,不进行转义处理。
➢ 反引号(``):把其中的命令执行后返回结果。
# PRICE=5
# echo "Price is $PRICE"
Price is 5
# echo "Price is \$$PRICE"
Price is $5
# echo `uname -a`
Linux linuxprobe.com 3.10.0-123.el7.x86_64
重要的环境变量
在 Linux 系统中,变量名称一般都是大写的,这是一种约定俗成的规范。我们可以直接通过变量名称来提取到对应的变量值。Linux系统中的环境变量是用来定义系统运行环境的一些参数。
那么,在用户执行了一条命令之后,Linux 系统中到底发生了什么事情呢?简单来说,命令在 Linux 中的
执行分为 4 个步骤。
第一步:判断用户是否以绝对路径或相对路径的方式输入命令(如/bin/ls),如果是的话
则直接执行。
第二步:Linux 系统检查用户输入的命令是否为“别名命令”,即用一个自定义的命令
名称来替换原本的命令名称。可以用 alias 命令来创建一个属于自己的命令别名,格式为
“alias 别名=命令”。若要取消一个命令别名,则是用 unalias 命令,格式为“unalias 别名”。
我们之前在使用 rm 命令删除文件时,Linux 系统都会要求我们再确认是否执行删除操作,
其实这就是 Linux 系统为了防止用户误删除文件而特意设置的 rm 别名命令,接下来我们
把它取消掉.
# alias rm
alias rm='rm -i'
# unalias rm
# rm initial-setup-ks.cfg
第三步:Bash 解释器判断用户输入的是内部命令还是外部命令。内部命令是解释器内部
的指令,会被直接执行;而用户在绝大部分时间输入的是外部命令,这些命令交由步骤 4 继
续处理。可以使用“type 命令名称”来判断用户输入的命令是内部命令还是外部命令。
第四步:系统在多个路径中查找用户输入的命令文件,而定义这些路径的变量叫作PATH,可
以简单地把它理解成是“解释器的小助手”,作用是告诉 Bash 解释器待执行的命令可能存放
的位置,然后 Bash 解释器就会乖乖地在这些位置中逐个查找。PATH 是由多个路径值组成的
变量,每个路径值之间用冒号间隔,对这些路径的增加和删除操作将影响到 Bash 解释器对
Linux 命令的查找。
# echo $PATH
# PATH=$PATH:/root/bin
这里有比较经典的问题:“为什么不能将当前目录(.)添加到 PATH 中呢? ” 原因是,
尽管可以将当前目录(.)添加到 PATH 变量中,从而在某些情况下可以让用户免去输入命令
所在路径的麻烦。但是,如果黑客在比较常用的公共目录/tmp 中存放了一个与 ls 或 cd 命令同
名的木马文件,而用户又恰巧在公共目录中执行了这些命令,那么就极有可能中招了。
Linux 系统中所有的环境变量。
HOME 用户的主目录(即家目录)
SHELL 用户在使用的 Shell 解释器名称
HISTSIZE 输出的历史命令记录条数
HISTFILESIZE 保存的历史命令记录条数
MAIL 邮件保存路径
LANG 系统语言、语系名称
RANDOM 生成一个随机数字
PS1 Bash 解释器的提示符
PATH 定义解释器搜索用户执行命令的路径
EDITOR 用户默认的文本编辑器
其实变量是由固定的变量名与用户或系统设置的变量值两部分组成的,我们完全可以自
行创建变量,来满足工作需求。
# WORKDIR=/home/workdir
# cd $WORKDIR
但是,这样的变量不具有全局性,作用范围也有限,默认情况下不能被其他用户使用。
如果工作需要,可以使用 export 命令将其提升为全局变量,这样其他用户也就可以使用它了。
export WORKDIR
读取环境变量的方法
export
命令显示当前系统定义的所有环境变量echo $PATH
命令输出当前的PATH
环境变量的值
$ export
$ echo $PATH
环境变量配置
方法一:使用export
命令直接修改PATH
的值
export PATH=$PATH:/home/uusama/mysql/bin
注意事项:
- 生效时间:立即生效
- 生效期限:当前终端有效,窗口关闭后无效
- 生效范围:仅对当前用户有效
- 配置的环境变量中不要忘了加上原来的配置,即
$PATH
部分,避免覆盖原来配置
方法二:通过修改用户目录下的~/.bash_profile
文件进行配置
vim ~/.bash_profile
# 在最后一行加上
export PATH=$PATH:/home/uusama/mysql/bin
注意事项:
- 生效时间:使用相同的用户打开新的终端时生效,或者手动
source ~/.bash_profile
生效 - 生效期限:永久有效
- 生效范围:仅对当前用户有效
- 如果没有
~/.bash_profile
文件,则可以编辑~/.profile
文件或者新建一个
方法四:vim /etc/profile
该方法修改系统配置,需要管理员权限或者对该文件的写入权限,和vim /etc/bashrc
类似:
# 如果/etc/profile文件不可编辑,需要修改为可编辑
chmod -v u+w /etc/profile
vim /etc/profile
# 在最后一行加上
export PATH=$PATH:/home/uusama/mysql/bin
注意事项:
- 生效时间:新开终端生效,或者手动
source /etc/profile
生效 - 生效期限:永久有效
- 生效范围:对所有用户有效
方法五:vim /etc/environment
该方法是修改系统环境配置文件,需要管理员权限或者对该文件的写入权限:
# 如果/etc/environment,需要修改为可编辑
chmod -v u+w /etc/environment
vim /etc/environment
# 在最后一行加上
export PATH=$PATH:/home/uusama/mysql/bin
注意事项:
- 生效时间:新开终端生效,或者手动
source /etc/environment
生效 - 生效期限:永久有效
- 生效范围:对所有用户有效
环境变量加载原理解析
那么Linux是如何加载这些配置的呢?是以什么样的顺序加载的呢?
特定的加载顺序会导致相同名称的环境变量定义被覆盖或者不生效。
环境变量可以简单的分成用户自定义的环境变量以及系统级别的环境变量。
- 用户级别环境变量定义文件:
~/.bashrc
、~/.profile
(部分系统为:~/.bash_profile
) - 系统级别环境变量定义文件:
/etc/bashrc
、/etc/profile
(部分系统为:/etc/bash_profile
)、/etc/environment
另外在用户环境变量中,系统会首先读取~/.bash_profile
(或者~/.profile
)文件,如果没有该文件则读取~/.bash_login
,根据这些文件中内容再去读取~/.bashrc
。
系统环境变量 -> 用户自定义环境变量
/etc/environment
-> /etc/profile
-> ~/.profile
可以自定义一个环境变量文件,比如在某个项目下定义uusama.profile
,在这个文件中使用export
定义一系列变量,然后在~/.profile
文件后面加上:sourc uusama.profile
,这样你每次登陆都可以在Shell脚本中使用自己定义的一系列变量。
也可以使用alias
命令定义一些命令的别名,比如alias rm="rm -i"
(双引号必须),并把这个代码加入到~/.profile
中,这样你每次使用rm
命令的时候,都相当于使用rm -i
命令,非常方便。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY