linux基础知识-20
Tofloor
poster avatar
老陌
deepin
2018-07-21 16:16
Author
参见老陌博客:https://www.cnblogs.com/myccloves/p/9345444.html

一、命令行替换

(一)历史替换
之前我们学习过!!表示执行前一条命令,这是一种替换。

(二)大括号替换
不太容易表达,直接上例子。 比如:我们想要创建winc, wind, wine目录,用于挂载C盘,D盘,E盘。

  1. linux@myccloves:~$ pwd
  2. /home/linux
  3. linux@myccloves:~$ mkdir /home/linux/test/winc /home/linux/test/wind /home/linux/test/wine
  4. linux@myccloves:~$ ls -l /home/linux/test
  5. total 12
  6. drwxr-xr-x 2 linux linux 4096 Jul 20 15:30 winc
  7. drwxr-xr-x 2 linux linux 4096 Jul 20 15:30 wind
  8. drwxr-xr-x 2 linux linux 4096 Jul 20 15:30 wine
Copy the Code

我们用mkdir一次性创建了三个文件,但每个文件都写绝对路径很麻烦,可以先进入目录再创建
  1. linux@myccloves:~$ cd /home/linux/test
  2. linux@myccloves:~/test$ mkdir winc wind wine
Copy the Code

实际还有更简单的方法:

  1. linux@myccloves:~/test$ mkdir win{a,b,c}
  2. linux@myccloves:~/test$ ls
  3. wina  winb  winc
Copy the Code

这就是大括号替换,win{a,b,c}分解成: wina, winb, winc。 我们来玩一个更酷的:

  1. mkdir -p user{1,2,3}/{images,music,video}
Copy the Code


这对于批量创建有共同特征的目录很方便。

(三)代字号替换
这个我们接触过,~表示当前用户主目录, ~username,这表示指定用户的主目录。

  1. linux@myccloves:~$ ls ~
  2. Desktop    Downloads  Music     test    VirtualBox VMs
  3. Documents  exercises  Pictures  Videos  模板
  4. linux@myccloves:~$ ls ~alice
  5. Desktop  Documents  Downloads  Music  Pictures  Videos  模板
  6. linux@myccloves:~$
Copy the Code

第一行命令查看当前用户主目录,第二行命令查看alice用户的主目录。

(四)变量替换
这个我们前面学过:

  • $变量名
  • ${变量名}


(五)算术替换
我们正常在命令写的数字,+,-, *, / (加,减,乘,除)都看成字符,没有任何数学意义。比如:

  1. linux@myccloves:~$ a=3
  2. linux@myccloves:~$ b=4
  3. linux@myccloves:~$ echo $a+$b
  4. 3+4
Copy the Code

但可以把他们放到$((...))里,这样就当成数学运算表达式了。

  1. linux@myccloves:~$ a=100
  2. linux@myccloves:~$ b=200
  3. linux@myccloves:~$ echo $((a+b))
  4. 300
Copy the Code

在分区时,我们需要计算分区的大小为多少M,比如:您想计算30G分区等于多少M,可以这样:

  1. linux@myccloves:~$ echo $((30*1024))
  2. 30720
Copy the Code

对于加,减,乘,除都支持,但不支持小数。看来还不是专业搞数学计算的。 重要的事情再说一次: 只支持整数运算,并且小数中不能整除的只保留整数位。

(六)命令替换
直接上实例,通过实例说明问题:

  1. linux@myccloves:~/test$ date +%Y%m%d
  2. 20180720
Copy the Code

我们发现 date命令输出了20180720,现在我想创建一个目录就是以当前时间为目录名。

  1. linux@myccloves:~/test$ mkdir date +%Y%m%d
  2. linux@myccloves:~/test$ ls -l
  3. total 8
  4. drwxr-xr-x 2 linux linux 4096 Jul 20 18:16 date
  5. drwxr-xr-x 2 linux linux 4096 Jul 20 18:16 +%Y%m%d
Copy the Code

发现和自己的想法不一样,原想要实现以后面的命令生成的日期为目录名,但现在shell把后面的命令当成字符串了。

  1. linux@myccloves:~/test$ mkdir `date +%Y%m%d`
  2. linux@myccloves:~/test$ ls -l
  3. total 4
  4. drwxr-xr-x 2 linux linux 4096 Jul 20 18:18 20180720
Copy the Code

修改一下,把命令放到反引号里,此时反引号里的字符被当成命令用了,也就是用命令结果进行替换,发现成功了。还有一种方法与算术运算方法类似,但只是一层括号,用$(命令...)实现。

  1. linux@myccloves:~/test$ mkdir $(date +%Y%m%d)
  2. linux@myccloves:~/test$ ls -l
  3. total 4
  4. drwxr-xr-x 2 linux linux 4096 Jul 20 18:29 20180720
Copy the Code

总结:在一行命令中,要用到另一行命令的结果,就要把那条命令放到:
  • `... `
  • $(...)


(七)路径名替换
这个我们之前接触过

  • * 表示0个或更多个字符
  • ? 表示一个字符
  • [...] 表示括号中的一个字符
  • [^...] 表示不在括号中的字符


二、引用和转义字符

有些字符是shell用的,比如:分号,$,引号等。 bash shell有三种方法避免字符被shell解释:
  • 转义
  • 双引号
  • 单击号


首先我们看一下转义:


要创建目录
,但我们知道 < 和 > 是重定向运算符,执行的时候被解释为重定向。为了不让shell解释为重定向,而只是做为普通字符,需要在前面加上  进行转义。 如: <, >,这样shell不会当成重定向运算符了。

我们也可以用双引号括起来,在双引号中除了$,!,`  会被shell解释,其它的都当普通字符对待:

我们会发现把
放到双引号里,不会被解释为重定向了,但对于反引号中的命令在双引号中仍然被shell解释,进行了一个命令替换。

最后是单引号,单引号中的字符都被看成普通字符。

  1. linux@myccloves:~/test$ mkdir '`date +%Y%m%d`'
  2. linux@myccloves:~/test$ ls -l
  3. total 4
  4. drwxr-xr-x 2 linux linux 4096 Jul 20 19:58 `date +%Y%m%d`
Copy the Code

所以要原样引用,需要用单引号。

shell的替换是在命令执行之前发生的。如果一个命令的参数有命令替换就要小心了,比如:

  1. root@myccloves:~/test# find /etc/ -name *.conf | head -2
  2. /etc/gnome-vfs-2.0/modules/default-modules.conf
  3. /etc/xdg/user-dirs.conf
Copy the Code

这个命令参数有一个*.conf的命令替换,但当前test目录下啥也没有,所以没有发生替换,直接把*.conf传递给find命令。

  1. root@myccloves:~/test# touch a.conf
  2. root@myccloves:~/test# find /etc/ -name *.conf | head -2
Copy the Code

再次运行发现相同的命令和刚才运行的结果不同,这就是说先进行替换了,那么替换后的结果是什么呢?

  1. root@myccloves:~/test# find /etc/ -name a.conf | head -2
Copy the Code

首先把*.conf替换成a.conf,因为在当前目录里有a.conf符合*.conf的替换规则。 由于/etc/里没有查到a.conf,所以啥也不显示。为了避免这种情况,我们应该把*.conf放到字符串里,防止命令替换的发生。因为"*.conf"是做为参数传递给find命令的。
以后用find命令要小心了,最好对搜索条件都用""号括上,这样会安全些。

我们来做一个有趣的实验:

因为老陌头一回了解这个细节,所以做一个实验加深理解。

  1. linux@myccloves:~$ cd test
  2. linux@myccloves:~/test$ echo "echo hello" > start
  3. linux@myccloves:~/test$ chmod +x start
  4. linux@myccloves:~/test$ *
  5. bash: start: command not found
  6. linux@myccloves:~/test$ PATH=$PATH:$PWD
  7. linux@myccloves:~/test$ *
  8. hello
Copy the Code

首先进入test目录做实验, 做实验的时候我们新创建一个目录,在里面做是很安全的,防止破坏外面的目录结构或误操作带来的隐患。

之后把 echo hello的字符串写到start文件中,那么就是说test目录中有一个文件start,而start中的内容是echo hello。 之后添加执行权限。

输入* 结果提示start命令没有找到, 通过之前学的,一定是*替换成了start。我们知道shell要执行的程序会在PATH中搜索,但start没有PATH路径中,所以我们要把当前目录加入到PATH中。

通过$PWD的方式,把当前目录加入到PATH环境变量中,之后执行* ,这回显示hello了。 如果没学这个知识点之前,以为发生幽灵事变了,一个*对你说hello……



Reply Favorite View the author
All Replies
avatar
Guumi
deepin
2018-07-21 17:26
#1
学习了,谢谢LZ
Reply View the author
avatar
老陌
deepin
2018-07-22 06:01
#2

共同进步。
Reply View the author