如何遍历 shell 命令的输出?

新手上路,请多包涵

我想编写一个脚本,循环遍历 shell 命令的输出(可能是数组?) ps

这是命令和输出:

 $ ps -ewo pid,cmd,etime | grep python | grep -v grep | grep -v sh
 3089 python /var/www/atm_securit       37:02
17116 python /var/www/atm_securit       00:01
17119 python /var/www/atm_securit       00:01
17122 python /var/www/atm_securit       00:01
17125 python /var/www/atm_securit       00:00

将其转换为 bash 脚本(片段):

 for tbl in $(ps -ewo pid,cmd,etime | grep python | grep -v grep | grep -v sh)
do
   echo $tbl
done

但输出变为:

 3089
python
/var/www/atm_securit
38:06
17438
python
/var/www/atm_securit
00:02
17448
python
/var/www/atm_securit
00:01

如何像在 shell 输出中一样遍历每一行,但在 bash 脚本中?

原文由 adic26 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.3k
2 个回答

从不 for 循环遍历 shell 命令的结果,如果你想逐行处理它,除非你将 内部字段分隔符 $IFS 更改为 \n 。这是因为这些行将成为 分词 的主题,这会导致您看到的实际结果。意思是,例如,如果您有这样的文件:

 foo bar
hello world

以下for循环

for i in $(cat file); do
    echo "$i"
done

给你:

 foo
bar
hello
world

即使您使用 IFS='\n' 这些行仍可能成为 文件名扩展 的主题


我建议改用 while + read 因为 read 读取。

此外,如果您正在搜索属于某个二进制文件的 pid,我会使用 pgrep 。 However, since python might appear as different binaries, like python2.7 or python3.4 I suggest to pass -f to pgrep which makes it search the整个命令行,而不仅仅是搜索名为 python 的二进制文件。但这也会找到已启动的进程,例如 cat foo.py 。你被警告了!最后,您可以像您希望的那样优化传递给 pgrep 的正则表达式。

例子:

 pgrep -f python | while read -r pid ; do
    echo "$pid"
done

或者如果您还想要进程名称:

 pgrep -af python | while read -r line ; do
    echo "$line"
done

如果要将进程名称和 pid 放在单独的变量中:

 pgrep -af python | while read -r pid cmd ; do
    echo "pid: $pid, cmd: $cmd"
done

你看, read 提供了一种灵活稳定的方式来逐行处理命令行的输出。


顺便说一句,如果您更喜欢 ps .. | grep 命令行而不是 pgrep 使用以下循环:

 ps -ewo pid,etime,cmd | grep python | grep -v grep | grep -v sh \
  | while read -r pid etime cmd ; do
    echo "$pid $cmd $etime"
done

请注意我如何更改 etimecmd 的顺序。因此,能够将可以包含空格的 cmd 读入单个变量。这是因为 read 会将行分解为变量,次数与您指定的变量一样多。该行的其余部分(可能包括空格)将分配给命令行中指定的最后一个变量。

原文由 hek2mgl 发布,翻译遵循 CC BY-SA 4.0 许可协议

我发现你可以使用双引号来做到这一点:

 while read -r proc; do
     #do work
done <<< "$(ps -ewo pid,cmd,etime | grep python | grep -v grep | grep -v sh)"

这会将每一行而不是每个项目保存到数组中。

原文由 jkdba 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题