【问题标题】:how to get output from `ps` line by line in shell [duplicate]如何在shell中逐行获取`ps`的输出[重复]
【发布时间】:2018-03-18 04:21:39
【问题描述】:

我想在 shell 中通过 ps 列出一个进程及其信息。 这是我的脚本:

#!/bin/sh

for line in `ps aux| grep test.py`
do
    echo $line
done

但是输出是:

hey
13241
0.0
0.3
48388
13528
pts/18
S+
18:50
0:00
python
test.py
hey
13370
0.0
0.0
14504
1016
pts/21
S+
19:00
0:00
grep
test.py

它将一行分成很多部分,但我希望我可以在终端中获得有关名称为 test.py 的进程的一行信息:

hey   13241  0.0  0.3  48388 13528 pts/18   S+   18:50   0:00 python test.py
hey   13446  0.0  0.0  14504   976 pts/21   S+   19:08   0:00 grep --color=auto test.py

如何解决

【问题讨论】:

  • 这不是ps特有的——关于如何逐行迭代来自其他来源的输入的答案都是有效的。
  • (也就是说,一般来说,如果可以避免的话,您不应该在脚本中使用来自ps 的输出。对于大多数用途,pgrep 更合适,或者使用这样的方法作为建议锁定,根本不需要读取进程表来检查程序是否正在运行)。

标签: linux shell sh ps


【解决方案1】:

根据 melpomene 的评论,这应该对您有用,而 keeping compatibility to sh

#!/bin/sh
ps aux | grep test.py | while IFS= read -r line; do
    printf '%s\n' "$line"
done 

【讨论】:

  • grep 1?这有什么意义?
  • 如果您的目标是跳过标题,ps auxw | { read; while read ...; done; } - 这样您就可以避免在您只想避免第一行时将开销放入用于读取 100% 行的过程中。跨度>
  • @CharlesDuffy 这仅用于测试目的,我更正了。感谢您的提示。
  • @Matthias IFS 的作用是什么?
  • @code_worker 它确保您阅读整行,请参阅unix.stackexchange.com/a/209184/90304
【解决方案2】:

read 命令将从标准输入中读取一行并将其放入一个变量中。当它到达输入结束时,它将以状态 1 退出,您可以使用它来结束 while 循环:

ps aux | grep test.py | while read line; do
  echo LINE:
  echo "$line"
  echo
done

如果您愿意,read 将使用内部字段分隔符 (IFS) 将输入拆分为单独的变量,如果输入的字段多于变量,它会在到达最后一个变量时停止拆分然后将行的其余部分(未拆分)放在那里。

这意味着如果您只提供一个变量(我在上面的示例中将其称为“行”),您将获得整行,未拆分,并且您无需担心设置 IFS。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 2021-02-01
    相关资源
    最近更新 更多