linux命令ps aux grep,`ps aux | grep '[n]ginx'` 命令中 [] 的作用

通常情况下,我们总是会结合使用 ps 和 grep 的方式来筛选出只包含某个进程名的那些行,比如:$ ps aux | grep nginx

root 9926 0.0 0.1 23388 948 ? Ss Mar15 0:00 nginx: master process ./sbin/nginx

nobody 21964 0.0 0.3 23388 1536 ? S Mar16 0:16 nginx: worker process

nobody 21965 0.0 0.4 23388 2032 ? S Mar16 0:14 nginx: worker process

nobody 21966 0.0 0.4 23716 2192 ? S Mar16 0:16 nginx: worker process

root 29249 0.0 0.1 11744 920 pts/0 S+ 23:15 0:00 grep --color=auto nginx

结果是出来了,但你有没有注意到最后多出了一行?那是什么?那其实就是我们的 grep 命令本身的命令行。 因为它的命令行中也包含了被筛选的内容(nginx),所以自然也会被包含进来。

所以怎么去掉?先说答案,像下面这样即可:$ ps aux | grep '[n]ginx'

root 9926 0.0 0.1 23388 948 ? Ss Mar15 0:00 nginx: master process ./sbin/nginx

nobody 21964 0.0 0.3 23388 1536 ? S Mar16 0:16 nginx: worker process

nobody 21965 0.0 0.4 23388 2032 ? S Mar16 0:14 nginx: worker process

nobody 21966 0.0 0.4 23716 2192 ? S Mar16 0:16 nginx: worker process

ps -ef | grep '[n]ginx'

通过正则,我们知道匹配的是 nginx 信息, 但实际上在进程中, grep 的查询进程是以 grep [n]ginx 的形式出现的, 也就是

"root xxxxx grep --color=auto [n]ginx"

我们 grep 的是 nginx 不是 [n]ginx ,所以在查询到的信息中,不会出现 grep 自身的干扰信息!

解释

为什么使用 []

grep(全局正则表达式打印,Global Regular Expression Print),是一种正则表达式模式匹配工具:用于搜索/匹配内容,并打印出匹配的内容。

在上面的用例中,[n] 这个模式在正则表达式中的含义是:中括号中的字符 n 必须出现一次。那么 grep '[n]ginx' 的含义是:在结果中搜索匹配 nginx 这个字符串。 因此就含义本身而言,grep '[n]ginx' 整体的含义等价于 grep nginx。

那么,前面的例子怎么解释?很好解释:两个命令并不相同。尽管它们的输入都是来自 ps aux,但是 grep 这个命令本身的命令在被 ps 枚举出来时是不一样的。(在执行 grep 命令的同时,也产生了一个 grep 进程,所以会出现在 ps 的结果中)

对于 ps aux | grep nginx,grep 命令的命令行是:grep nginx;

对于ps aux | grep '[n]ginx',grep 命令的命令行是:grep [n]ginx;

由于 grep nginx 和 grep '[n]ginx' 都是在结果搜索匹配 nginx,但是因为后者的 grep 命令为 grep [n]ginx。因此不被包含在结果中。这,就是原因。

为什么要加单引号?

单引号可以避免 bash 做路径名展开。

像上面这样的比较简单的字符串的匹配,不加引号基本上不会出错。

但是,在 bash 这种完全基于字符串的语言中,任何人都能轻易写出漏洞百出的脚本代码。

比如就本文的例子而言:[] 不仅是正则表达式中的特殊字符,它还是 bash 的路径名展开(pathname expansion)语法的一部分:bash 这个 shell 在执行我们的命令前会分析我们输入的命令, 并且执行若干个展开步骤中的路径名展开(pathname expansion),最后才是执行命令。

那么何为路径名展开?你可以简单地理解为替换通配符,就像我们可以用 * 代替当前目录下的所有文件一样。

展开有成功也有失败:

若成功:展开前的特殊字符被路径名替换;

若失败:默认保持不变;

举个例子:

如果当前目录下没有一个名为 nginx 的文件,grep [n]ginx (注意没有引号)会展开成 grep [n]ginx,没变。

如果当前目录下有一个名为 nginx 的文件,grep [n]ginx (注意没有引号)会展开成grep nginx,中括号没了。

所以,后者得不到期望的结果。

为什么加单引号?单引号可以避免 bash 做路径名展开。

单引号会作为参数的一部分传递给 grep 吗?不会,bash 还会执行一个叫 Quote Removal 的步骤,将(不是用户特意产出的)引号给移除掉。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值