|
逸学已用学习网-免责声明
【逸学已用学习网】保证站内提供的所有可下载资源(软件等等)都是按照“原样”提供,并未对其做过任何改动。但【逸学已用学习网】不保证本站提供的下载资源的准确性、安全性和完整性。同时,【逸学已用学习网】也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。
 | |  |  | 本帖最后由 xiaoqiu 于 2020-10-17 18:50 编辑
目录
一、输入输出重定向
二、管道命令符
三、命令行的通配符
四、常用的转义字符
五、重要的环境变量
章节概述:
到目前为止,我们前面已经学习了数十个常用的Linux系统命令,如果不能把这些命令进行组合使用,则无法提升工作效率。
我们来讲解与文件读写操作有关的重定向技术的五种模式,分别为:标准覆盖输出重定向、标准追加输出重定向、错误覆盖输出重定向、错误追加输出重定向以及输入重定向,通过实验切实理解每个重定向模式的作用,解决输出信息的保存问题。
随后深入讲解管道命令符,掌握命令之间的搭配使用方法,进一步提高命令输出值的处理效率。通过讲解Linux系统命令行中的通配符和常见转义符,让您输入的Linux命令具有更准确的意义,为接下来学习编写Shell脚本打好功底。
最后,深度剖析了Bash解释器执行Linux命令的内部原理,为掌握PATH变量及Linux系统中的重要环境变量打下了基础。
一、输入输出重定向
我们在上一章学完了几乎所有基础且常用的Linux命令,所以接下来的任务就是把多个Linux命令适当的组合到一起,使其协同工作,以便我们更加高效地处理数据。要做到这一点,就必须搞明白命令的输入重定向和输出重定向的原理。
输入重定向是指把文件导入到命令中,而输出重定向是指把原本要输出到屏幕的数据信息写入到指定文件中。在日常的学习和工作中,我们使用输出重定向的频率更高,所以又将输出重定向分为了标准输出重定向和错误输出重定向两种不同的技术,以及清空写入与追加写入两种模式。
标准输入重定向(STDIN,文件描述符为0):默认从键盘输入,也可从其他文件或命令中输入。
标准输出重定向(STDOUT,文件描述符为1):默认输出到屏幕。
错误输出重定向(STDERR,文件描述符为2):默认输出到屏幕。
比如我们分别查看两个文件的属性信息,先创建出第一个文件,而第二个文件是不存在的。所以针对这两个文件的操作都分别会在屏幕上输出一些信息,但这两个操作的差异其实很大:
[root@localhost ~]# touch linuxqiu
(tuoch=新建 linuxqiu=目录 简单说明就是使用tuoch命令新建一个linuxqiu目录)
[root@localhost ~]# ls -l linuxqiu
-rw-r--r--. 1 root root 0 Oct 20 10:30 linuxqiu
(命令的意思是查看前面新建的linuxqiu目录信息【文件名称是存在的,所以显示正常信息】)
[root@localhost ~]#
[root@localhost ~]# ls -l linux
ls: cannot access 'linux': No such file or directory
(命令的意思是使用ls -l命令查看linux目录信息,但是这个linux目录不存在,所以报错【文件名称是不存在的,所以显示报错】)
[root@localhost ~]#
在上面的命令中,名为linuxqiu的文件是真实存在的,输出信息是该文件的一些相关权限、所有者、所属组、文件大小及修改时间等信息,这也是该命令的标准输出信息。而名为linux的第二个文件是不存在的,因此在执行完ls命令之后显示的报错提示信息也是该命令的错误输出信息。那么,要想把原本输出到屏幕上的数据转而写入到文件当中,就要区别对待这两种输出信息。
(重定向符:它实际上是将我们的命令,跟我们的文件结合到一起,要么就是把命令输出的结果输出到一个文件里面,要么就是文件输入到命令)
输入重定向,相关参数及其作用表
输入重定向:就是将一个文件输入到一个命令里面(这个比较少见)
符号 | 作用 | 命令 < 文件(小于号) | 将文件作为命令的标准输入 | 命令 << 分界符 | 从标准输入中读入,直到遇见分界符才停止 | 命令 < 文件1 > 文件2 | 将文件1作为命令的标准输入并将标准输出到文件2 |
输出重定向,相关参数及其作用表
输出重定向:是将命令输出的结果,输出到一个文件里
符号 | 作用 | 命令 > 文件(大于号) | 将标准输出重定向到一个文件中(清空原有文件里面的内容) | 命令 2> 文件 | 将错误输出重定向到一个文件中(清空原有文件的数据) | 命令 >> 文件 | 将标准输出重定向到一个文件中(追加内容到原有内容的后面) | 命令 2>> 文件 | 将错误输出重定向到一个文件中(追加到原有内容的后面) | 命令 >> 文件 2>&1
或
命令 &>> 文件 | 将标准输出与错误输出共同写入到文件中(追加到原有内容的后面) |
输出重定向(清空型写入内容到Linuxqiu文件):
如图,我们敲uptime命令可以看到系统负载信息的内容。但是如果我想将负载信息的内容输出到linuxqiu文件中,应该怎么操作呢?命令敲uptime > linuxqiu就可以将uptime的负载信息输出到linuxqiu文件中了。
如果我们敲四遍uptime > linuxqiu,它还是只有一条负载信息,这就是所说的清空写入(清空原有的数据,写入新的数据)。
[root@localhost ~]# uptime (敲命令可以直接看到负载信息)
19:33:06 up 14 min, 1 user, load average: 0.10, 0.68, 0.63
[root@localhost ~]#
(命令输出到屏幕的负载信息,我们将它输出到linuxqiu文件中,这就是所说的输出重定向)
uptime(查看负载信息的命令)>(清空写入的参数)linuxqiu(文件)(文件的作用是将uptime原本要显示到屏幕的内容,写入到文件中)
[root@localhost ~]# uptime > linuxqiu
[root@localhost ~]# uptime > linuxqiu
[root@localhost ~]# uptime > linuxqiu
[root@localhost ~]# uptime > linuxqiu
[root@localhost ~]#
cat(查看文件内容命令)linuxqiu(文件)(总结:查看Linuxqiu文件)
[root@localhost ~]# cat linuxqiu
19:33:22 up 14 min, 1 user, load average: 0.08, 0.65, 0.62
[root@localhost ~]#
输出重定向(追加型写入内容到Linuxqiu文件):
上面我们介绍了“清空型写入内容到Linuxqiu文件”是加了参数“>”。这里我们讲一下追加写入。顾名思义就是可以多写入几行内容。原文件内容还存在,这里我们需要加参数“>>”。
[root@localhost ~]# uptime >> linuxqiu
[root@localhost ~]# uptime >> linuxqiu
[root@localhost ~]# uptime >> linuxqiu
[root@localhost ~]# uptime >> linuxqiu
[root@localhost ~]#
[root@localhost ~]# cat linuxqiu
19:49:50 up 31 min, 1 user, load average: 0.00, 0.03, 0.20
19:51:03 up 32 min, 1 user, load average: 0.16, 0.10, 0.21
19:51:04 up 32 min, 1 user, load average: 0.16, 0.10, 0.21
19:51:05 up 32 min, 1 user, load average: 0.16, 0.10, 0.21
19:51:06 up 32 min, 1 user, load average: 0.15, 0.10, 0.21
[root@localhost ~]#
上面我们学会了清空写入及追加写入,这里我们教大家如何写入错误的信息,不然我们敲一个不存在的文件,它会提示错误,而这个错误它不会写入到我们的文件中,那么怎么办呢?
(ls命令是查看当前目录有哪些文件,ls -l命令可以看到当前查看当前目录文件的详细信息的,如文件权限、文件大小、文件日期等信息。具体的每一项内容解析会在“用户身份与文件权限”中讲到)
[root@localhost ~]# ls (ls命令是查看当前目录有哪些文件及目录,有颜色的是目录,没颜色的是文件)
anaconda-ks.cfg Documents initial-setup-ks.cfg Music Public Videos
Desktop Downloads linuxqiu Pictures Templates
[root@localhost ~]#
[root@localhost ~]# ls -l linuxqiu
-rw-r--r--. 1 root root 306 Oct 16 10:18 linuxqiu
(ls -l命令,简单的说就是加了-l 参数,可以看到当前目录所有文件详细信息。linuxqiu文件名称,使用敲ls -l linuxqiu会显示出这个文件的详细信息)
[root@localhost ~]#
[root@localhost ~]# ls -l linux (当前目录没有这个文件,所以会显示报错No such file or directory“没有这样的文件或目录”)
ls: cannot access 'linux': No such file or directory
上面我们可以看到linuxqiu.com目录是存在的,Linux目录是不存在的,那么我们要怎么样将错误的信息也写入到我们linuxqiu这个文件中呢。
彩蛋知识:
(Linux中新建文件命令touch 文件名)
(Linux中删除文件命令rm 文件名称。加参数-rf可以强制删除rm -rf 文件名名称)
(Linux中新建目录命令mkdir 文件名称)
(Linux中删除目录命令rmdir 文件名称)
命令:(结合前面学的命令)
[root@localhost ~]# ls
anaconda-ks.cfg Downloads linuxqiu.com Public
Desktop initial-setup-ks.cfg Music Templates
Documents linuxqiu Pictures Videos
[root@localhost ~]# ls -l linuxqiu.com >> linuxqiu
【标准输出:只能输出正确的信息,报错的信息无法输出】
[root@localhost ~]# cat linuxqiu
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
[root@localhost ~]# ls -l linuxqiu.com >> linuxqiu
[root@localhost ~]# ls -l linuxqiu.com >> linuxqiu
[root@localhost ~]#
[root@localhost ~]# cat linuxqiu
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
[root@localhost ~]#
[root@localhost ~]# ls -l linux
ls: cannot access 'linux': No such file or directory
[root@localhost ~]#
[root@localhost ~]# ls -l linux 2>> linuxqiu
【错误输出,如果加了2数字后,只能输出错误的信息】
[root@localhost ~]#
[root@localhost ~]# cat linuxqiu
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
ls: cannot access 'linux': No such file or directory
[root@localhost ~]#
上面我们知道了怎么把报错信息也输出到文件了,细心的朋友应该会发现,我们加了“2>>”参数后输出不了正确的信息到文件里,一定要将数字“2”去掉,改成“>>”才可以重新追加写入正确的信息。接下来教大家如何将“正确的信息”及“报错的信息”都写入到文件中。这里我们在将“2”改成“&”,意思就是,不管正确的信息输出,还是报错的错误信息输出,它都会输出到我们的文件中。
(注:Linux是不存在的文件,linuxqiu.com是存在的文件。linuxqiu是写入信息到这个文件。)
[root@localhost ~]# ls -l linux &>> linuxqiu
[root@localhost ~]# ls -l linux &>> linuxqiu
[root@localhost ~]# ls -l linux &>> linuxqiu
[root@localhost ~]# cat linuxqiu
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
ls: cannot access 'linux': No such file or directory
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
ls: cannot access 'linux': No such file or directory
ls: cannot access 'linux': No such file or directory
ls: cannot access 'linux': No such file or directory
[root@localhost ~]#
[root@localhost ~]# ls -l linuxqiu.com &>> linuxqiu
[root@localhost ~]# ls -l linuxqiu.com &>> linuxqiu
[root@localhost ~]# ls -l linuxqiu.com &>> linuxqiu
[root@localhost ~]# cat linuxqiu
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
ls: cannot access 'linux': No such file or directory
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
ls: cannot access 'linux': No such file or directory
ls: cannot access 'linux': No such file or directory
ls: cannot access 'linux': No such file or directory
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
-rw-r--r--. 1 root root 0 Oct 16 10:43 linuxqiu.com
[root@localhost ~]#
输入重定向:
案例1:
[root@localhost ~]# wc -l anaconda-ks.cfg
45 anaconda-ks.cfg
[root@localhost ~]#
[root@localhost ~]# wc -l < anaconda-ks.cfg
45
(第一条命令解析:wc(命令)-l(参数)anaconda-ks.cfg(对象)
(第二个命令解析:wc(命令)-l(参数)< anaconda-ks.cfg(内容导入到命令里,所以没有让命令获取到文件名称)
是不一样,第二个命令少了文件名称
案例2:
(输入重定向,当指定了 0 作为分界符之后,只要不输入 0,就可以一直输入数据)
[root@localhost ~]# cat << 0 (命令输入后回车)
> linux (可以输入内容)
> linuxqiu (还可以输入内容)
> linuxqiu.com (还可以输入内容)
> 0
linux
linuxqiu
linuxqiu.com
[root@localhost ~]#
二、管道命令符
管道命令符的作用可以用一句话来概括“把前一个命令原本要输出到屏幕的信息当作是后一个命令的标准输入”。当然大家千万不要误以为管道命令符只能在一个命令组合中使用一次,我们完全可以这样使用:“命令A | 命令B | 命令C”。
(管道符:实际上是作为我们的命令跟命令之间的纽带。命令结果通过管道符,在我们之间传输)
管道符:可以执行多次。要想让我们后面命令来接收到输出的结果,命令之间要有空格。。管道符=任意门
这个管道符就像一个法宝,我们可以将它套用到其他不同的命令上,比如用翻页的形式查看/etc目录中的文件列表及属性信息(这些内容默认会一股脑儿地显示到屏幕上,根本看不清楚):
命令解析:ls -l(查看当前目录文件)/etc/(目录文件名称)more(翻页查看文件内容的命令)
[root@linuxprobe ~]# ls -l /etc/ | more
total 1344
-rw-r--r--. 1 root root 16 Jul 21 05:08 adjtime
-rw-r--r--. 1 root root 1518 Sep 10 2018 aliases
drwxr-xr-x. 3 root root 65 Jul 21 05:06 alsa
drwxr-xr-x. 2 root root 4096 Jul 21 05:08 alternatives
-rw-r--r--. 1 root root 541 Oct 2 2018 anacrontab
-rw-r--r--. 1 root root 55 Feb 1 2019 asound.conf
-rw-r--r--. 1 root root 1 Aug 12 2018 at.deny
drwxr-x---. 4 root root 100 Jul 21 05:16 audit
drwxr-xr-x. 3 root root 228 Jul 21 05:08 authselect
drwxr-xr-x. 4 root root 71 Jul 21 05:06 avahi
drwxr-xr-x. 2 root root 204 Jul 21 05:06 bash_completion.d
-rw-r--r--. 1 root root 3001 Sep 10 2018 bashrc
--More--
在修改用户密码时,通常都需要输入两次密码进行确认才能修改完成,这在编写自动化脚本时将成为一个非常致命的缺陷(因为明明是自动化的,反而还要你按y确认,这是很不好的)。这时候我们可以通过管道符和passwd命令的--stdin参数相结合,可以用一条命令来完成密码重置操作:
(这种方式虽然简单,但是通过history命令可以查到用户的密码,所以不安全。)
第一种方法:使用passwd命令修改密码,需要输入两次密码确认
[root@localhost ~]# passwd (命令)
Changing password for user root.
New password: (输入修改的密码)
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: (输入第二次修改的密码,也叫输入确认密码)
passwd: all authentication tokens updated successfully. (修改完成)
[root@localhost ~]#
第二种方法:通过管道符和passwd命令的--stdin参数相结合,可以用一条命令来完成密码重置操作。
解析:命令(echo) 设置密码值(linuxqiu) 通过管道符(|) 标准输入管道读入(也可以叫是通过管道符去接收用户密码的参数(passwd --stdin)用户(root)
(这种方式虽然简单,但是通过history命令可以查到用户的密码,所以不安全。)
[root@localhost ~]# echo "linuxqiu" | passwd --stdin root
Changing password for user root.
passwd: all authentication tokens updated successfully.
[root@localhost ~]#
我们前面学习ps命令的时候,输入ps aux参数后屏幕信息呼呼闪过,根本找不到有用的信息,现在也可以将ps、grep、管道符三者结合到一起使用了。搜索与bash有关的进程信息:
命令解析:
ps aux(查看应用进程情况,如bash进程、WEB进程等)
| (管道操作符“|”可以把一个命令的标准输出传送到另一个命令的标准输入中,连续的|意味着第一个命令的输出为第二个命令的输入,第二个命令的输入为第一个命令的输出,依次类推)
grep(文本搜索命令)
bash(搜索的进程)
[root@localhost ~]# ps aux | grep bash
root 971 0.0 0.1 17172 2420 ? S 23:39 0:00 /bin/bash /usr/sbin/ksmtuned
root 9470 0.0 0.2 26540 5168 pts/0 Ss 23:46 0:00 bash
root 9785 0.0 0.0 12112 1084 pts/0 S+ 23:57 0:00 grep --color=auto bash
如果是一名刚刚开始学习Linux的朋友,可能会觉得上面的命令组合已经十分复杂了,但是有过运维经验的朋友又会感觉如隔靴挠痒般不过瘾,他们希望能将这样方便的命令写得更高级一些,功能更强大一些,为了为了不负众望,当然要义不容辞的在说一种方法。假设如果需要将管道符处理后的结果即输出到屏幕,又同时写入到文件中,则可以与tee命令结合使用。
命令中,前面一半的命令,我们在上面介绍了,我们选择介绍一下后面的。
解析:tee(会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。)
linuxqiu(是我们的文件)
简单的说,就是通过tee命令,将teem命令前面的信息即输出到屏幕给我们看,也输出到我们的文件中。
t@localhost ~]# ps aux | grep bash | tee linuxqiu
root 971 0.0 0.1 17172 2420 ? S Oct16 0:00 /bin/bash /usr/sbin/ksmtuned
root 9470 0.0 0.2 26540 5168 pts/0 Ss Oct16 0:00 bash
root 10088 0.0 0.0 12112 988 pts/0 S+ 00:13 0:00 grep --color=auto bash
[root@localhost ~]#
[root@localhost ~]# cat linuxqiu (查看linuxqiu文件中是否有信息写入到文件中)
root 971 0.0 0.1 17172 2420 ? S Oct16 0:00 /bin/bash /usr/sbin/ksmtuned
root 9470 0.0 0.2 26540 5168 pts/0 Ss Oct16 0:00 bash
root 10088 0.0 0.0 12112 988 pts/0 S+ 00:13 0:00 grep --color=auto bash
[root@localhost ~]#
三、命令行的通配符
大家可能都遇到过提笔忘字的尴尬,作为Linux运维人员,我们有时候也会遇到明明一个文件的名称就在嘴边但就是想不起来的情况。如果就记得一个文件的开头几个字母,想遍历查找出所有以这个关键词开头的文件,该怎么操作呢?又假设想要批量查看所有硬盘文件的相关权限属性,一种方式是这样的:
[root@localhost ~]# ls -l /dev/sda
brw-rw----. 1 root disk 8, 0 Oct 17 20:22 /dev/sda
[root@localhost ~]# ls -l /dev/sda1
brw-rw----. 1 root disk 8, 1 Oct 17 20:22 /dev/sda1
[root@localhost ~]# ls -l /dev/sda2
brw-rw----. 1 root disk 8, 2 Oct 17 20:22 /dev/sda2
[root@localhost ~]# ls -l /dev/sda3
ls: cannot access '/dev/sda3': No such file or directory
[root@localhost ~]#
幸亏我的硬盘文件和分区只有3个,要是有几百个,估计需要花费一天的时间来忙这个事情了,所以这种方式的效率确实很低。
虽然在后面才会讲解到Linux系统的存储结构和FHS,但上面我们应该能看出一些简单规律了。比如,这些硬盘设备文件都是以sda开头并且存放到了/dev目录中,这样一来,即使我们不知道硬盘的分区编号和具体分区的个数,也可以使用通配符来搞定。
顾名思义,通配符就是通用的匹配信息的符号,比如星号(*)代表匹配零个或多个字符,问号(?)代表匹配单个字符,中括号内加上数字[0-9]代表匹配0~9之间的单个数字的字符,而中括号内加上字母[abc]则是代表匹配a、b、c三个字符中的任意一个字符。
Linux系统中的通配符及含义表:
【注:括号里面不要带空格,如[ 1,3,5 ],这样会报错】
通配符 | 含义 | * | 匹配任意字符(空值或无穷值) | ? | 匹配单个字符 | [a-z] | 匹配小写字母 | [A-Z] | 匹配大写字母 | [a,b,c] | 精准匹配字母 | [0-9]
[1,3,5]
{1,3,5}
| 匹配0-9的数字
精准匹配数字
可以精准匹配出关于1,3,5的内容(但是如果没匹配
出来的内容,它会报错说没搜索到)
| [:alpha:] | 任意字母 | [:upper:] | 任意大写字母 | [:lower:] | 任意小写字母 | [:digit:] | 所有数字 | [:alnum:] | 任意字母加数字 | [:punct:] | 标点符号 |
下面我们先来匹配所有在/dev目录中且以sda开头的文件:
我们在sda后面加个*符号,通配符(这样可以匹配到以sda开头,后面的所有硬盘文件)
[root@localhost ~]# ls -l /dev/sda*
brw-rw----. 1 root disk 8, 0 Oct 17 20:22 /dev/sda
brw-rw----. 1 root disk 8, 1 Oct 17 20:22 /dev/sda1
brw-rw----. 1 root disk 8, 2 Oct 17 20:22 /dev/sda2
如果只想查看文件名为sda开头,但是后面还紧跟其他某一个字符的文件的相关信息,这时就需要用到(?)问号来进行通配了:
(?问号匹配,是无法匹配到sda,因为sda后面没有数字,假设不是sda而是sda0,那么就可以匹配到了。所以说问号的意思就是说需要有一个值才能匹配到)
[root@localhost ~]# ls -l /dev/sda?
brw-rw----. 1 root disk 8, 1 Oct 17 20:22 /dev/sda1
brw-rw----. 1 root disk 8, 2 Oct 17 20:22 /dev/sda2
[root@localhost ~]#
除了使用[0-9]来匹配0-9之间的单个数字,也可以用[1,3,5]这样的方式仅匹配这三个指定数字中的一个,若没有匹配到数字1或2或3则不会显示出来,当然这里如果将{1,3,5}使用大括号,没匹配出来的会显示报错内容。
[root@localhost ~]# ls -l /dev/sda[0-9]
brw-rw----. 1 root disk 8, 1 Oct 17 20:22 /dev/sda1
brw-rw----. 1 root disk 8, 2 Oct 17 20:22 /dev/sda2
[root@localhost ~]#
[root@localhost ~]# ls -l /dev/sda[1,3,5]
brw-rw----. 1 root disk 8, 1 Oct 17 20:22 /dev/sda1
[root@localhost ~]#
[root@localhost ~]# ls -l /dev/sda{1,3,5}
ls: cannot access '/dev/sda3': No such file or directory
ls: cannot access '/dev/sda5': No such file or directory
brw-rw----. 1 root disk 8, 1 Oct 17 20:22 /dev/sda1
这里有个问题,如果我想匹配1,20,30,50,怎么匹配呢?如果使用小括号(),会乱掉,所以这里我们要使用大括号{}才可以匹配,如果没匹配到,它会提示报错,显示告知我们
[root@localhost ~]# ls -l /dev/sda[1,20,30,50] 【如果使用小括号,20被拆分成了2,0。所以就变成了1,2,0,30,50了】
brw-rw----. 1 root disk 8, 1 Oct 17 20:22 /dev/sda1
brw-rw----. 1 root disk 8, 2 Oct 17 20:22 /dev/sda2
[root@localhost ~]#
[root@localhost ~]# ls -l /dev/sda{1,20,30,50} 【所以我们这里要使用大括号,,这样才是正确的。20,30,50不存在,就提示告诉我们】
ls: cannot access '/dev/sda20': No such file or directory
ls: cannot access '/dev/sda30': No such file or directory
ls: cannot access '/dev/sda50': No such file or directory
brw-rw----. 1 root disk 8, 1 Oct 17 20:22 /dev/sda1
[root@localhost ~]#
通配符不一定非要放到最后面,也可以搜索下/etc/目录中所有以.conf结尾的配置文件有哪些:
通配符不仅可以被用于搜索文件或代替被通配的字符,还可以与创建文件的命令相结合,一口气创建出好多个文件。唯一区别是要用到大括号,并且字段之间用逗号间隔
[root@localhost ~]# touch {AA,BB,CC,DD}.conf
[root@localhost ~]#
[root@localhost ~]# ls -l *.conf
-rw-r--r--. 1 root root 0 Oct 17 20:57 AA.conf
-rw-r--r--. 1 root root 0 Oct 17 20:57 BB.conf
-rw-r--r--. 1 root root 0 Oct 17 20:57 CC.conf
-rw-r--r--. 1 root root 0 Oct 17 20:57 DD.conf
[root@localhost ~]#
再或者输出一些指定的信息,玩法特别多,接下来大家就自己开发在评论区留言哦~:
[root@localhost ~]# echo file{1,2,3,4,5,6}
file1 file2 file3 file4 file5 file6
四、常用的转义字符
为了能够更好地理解用户的表达,Shell解释器还提供了特别丰富的转义字符来处理输入的特殊数据。下面我们说一下最常用的4个转义字符!
4个最常用的转义字符如下所示。
反斜杠(\) :使反斜杠后面的一个变量变为单纯的字符。(单个字符转义)
单引号(''):转义其中所有的变量为单纯的字符串(全部字符转义)。
双引号(""):保留其中的变量属性,不进行转义处理。(定义范围)
反引号(``):把其中的命令执行后返回结果。(执行命令)
【命令放在反引号就可以执行命令,如`uptime`】
我们先定义一个名为PRICE的变量并赋值为10,然后输出以双引号括起来的字符串与变量信息:
[root@localhost ~]# PRICE=10
[root@localhost ~]#
[root@localhost ~]# echo "Price is $PRICE"
Price is 10
[root@localhost ~]#
接下来,我们希望能够输出“Price is $10”,即价格是10美元的字符串内容,但碰巧美元符号与变量提取符号合并后的$$作用是显示当前程序的进程ID号码,于是命令执行后输出的内容并不是我们所预期的:
[root@localhost ~]# echo "Price is $$PRICE"
Price is 3215PRICE
要想让第一个“$”乖乖地作为美元符号,那么就需要使用反斜杠(\)来进行转义,将这个命令提取符转义成单纯的文本,去除其特殊功能:
[root@localhost ~]# echo "Price is \$$PRICE"
Price is $10
而如果只需要某个命令的输出值时,可以像`命令`这样,将命令用反引号括起来,达到预期的效果。
例如,将反引号与uname -a命令结合,然后使用echo命令来查看本机的Linux版本和内核信息:
[root@localhost ~]# echo `uname -a`
Linux localhost.localdomain 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
反斜杠和反引号的功能比较有特点,同学们一般不会犯错,但对于什么时候使用双引号却容易混淆,因为好像大多数情况下加不加效果都一样:
[root@localhost ~]# echo AA BB CC DD
AA BB CC DD
[root@localhost ~]#
[root@localhost ~]# echo "AA BB CC DD"
AA BB CC DD
区别在于我们无法得知第一种执行方式中到底有几个参数,是的,不能确定!因为有可能把“AA BB CC DD”当作了一个参数整体直接输出到了屏幕,也有可能是分别将AA、BB、CC、DD输出到了屏幕,就算摸清了echo命令处理参数的机制,其他命令依然是这种情况。因此给大家总结一个简单小技巧,虽然可能不够严谨,但绝对简单,就是参数中如果出现了空格,那么就加双引号,如果参数中没有空格,那就不用加。
五、重要的环境变量
变量是计算机系统用于保存可变值的数据类型。在Linux系统中,变量名称一般都是大写的,命令则都是小写的,这是一种约定俗成的规范。Linux系统中的环境变量是用来定义系统运行环境的一些参数,比如每个用户不同的家目录、邮件存放位置等,可以直接通过变量名称来提取到对应的变量值。
细心的读者应该发现了,本节和上一节的标题名都分别加了形容词—重要的、常见的。原因其实不言而喻—要想让Linux系统能够正常运行并且为用户提供服务,需要数百个环境变量来协同工作,我们没有必要逐一查看、学习每一个变量,而是应该在有限的篇幅中精讲最重要的内容。
为了更好地帮助大家理解变量的作用,给大家举个例子。我们曾经讲到,在Linux系统中一切都是文件,Linux命令也不例外。那么,在用户执行了一条命令之后,Linux系统中到底发生了什么事情呢?简单来说,命令在Linux中的执行分为四个步骤。
第1步:判断用户是否以绝对路径或相对路径的方式输入命令(如/bin/ls),如果是的话则直接执行。
绝对路径:ls或/bin/ls
第2步:Linux系统检查用户输入的命令是否为“别名命令”,即用一个自定义的命令名称来替换原本的命令名称。
简单来说:我们开启网卡命令是:nmcli connection up ens160那么我们将这一串命令设置别名,比如设置成wangluo,那么我们敲wangluo就可以重新开启网卡了。这里我们使用alias命令来创建一个属于自己的命令别名,语法格式为“alias 别名=命令”,若要取消一个命令别名,则是用unalias命令,语法格式为“unalias 别名”。
(如果需要将别名永久保存,需要在vim /etc/profile文件中编辑)
命令解析:alias(别名命令)wangluo(我们设置的别名)nmcli connection up ens160(重启网卡命令)
[root@localhost ~]# alias wangluo="nmcli connection up ens160"
[root@localhost ~]#
[root@localhost ~]# wangluo (敲我们设置的别名,去开启网卡)
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)
[root@localhost ~]#
[root@localhost ~]# nmcli connection up ens160 (直接敲开启网卡的命令,去开启。)
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5)
[root@localhost ~]#
如果要取消我们设置的别名,我们可以在命令前面加un,如unalias wangluo就可以取消别名了
命令解析: unalias(取消别名命令)wangluo(取消设置好的别名名称)
总结:使用命令取消别名wangluo
[root@localhost ~]# unalias wangluo (取消别名)
[root@localhost ~]#
[root@localhost ~]# wangluo (重新敲别名,看看还能不能开启网卡,验证看到是不行的。)
bash: wangluo: command not found...
[root@localhost ~]#
如果需要看系统是否有重复的别名,可以直接敲alias查看
如图,敲了alias命令,看到了当前系统中已经做过了十几二十个左右的alias。
假如这里我没看到wanglou的别名,那么我们可以做个重启网卡的别名
如alias wangluo="nmcli connection up ens160"
单引号('')或者双引号("")没有区别,都可以使用。
设置完别名后,我们重新敲alias命令,就可以看到我们上面设置好的别名
第3步:Bash解释器判断用户输入的是内部命令还是外部命令。内部命令是解释器内部的指令,会被直接执行;而用户在绝大部分时间输入的是外部命令,这些命令交由第4步继续处理。可以使用“type 命令名称”来判断用户输入的命令是内部命令还是外部命令:
type命令:用来显示指定命令的类型,判断给出的指令是内部指令还是外部指令。
内部命令:在系统启动时就调入内存,是常驻内存的,所以执行效率高。
外部命令:是系统的软件功能,用户需要时才从硬盘中读入内存。
[root@localhost ~]# type echo
echo is a shell builtin (builtin内部命令)
[root@localhost ~]# type uptime
uptime is /usr/bin/uptime
[root@localhost ~]# type cd
cd is a shell builtin (builtin内部命令)
[root@localhost ~]# type ls (builtin内部命令)
ls is aliased to `ls --color=auto'
[root@localhost ~]# type if
if is a shell keyword (keyword内部命令)
[root@localhost ~]# type type
type is a shell builtin (builtin内部命令)
[root@localhost ~]# type fryash (找不到这个命令)
bash: type: fryash: not found (not found=没找到)
builtin 命令因为是 shell 的一部分,所以执行 builtin 命令可能会改变 shell的内部状态
Linux中所有的内置命令。
alias, bg, bind, break, builtin, caller, cd, command, compgen, complete, compopt, continue, declare, dirs, disown, echo,enable, eval, exec, exit, export, false, fc, fg, getopts, hash, help,history, jobs, kill, let, local, logout, mapfile, popd, printf, pushd,pwd, read, readonly, return, set, shift, shopt, source, suspend, test,times, trap, true, type, typeset, ulimit, umask, unalias, unset, wait
第4步:系统在多个路径中查找用户输入的命令文件,而定义这些路径的变量叫作PATH,可以简单地把它理解成是“解释器的小助手”,作用是告诉Bash解释器待执行的命令可能存放的位置,然后Bash解释器就会乖乖地在这些位置中逐个查找。PATH是由多个路径值组成的变量,每个路径值之间用冒号间隔,对这些路径的增加和删除操作将影响到Bash解释器对Linux命令的查找。
[root@localhost ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/root/bin
[root@localhost ~]#
[root@localhost ~]# PATH=$PATH:/root/bin
[root@localhost ~]#
[root@localhost ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/root/bin:/root/bin
[root@localhost ~]#
这里有比较经典的问题:“为什么不能将当前目录(.)添加到PATH中呢? ” 原因是,尽管可以将当前目录(.)添加到PATH变量中,从而在某些情况下可以让用户免去输入命令所在路径的麻烦。但是,如果黑客在比较常用的公共目录/tmp中存放了一个与ls或cd命令同名的木马文件,而用户又恰巧在公共目录中执行了这些命令,那么就极有可能中招了。
所以,作为一名态度谨慎、有经验的运维人员,在接手了一台Linux系统后一定会在执行命令前先检查PATH变量中是否有可疑的目录,另外从前面的PATH变量示例中是否也感觉到环境变量特别有用呢。我们可以使用env命令来查看到Linux系统中所有的环境变量,而下面是我们最重要的10个环境变量。
变量名称 | 作用 | HOME | 用户的主目录(即家目录) | SHELL | 用户在使用的Shell解释器名称 | HISTSIZE | 输出的历史命令记录条数 | HISTFILESIZE | 保存的历史命令记录条数 | MAIL | 邮件保存路径 | LANG | 系统语言、语系名称 | RANDOM | 生成一个随机数字 | PS1 | Bash解释器的提示符 | PATH | 定义解释器搜索用户执行命令的路径 | EDITOR | 用户默认的文本编辑器(RHEL8版本没有这个命令了) |
Linux作为一个多用户多任务的操作系统,能够为每个用户提供独立的、合适的工作运行环境,因此,一个相同的变量会因为用户身份的不同而具有不同的值。例如,使用下述命令来查看HOME变量在不同用户身份下都有哪些值
[root@linuxprobe ~]# echo $HOME (用户的主目录(即家目录,也是根目录)
/root
[root@linuxprobe ~]# su - linuxqiu (切换到linuxqiu用户)
[linuxprobe@linuxprobe ~]$ echo $HOME
/home/linuxprobe
其实变量是由固定的变量名与用户或系统设置的变量值两部分组成的,我们完全可以自行创建变量,来满足工作需求。例如设置自己定义一个名称为WORKDIR的变量,方便用户更轻松地进入一个层次较深的目录:
[root@ linuxqiu ~]# WORKDIR=/home/linuxqiu (随便给它一个值)
[root@ linuxqiu ~]# mkdir /home/linuxqiu (新建变量)
[root@ linuxqiu ~]# cd $WORKDIR (这样我们就可以进入到home/linuxqiu目录)
[root@linuxqiu linuxqiu]# pwd
/home/linuxqiu
但是,这样的变量不具有全局性,作用范围也有限,默认情况下不能被其他用户使用:
[root@linuxqiu linuxqiu]# su linuxqiu
[linuxlinuxqiu@linuxqiu ~]$ cd $WORKDIR
[linuxlinuxqiu@linuxqiu ~]$ echo $WORKDIR
[linuxlinuxqiu@linuxqiu~]$ exit
如果工作需要,可以使用export命令将其提升为全局变量,这样其他用户也就可以使用它了:
[root@linuxqiu ~]# export WORKDIR (在root管理员用户下将变量提升为全局变量,这样其它用户也可以使用它)
[root@linuxqiu ~]# su linuxqiu (切换到另一个账户)
[linuxqiu@linuxqiu ~]$ cd $WORKDIR (使用进入$WORKDIR变量)
[linuxqiu@linuxqiu linuxqiu]$ pwd (pwd命令查看是否已经进入/home/linuxqiu)
/home/linuxqiu
后续要是不用这个变量了,那么就顺手执行下unset命令取消掉它吧:
[root@linuxprobe ~]# unset WORKDIR
[root@linuxprobe ~]#
直接定义与export的区别
直接定义=自己用
(自己用意思是,比如前面建立的WORKDIR变量,切换另一个用户,它不能用这个变量)
export=所有人用
(如果想让另一个用户也可以用前面建立的WORKDIR变量,那么要敲export WORKDIR命令,这样另一个用户才可以使用)
以上这个重启是不生效的,如果需要生效,需要进入vim /etc/profile文件中,在done与unset i中间位置编辑
WORKDIR=/home/linuxqiu然后保存退出,重启生效,如果想要立即生效也可以敲命令source /etc/profilem命令去加载一下它。如果还怕它不生效怎么办呢?那么可以敲vim ~/.bashrc文件,在alias mv='mv -i'下一行输入前面的变量名称WORKDIR=/home/linuxqiu然后保存退出(保证万无一失)
最后说一下,删除文件的方法
之前在使用rm命令删除文件时,Linux系统都会要求我们再确认是否执行删除操作,其实这就是Linux系统为了防止用户误删除文件而特意设置的rm别名命令。
解析:rm(删除命令)BB.conf(文件名称)总结:删除BB.conf文件
[root@localhost ~]# rm BB.conf
rm: remove regular empty file 'BB.conf'? y
如图我们先敲了ls命令,查看当前目录有哪些文件,假设我们要删除BB.conf文件,那么敲rm BB.conf命令后,提示是否确认删除,我们敲y,就可以删除完成了。我们再次敲ls查看当前目录文件,可以看到BB.conf文件已经看不到了,说明删除完成了。
| |  | |  |
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
逸学已用学习网-免责声明
【逸学已用学习网】本站上的所有软件和资料均为软件作者提供或网友自行上传发布,仅供个人学习和研究使用,不得用于任何商业用途。如有侵犯您商标权、著作权或其他合法权利的,请联系我们,我们将在第一时间对此进行核实并处理。
|