我正在使用 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
如果你使用zsh
or(t)csh
代替bash
,你就会明白你的错误:
$ ps -ef | grep [c]ron
zsh: no matches found: [c]ron
上面,您有一个通配模式,旨在扩展到当前目录中与该模式匹配的文件列表。
然而,在大多数类似 Bourne 和类似 rc 的 shell 中,如果没有匹配的文件,该模式会不经改动地静默传递给命令。
这就是为什么它可以与 一起使用,因为当前目录中[c]ron
没有调用任何文件,但不能与 一起使用,因为当前目录中有一个与该模式匹配的文件,它被 shell 扩展为并获取一个参数而不是。cron
[a]2draw
a2draw
grep
a2draw
[a]2draw
请注意,bash
可以通过执行以下操作来配置为像zsh
在这种情况下一样工作:
shopt -s failglob
当 glob 不匹配时, shellfish
也会报告错误。然而,[...]
它不是 中的通配符运算符fish
。
这意味着当您不希望扩展通配符时,需要引用它们:
ps -ef | grep '[a]2draw'
您可以不用在bash
除 之外的其他类似 Bourne 的 shell中执行此操作zsh
,但这会导致潜伏的错误在您在具有匹配文件的目录中运行命令的当天随时准备好启动。
我可能会在意想不到的情况下产生令人讨厌的副作用。喜欢:
rm -?
在包含名为 和 的文件的目录中--
,-x
将-y
同时删除-x
和-y
。