输入输出重定向
输入重定向是指把文件导入到命令中,而输出重定向则是把原本要输出到屏幕的数据系信息写入到指定文件中。输出重定向分为标准输出重定向和错误输出重定向两种不同的技术,以及清空写入与追加写入两种模式。
☆标准输入重定向(STDIN,文件描述符为0):默认从键盘输入,也可从其他文件或命令中输入。
☆标准输出重定向(STDOUT,文件描述符为1):默认输出到屏幕
☆错误输出重定向(STDERR,文件描述符为2):默认输出到屏幕。
对于输入重定向来讲,用到的符号及其作用如表:
符号 | 作用 |
---|---|
命令 < 文件 | 将文件作为命令的标准输入 |
命令 << 分解符 | 从标准输入中读入,知道御剑分解符才停止 |
命令 < 文件1 > 文件2 | 将文件1作为命令的标准输入并将标准输出到文件2 |
对于输出重定向来讲,用到的符号及其作用如下:
符号 | 作用 |
---|---|
命令 > 文件 | 将标准输出重定向到一个文件中(清空原有文件的数据) |
命令 2> 文件 | 将错误输出重定向到一个文件中(清空原有文件数据) |
命令 >> 文件 | 将标准输出重定向到一个文件中(追加到原有内容的后面) |
命令 >> 文件 >2>&1 或命令 &>> 文件 | 将标准输出与错误输出共同写入到文件中(追加到原有内容的后面) |
对于重定向中的标准输出模式,可以省略文件描述符1不写,而错误输出模式的文件描述符2是必须写的。
例子1:[root@test2 opt]# ifconfig > 123
[root@test2 opt]# cat 123
eno16777728: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.124 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::20c:29ff:fe69:3fde prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:69:3f:de txqueuelen 1000 (Ethernet)
RX packets 400321 bytes 52572415 (50.1 MiB)
RX errors 0 dropped 186672 overruns 0 frame 0
TX packets 128573 bytes 33586950 (32.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 82 bytes 6750 (6.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 82 bytes 6750 (6.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
例子2:[root@test2 opt]# echo hello pig > 123
[root@test2 opt]# cat 123
hello pig
使用标准输出将原本要输出到屏幕的信息写到的文件中,而错误的输出重定向则依然把信息输出到屏幕上
例子3:[root@test2 opt]# ls -l a
-rw-r--r--. 1 root root 67 Jul 6 09:48 a
[root@test2 opt]# ls -l a > /opt/a
[root@test2 opt]# ls -l a 2> /opt/a
-rw-r--r--. 1 root root 0 Jul 6 10:14 a
abc是不存在的文件,将错误信息写入到123文件中
例子4:[root@test2 opt]# ls -l abc 2> 123
[root@test2 opt]# cat 123
ls: cannot access abc: No such file or directory
管道命令符
管道符格式为 A命令|B命令,也可以是A|命令|B命令|C|命令|D命令。管道符的作用:把前一个命令原本要输出到屏幕的标准正常数据当做是后一个命令的标准输入。
☆找出被限制的登录用户的命令是grep “/sbin/nologin” /etc/passwd;
☆统计文本行数的命令是wc -l
例子1:[root@test2 tmp]# grep "/sbin/nologin" /etc/passwd |wc -l
33
例子2:[root@test2 tmp]# ls -l /etc/ |more
total 1396
drwxr-xr-x. 3 root root 97 Jul 2 23:18 abrt
-rw-r--r--. 1 root root 16 Jul 2 23:24 adjtime
-rw-r--r--. 1 root root 1518 Jun 7 2013 aliases
-rw-r--r--. 1 root root 12288 Jul 2 15:52 aliases.db
drwxr-xr-x. 2 root root 49 Jul 2 23:18 alsa
drwxr-xr-x. 2 root root 4096 Jul 2 23:20 alternatives
-rw-------. 1 root root 541 Jan 28 2014 anacrontab
-rw-r--r--. 1 root root 55 Jan 29 2014 asound.conf
-rw-r--r--. 1 root root 1 Jan 29 2014 at.deny
drwxr-xr-x. 2 root root 31 Jul 2 23:19 at-spi2
drwxr-x---. 3 root root 41 Jul 2 23:18 audisp
drwxr-x---. 3 root root 79 Jul 2 23:52 audit
drwxr-xr-x. 4 root root 94 Jul 2 23:18 avahi
drwxr-xr-x. 2 root root 4096 Jul 2 23:21 bash_completion.d
-rw-r--r--. 1 root root 2835 Mar 13 2014 bashrc
drwxr-xr-x. 2 root root 6 Apr 2 2014 binfmt.d
drwxr-xr-x. 2 root root 39 Jul 2 23:19 bluetooth
drwxr-xr-x. 2 root root 41 Jul 2 23:16 bonobo-activation
drwxr-xr-x. 2 root root 12288 Jul 2 23:18 brltty
-rw-r--r--. 1 root root 21929 Jan 29 2014 brltty.conf
drwxr-xr-x. 2 root root 6 Jan 29 2014 chkconfig.d
-rw-r--r--. 1 root root 1157 Feb 6 2014 chrony.conf
在修改用户密码时,通常要输入2次进行确认,如果编写自动化脚本将成为一个非常致命的缺陷。但通过管道符和passwd命令的–stdin参数相结合,就可以用一条命令来完成密码重置。
例子3:[root@test2 tmp]# echo "poscard" |passwd --stdin root
Changing password for user root.
passwd: all authentication tokens updated successfully.
比如,在发送电子邮件时,默认采用交互方式来进行,完全可以用一条结合了管道符的命令语句,把编辑好的的内容与标题一起“打包”,最终用一条命令实现邮件发送。
例子4:[root@test2 tmp]# echo "这是一条邮件" |mail -s "测试" root
[root@test2 tmp]# mail
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/root": 2 messages 1 new
1 user@localhost.local Fri Jul 3 17:12 305/11030 "[abrt] full crash report"
>N 2 root Mon Jul 6 11:16 18/602 "测试"
&
& 2
Message 2:
From root@test2.localdomain Mon Jul 6 11:16:59 2020
Return-Path: <root@test2.localdomain>
X-Original-To: root
Delivered-To: root@test2.localdomain
Date: Mon, 06 Jul 2020 11:16:59 +0800
To: root@test2.localdomain
Subject: 测试
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=utf-8
From: root@test2.localdomain (root)
Status: R
这是一条邮件
&
下面这条自造命令就结合使用了mail邮件命令与输入重定向的分解符,其目的是让用户一直输入内容,直到用户输入了其自定义的分解符时,才结束输入。
例子4:[root@test2 tmp]# mail -s "测试输入重定向内容" root@test2 << end
> 第一条内容
> 第二条内容
> 赵红霞is pig
> 可以结束测试了
> 准备输入end
> end
[root@test2 tmp]# mail
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/root": 3 messages 1 new
1 user@localhost.local Fri Jul 3 17:12 305/11030 "[abrt] full crash report"
2 root Mon Jul 6 11:16 19/613 "测试"
>N 3 root Mon Jul 6 11:29 22/703 "测试输入重定向内容"
& 3
Message 3:
From root@test2.localdomain Mon Jul 6 11:29:45 2020
Return-Path: <root@test2.localdomain>
X-Original-To: root@test2
Delivered-To: root@test2.localdomain
Date: Mon, 06 Jul 2020 11:29:45 +0800
To: root@test2.localdomain
Subject: 测试输入重定向内容
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=utf-8
From: root@test2.localdomain (root)
Status: R
第一条内容
第二条内容
赵红霞is pig
可以结束测试了
准备输入end
&
命令行通配符
通配符就是通用的匹配信息的符号,比如型号(*)代表匹配零个或多个字符,问号(?)代表单个字符,中括号内加上数组[0-9] 代表匹配0-9之间的单个数字的字符,而中括号内加上字母[abc] 则是代表匹配a、b、c三个字符中的任意一个字符。
例子:[root@test2 tmp]# ls -l /dev/sda*
brw-rw----. 1 root disk 8, 0 Jul 3 17:10 /dev/sda
brw-rw----. 1 root disk 8, 1 Jul 3 09:22 /dev/sda1
brw-rw----. 1 root disk 8, 2 Jul 3 09:22 /dev/sda2
[root@test2 tmp]# ls -l /dev/sda?
brw-rw----. 1 root disk 8, 1 Jul 3 09:22 /dev/sda1
brw-rw----. 1 root disk 8, 2 Jul 3 09:22 /dev/sda2
[root@test2 tmp]# ls -l /dev/sda[0-9]
brw-rw----. 1 root disk 8, 1 Jul 3 09:22 /dev/sda1
brw-rw----. 1 root disk 8, 2 Jul 3 09:22 /dev/sda2
[root@test2 tmp]# ls -l /dev/sda[126]
brw-rw----. 1 root disk 8, 1 Jul 3 09:22 /dev/sda1
brw-rw----. 1 root disk 8, 2 Jul 3 09:22 /dev/sda2
[root@test2 tmp]#
常用的转义字符
4个常用转义字符如下所示:
☆反斜杠(\):使反斜杠后面的一个变量变为单纯的字符串
☆单引号(’’):转义其中所有的变量为单纯的字符串
☆双引号(""):保留其中的变量属性,不进行转义处理。
☆反引号(``):把其中的命令执行后返回结果
例子1:先定义一个名为PRICE的变量并赋值为5,然后输出以双引号括起来的字符串与变量信息:
[root@test2 tmp]# PRICE=5
[root@test2 tmp]# echo "Price is $PRICE"
Price is 5
[root@test2 tmp]#
接下来,我们希望能够输出“Price is 5 ” , 即 价 格 是 5 没 有 的 字 符 串 内 容 , 但 美 元 符 号 与 变 量 提 取 符 号 合 并 后 的 5” ,即价格是5没有的字符串内容,但美元符号与变量提取符号合并后的 5”,即价格是5没有的字符串内容,但美元符号与变量提取符号合并后的$作用是显示当前程序的进程ID号码,浴室命令执行后的输出内容并不是所预期的:
[root@test2 tmp]# echo "Price is $$PRICE"
Price is 52592PRICE
[root@test2 tmp]#
要想让第一个“$”乖乖的作为美元符号,那么就需要反斜杠来进行转义,将这个命苦提取符转义成单纯的文本,去除其特殊功能。
[root@test2 tmp]# echo "Price is \$$PRICE"
Price is $5
[root@test2 tmp]#
而如果只需要某个命令的输出值时,可以向命令
这样,将命令用反引号括起来,达到预期的效果。例如,将反引号与uname -a 命令结合,然后使用echo命令来查看本机的Linux版本和内核信息:
[root@test2 tmp]# echo `uname -a`
Linux test2 3.10.0-123.el7.x86_64 #1 SMP Mon May 5 11:16:57 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux
环境变量
变量是计算机系统用于保存可变值的数据类型。在Linux系统中,变量名称一般都是大写的。我们可以直接通过变量名提取到对应的变量值。Linux系统中的环境变量是用来定义系统运行环境的一些参数,比如每个用户不同的家目录,应用安装存放位置等。
在Linux系统中一切都是文件,Linux命令也不例外。在用户执行了一条命令之后,系统中到底发生了什么事情呢?简单来说,命令在Linux系统中执行分为4个步骤。
☆第1步:判断用户是否以绝对路径或相对路径的方式输入命令,如果是的话则执行。
☆第2步:Linux系统检查用户输入的命令是否为“别名命令”,即用一个自定义的命令名称来替换原本的命令名称。泳衣用alias命令来创建一个属于自己的命令别名,格式为“alias 别名=命令”。若要取消一个命令别名,则是用unalias命令,格式为“unalias 别名”。
例子:之前使用rm删除文件时,系统会要求再次确认,接下来我们把它再次确认取消掉:
[root@test2 tmp]# cd /opt/
[root@test2 opt]# ls
123 a rh
[root@test2 opt]# alias rm
alias rm='rm -i'
[root@test2 opt]# unalias rm
[root@test2 opt]# rm 123
[root@test2 opt]# ls
a rh
[root@test2 opt]#
☆第3步:Bash解释器判断用户输入的是内部命令还是外部命令。内部命令是解释器内部的指令,会被直接执行;而用户在绝大部分时间输入的是外部命令,这些命令交由步骤4继续处理。可以使用“type 命令名称”来判断用户输入的命令是内部命令还是外部命令。
☆第4步:系统在多个路径中查找用户输入的命令文件,而定义这些路径的变量叫做PATH,可以简单把它理解成“解释器的小助手”,作用是告诉Bash解释器待执行的命令可能存放的位置,然后Bash解释器就会乖乖的在这些位置逐个查找。PATH是有多个路径值组成的变量,每个路径值之间用冒号间隔,对这些路径增加和删除操作将影响到Bash解释器对Linux命令的查找。
[root@test2 opt]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@test2 opt]# PATH=$PATH:/root/bin
[root@test2 opt]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
[root@test2 opt]#
Linux系统中最重要的10个环境变量
变量名称 | 作用 |
---|---|
HOME | 用户的主目录(家目录) |
SHELL | 用户在使用的Shell解释器名称 |
HISTSIZE | 输出的历史命令记录条数 |
HISTFILESIZE | 保存的历史命令记录条数 |
邮件保存路径 | |
LANG | 系统语言、语系名称 |
RANDOM | 生成一个随机数字 |
PS1 | Bash解释器的提示符 |
PATH | 定义解释器搜索用户执行命令的路径 |
EDITOR | 用户默认的文本编辑器 |
Liunx作为一个多用户多任务的操作系统,能够为每个用户提供独立的、合适的工作运行环境,因此一个相同的变量在不同的用户身份下都有哪些值:
[root@test2 opt]# echo $HOME
/root
[root@test2 opt]# su poscard
[poscard@test2 opt]$ echo $HOME
/home/poscard
[poscard@test2 opt]$
其实变量是由固定的变量名与用户或系统设置的变量值两部分组成的,我们完全可以自行创建变量,来满足工作需求。例如设置一个为WORKDIR的变量,方便用户更轻松进入一个层次较深的目录:
[root@test2 opt]# mkdir /home/workdir
[root@test2 opt]# WORKDIR=/home/workdir
[root@test2 ~]# cd $WORKDIR
[root@test2 workdir]# pwd
/home/workdir
可以使用export命令将其提升为全局变量,这样其他用户也就可以使用它了。
[root@test2 workdir]# export WORKDIR
[root@test2 workdir]# cd $WORKDIR..
[root@test2 workdir]# pwd
/home/workdir
[root@test2 workdir]#