附:| grep 在子 shell 中显示错误的输出,并且作业在后台运行

附:| grep 在子 shell 中显示错误的输出,并且作业在后台运行

我正在使用 bash。我有一个名为“a2draw”的文件,其中仅包含 1 行:

sleep 99999

我使用以下命令启动它:

bash a2draw &

现在,我知道并理解方括号的技巧,它允许您在 ps 输出中省略 grep 过程:

ps aux | grep cron
root      1079  0.0  0.0   2596   788 ?        Ss   Mar25   0:00 cron
root      1119  0.0  0.0   3684   696 ?        Ss   Mar25   0:00 /usr/sbin/incrond -f /etc/incron.conf
ja       29781  0.0  0.0   4368   820 pts/10   S+   12:49   0:00 grep cron

ps aux | grep [c]ron
root      1079  0.0  0.0   2596   788 ?        Ss   Mar25   0:00 cron
root      1119  0.0  0.0   3684   696 ?        Ss   Mar25   0:00 /usr/sbin/incrond -f /etc/incron.conf

但它在后台运行作业的子 shell 中不起作用:

jobs
[1]+  Running                 bash a2draw &

ps aux | grep [a]2draw
ja       22977  0.0  0.0   5172  1080 pts/10   S    12:21   0:00 bash a2draw
ja       30242  0.0  0.0   4364   816 pts/10   R+   12:50   0:00 grep

更奇怪的是,从进程名称中删除一个字母会产生正确的结果:

ps aux | grep [a]2dra
ja       22977  0.0  0.0   5172  1080 pts/10   S    12:21   0:00 bash a2draw

在另一个 shell 上,一切都按我的预期运行:

ps aux | grep [a]2draw
ja       22977  0.0  0.0   5172  1080 pts/10   S    12:21   0:00 bash a2draw

ps aux | grep [a]2dra
ja       22977  0.0  0.0   5172  1080 pts/10   S    12:21   0:00 bash a2draw

我不知道发生了什么事。修改管道创建方式的后台作业有什么特别之处吗?

答案1

如果你使用zshor(t)csh代替bash,你就会明白你的错误:

$ ps -ef | grep [c]ron
zsh: no matches found: [c]ron

上面,您有一个通配模式,旨在扩展到当前目录中与该模式匹配的文件列表。

然而,在大多数类似 Bourne 和类似 rc 的 shell 中,如果没有匹配的文件,该模式会不经改动地静默传递给命令。

这就是为什么它可以与 一起使用,因为当前目录中[c]ron没有调用任何文件,但不能与 一起使用,因为当前目录中有一个与该模式匹配的文件,它被 shell 扩展为并获取一个参数而不是。cron[a]2drawa2drawgrepa2draw[a]2draw

请注意,bash可以通过执行以下操作来配置为像zsh在这种情况下一样工作:

shopt -s failglob

当 glob 不匹配时, shellfish也会报告错误。然而,[...]它不是 中的通配符运算符fish

这意味着当您不希望扩展通配符时,需要引用它们:

ps -ef | grep '[a]2draw'

您可以不用在bash除 之外的其他类似 Bourne 的 shell中执行此操作zsh,但这会导致潜伏的错误在您在具有匹配文件的目录中运行命令的当天随时准备好启动。

我可能会在意想不到的情况下产生令人讨厌的副作用。喜欢:

rm -?

在包含名为 和 的文件的目录中---x-y同时删除-x-y

相关内容