本问题已经有最佳答案,请猛点这里访问。
我想在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
怎么解决这个问题
mywiki.wooledge.org/DontReadLinesWithFor
关于这一点的任何内容都不是特定于ps - 关于如何逐行迭代来自其他源的输入的答案都是有效的。
(也就是说,一般情况下,如果可以避免,则不应在脚本中使用ps的输出。对于大多数用途pgrep更合适,或使用不需要的咨询锁定等方法 完全读取进程表以检查程序是否正在运行)。
根据melpomene的评论,这应该适合你,同时保持与sh的兼容性。
#!/bin/sh
ps aux | grep test.py | while IFS= read -r line; do
printf '%s
'"$line"
done
grep 1? 那是什么意思?
如果您的目标是跳过标题ps auxw | { read; while read ...; done; } - 那么当您只想避开第一行时,就可以避免将开销放入用于读取100%行的过程中。
@CharlesDuffy这仅用于测试目的,我更正了。 谢谢你的提示。
@Matthias IFS的工作是什么?
@code_worker它确保你阅读整行,请参阅unix.stackexchange.com/a/209184/90304
read命令将从标准输入读取一行并将其放入变量中。 当它到达输入结束时,它将以状态1退出,您可以使用它来结束while循环:
ps aux | grep test.py | while read line; do
echo LINE:
echo"$line"
echo
done
如果你想要它,read将使用内部字段分隔符(IFS)将输入拆分为单独的变量,如果输入的字段多于变量,它将在到达最后一个变量时停止分割 线路的其余部分,未分裂,在那里。
这意味着如果你只提供一个变量(我在上面的例子中称之为"line"),你将得到整行,unsplit,你不必担心设置IFS。