我正在创建一个脚本来更新远程计算机,我想在更新之前知道是否有用户正在使用该计算机。我有一个用户列表,并为所有用户创建了一个heredoc。我试图使的命令看起来像这样:
ps -ef | grep -f | cat <<- END
user1
user2
user3
END
这是行不通的。我该怎么做才能使用 Heredoc 根据我的用户列表过滤 ps 命令?
答案1
简短回答:ps -u user1,user2,user3
您的grep
命令不完整,因为该-f
选项需要参数。您的cat
命令正在从此处文档接收其输入,因此即使您修复了该grep
命令,其输出也会被丢弃。
如果您正在寻找硬编码用户,您可以使用
ps -ef | grep alice
(除非这不是一个好方法,我稍后会解释)。的输入grep
是 的输出ps -ef
。您可以通过传递多个-e
选项来传递多个搜索模式:
ps -ef | grep -e alice -e bob
这将打印包含alice
或 的行bob
。要从文件中获取输入列表,您可以使用该-f
选项,但这需要文件名。
cat <<EOF >users.txt
alice
bob
END
ps -ef | grep -f users.txt
您正在过滤的文本已采用标准输入,因此您无法将其重新用于搜索模式。想要多个输入是一个常见问题,因此一些 shell(ksh、bash、zsh)提供了解决方案:流程替代(这是什么唐·克里斯蒂建议在一条评论):
ps -ef | grep -f <(cat <<END
alice
bob
END
)
如果用户列表是由复杂命令生成的,则此方法很有用,但使用硬编码列表时,它会变得不必要的复杂:grep -e alice -e bob
执行相同的工作。
这种方法的问题在于它会匹配线路上任何位置的用户名。该ps
命令具有仅列出特定用户组的进程的选项。就用那个吧。
ps -u alice,bob
如果您使用的嵌入式系统的版本ps
不支持-u
,请查看它是否支持-o USER
,并使用grep -x
来匹配整行。
busybox ps -o user | grep -x -e alice -e bob
答案2
一般来说,我会推荐吉尔斯的回答。
如果您需要脚本兼容 POSIX 而您的脚本ps
不支持-u
,则可以使用以下方法:
ps -ef | grep -e \
"^smtpd
^dbus
^ntp"
ps -ef
即通过管道输出grep -e pattern_list
。 Pattern_list 作为多行字符串提供,每个模式都以 开头,将^
其锚定在行的开头。