奇怪的bash行为

时间:2014-01-24 14:54:08

标签: bash ls

所以我正在尝试获取我正在运行程序的所有目录的列表,因此我可以跟踪我目前运行的众多作业。

当我单独运行命令时,它们似乎都有效,但是当我将它们链接在一起时,出现了问题...(ll只是常规ls -l别名)

for pid in `top -n 1 -u will | grep -iP "(programs|to|match)" | awk '{print $1}'`; 
    do 
    ll /proc/$pid/fd | head -n 2 | tail -n 1; 
done

enter image description here

为什么当我在ll /proc/31353/fd循环中有for时,它无法访问该文件,但是当我正常使用它时它可以正常工作?

通过hexdump -C管道传输:

$ top -n 1 -u will | 
    grep -iP "(scatci|congen|denprop|swmol3|sword|swedmos|swtrmo)" | 
        awk '{print $1}' | hexdump -C
00000000  1b 28 42 1b 5b 6d 1b 28  42 1b 5b 6d 32 31 33 35  |.(B.[m.(B.[m2135|
00000010  33 0a 1b 28 42 1b 5b 6d  1b 28 42 1b 5b 6d 32 39  |3..(B.[m.(B.[m29|
00000020  33 33 31 0a 1b 28 42 1b  5b 6d 1b 28 42 1b 5b 6d  |331..(B.[m.(B.[m|
00000030  33 30 39 39 36 0a 1b 28  42 1b 5b 6d 1b 28 42 1b  |30996..(B.[m.(B.|
00000040  5b 6d 32 36 37 31 38 0a                           |[m26718.|
00000048

2 个答案:

答案 0 :(得分:4)

chepner had the right hunchtop的输出是为人而设计的,而不是用于解析。 hexdump显示top正在产生一些终端转义序列。这些转义序列是该行的第一个字段的一部分,因此生成的文件名称类似于/proc/\e(B\e[m\e(B\e[m21353/pid而不是/proc/21353/pid,其中\e是转义字符。

使用pspgreppidof代替。在Linux下,您可以使用-C ps选项来匹配确切的程序名称(重复选项以允许多个名称)。使用-o选项控制显示格式。

for pid in $(ps -o pid= -C scatci -C congen -C denprop -C swmol3 -C sword -C swedmos -C swtrmo); do 
  ls -l /proc/$pid/fd | head -n 2 | tail -n 1
done

如果要通过降低CPU使用率进行排序:

for pid in $(ps -o %cpu=,pid= \
                -C scatci -C congen -C denprop -C swmol3 -C sword -C swedmos -C swtrmo |
             sort -k 1gr |
             awk '{print $2}'); do 

enter image description here

此外,使用反引号而不是美元括号来进行命令替换 - 反引号中的引号表现得有些奇怪,并且很容易在那里犯错误。在美元括号内引用是直观的。

答案 1 :(得分:-2)

尝试使用“cut”而不是“awk”,如下所示:

for pid in `top -n 1 -u will | grep -iP "(scatci|congen|denprop|swmol3|sword|swedmos|swtrmo)" | sed 's/  / /g' | cut -d ' ' -f2`; do echo /proc/$pid/fd | head -n 2 | tail -n 1; done