脚本中的奇怪grep行为

时间:2018-01-17 14:46:43

标签: linux bash grep

在我的一个工具中需要系统中的specyfic过程的PID。我尝试按照以下命令执行此操作:

parasit@host:~/# ps -ef | grep beam.smp |grep -v grep |awk '{ print $2 }' |head -n1
11982

工作正常,但是当我尝试在脚本中使用相同的命令时,在绝大多数情况下得到 grep 的PID而不是目标进程(在这种情况下为beam.smp),尽管&#39 ; grep -v grep`。

parasit@host:~/# cat getPid.sh
#!/bin/bash

PROC=$1    
#GET PID
CMD="ps -ef | grep $PROC |grep -v grep |awk '{ print \$2 }' |head -n1"
P=`eval $CMD`


parasit@host:~/# bash -x ./getPid.sh beam.smp 
+ PROC=beam.smp
+ CMD='ps -ef |grep beam.smp |grep -v grep |awk '\''{ print $2 }'\'' |head -n1'
++ eval ps -ef '|grep' beam.smp '|grep' -v grep '|awk' ''\''{' print '$2' '}'\''' '|head' -n1
+++ head -n1
+++ awk '{ print $2 }'
+++ grep -v grep
+++ grep beam.smp
+++ ps -ef
+ P=2189

有趣的是,它不是确定性的,我知道这听起来很奇怪,但有时它可以正常工作,有时候没有,我不知道它取决于什么。

怎么可能?有没有更好的方法来摆脱" grep"从结果?

BR Parasit

1 个答案:

答案 0 :(得分:1)

pidof -s就是这样做的(-s:返回单个ID):

pidof -s "beam.smp"

但是,pidof也会返回已解散(僵尸,死机)进程。因此,这是一种获取指定命令的第一个活动和运行过程的PID的方法:

# function in bash

function _get_first_pid() {
  ps -o pid=,comm= -C "$1" | \
     sed -n '/'"$1"' *$/{s:^ *\([0-9]*\).*$:\1:;p;q}'
}

# example

_get_first_pid "beam.smp"
  1. -o pid=,comm=:仅列出PID和COMMAND列;即。只列出我们需要检查的内容;如果列出了所有内容,那么以后处理起来会更加困难
  2. -C "$1"-C中指定的命令;即。只找到那个特定命令的过程,而不是一切
  3. sed:仅打印没有“defunct”的第一行的PID或基本命令名后的任何内容