linux基础知识-20

Posted 老陌的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux基础知识-20相关的知识,希望对你有一定的参考价值。

一、命令行替换

(一)历史替换

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

(二)大括号替换

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

linux@myccloves:~$ pwd
/home/linux
linux@myccloves:~$ mkdir /home/linux/test/winc /home/linux/test/wind /home/linux/test/wine
linux@myccloves:~$ ls -l /home/linux/test
total 12
drwxr-xr-x 2 linux linux 4096 Jul 20 15:30 winc
drwxr-xr-x 2 linux linux 4096 Jul 20 15:30 wind
drwxr-xr-x 2 linux linux 4096 Jul 20 15:30 wine

我们用mkdir一次性创建了三个文件,但每个文件都写绝对路径很麻烦,可以先进入目录再创建

linux@myccloves:~$ cd /home/linux/test
linux@myccloves:~/test$ mkdir winc wind wine

实际还有更简单的方法:

linux@myccloves:~/test$ mkdir win{a,b,c}
linux@myccloves:~/test$ ls
wina  winb  winc

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

mkdir -p user{1,2,3}/{images,music,video}

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

(三)代字号替换

这个我们接触过,~表示当前用户主目录, ~username,这表示指定用户的主目录。

linux@myccloves:~$ ls ~
Desktop    Downloads  Music     test    VirtualBox VMs
Documents  exercises  Pictures  Videos  模板
linux@myccloves:~$ ls ~alice
Desktop  Documents  Downloads  Music  Pictures  Videos  模板
linux@myccloves:~$ 

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

(四)变量替换

这个我们前面学过:

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

(五)算术替换

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

linux@myccloves:~$ a=3
linux@myccloves:~$ b=4
linux@myccloves:~$ echo $a+$b
3+4

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

linux@myccloves:~$ a=100
linux@myccloves:~$ b=200
linux@myccloves:~$ echo $((a+b))
300

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

linux@myccloves:~$ echo $((30*1024))
30720

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

(六)命令替换

直接上实例,通过实例说明问题:

linux@myccloves:~/test$ date +%Y%m%d
20180720

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

linux@myccloves:~/test$ mkdir date +%Y%m%d
linux@myccloves:~/test$ ls -l
total 8
drwxr-xr-x 2 linux linux 4096 Jul 20 18:16 date
drwxr-xr-x 2 linux linux 4096 Jul 20 18:16 +%Y%m%d

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

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

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

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

总结:在一行命令中,要用到另一行命令的结果,就要把那条命令放到:

  • `... `
  • $(...)

(七)路径名替换

这个我们之前接触过

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

二、引用和转义字符

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

  • 转义
  • 双引号
  • 单击号

首先我们看一下转义:

linux@myccloves:~/test$ mkdir <a>
bash: syntax error near unexpected token `newline\'
linux@myccloves:~/test$ mkdir \\<a\\>
linux@myccloves:~/test$ ls -l
total 4
drwxr-xr-x 2 linux linux 4096 Jul 20 19:51 <a>
linux@myccloves:~/test$ 

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

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

linux@myccloves:~/test$ mkdir "<a>"
linux@myccloves:~/test$ mkdir "`date +%Y%m%d`"
linux@myccloves:~/test$ ls -l
total 8
drwxr-xr-x 2 linux linux 4096 Jul 20 19:55 20180720
drwxr-xr-x 2 linux linux 4096 Jul 20 19:54 <a>

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

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

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

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

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

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

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

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

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

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

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

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

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

linux@myccloves:~$ cd test
linux@myccloves:~/test$ echo "echo hello" > start
linux@myccloves:~/test$ chmod +x start
linux@myccloves:~/test$ *
bash: start: command not found
linux@myccloves:~/test$ PATH=$PATH:$PWD
linux@myccloves:~/test$ *
hello

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

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

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

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

以上是关于linux基础知识-20的主要内容,如果未能解决你的问题,请参考以下文章

20155201 李卓雯 《网络对抗技术》实验一 逆向及Bof基础

逆向及Bof基础实践

1 代码片段1

[linux][c/c++]代码片段01

PTA乙级 (1049 数列的片段和 (20分))

20155307刘浩《网络对抗》逆向及Bof基础