0

I need a full path/command thats been execued to start a process thats exposed on the network - listens on tcp/udp . I did manage to get all of that using below "one liner":

netstat -nlp46|tail -n +3 |   while IFS=" " read -r -a line; 
do nb=${#line[@]}; 
PID=$(echo ${line[$((nb - 1))]} | awk -F'/' '{print $1}'); 
CMD=$(ps -ef|awk '$2 == '"$PID" |awk -F" " '{out=$8; for(i=9;i<=NF;i++){out=out""$i}; print out}');
echo $PID^$CMD; 
done

but when process contains some special characters in command line, eg thin server, script has some issues with following error

awk: line 1: missing ) near end of line

when I did run part of script against that process I had no problems

root@ftp-host02:~# PID=15000; COMMAND=$(ps -ef|awk '$2 == '"$PID" |awk '{out=$8; for(i=9;i<=NF;i++){out=out" "$i}; print out}'); 
echo $COMMAND

thin server (0.0.0.0:3000)

What I'm doing wrong here?

Thanks

1
  • Not sure exactly what is wrong with the quoting there but once you've got a list of clean pids then ps -ww -o args= -p $PID is probably an easier way to get the command line (or look at /proc/$PID/cmdline) Commented Apr 21, 2015 at 20:42

2 Answers 2

2

The error is here: awk '$2 == '"$PID"

  • if $PID is not strictly numeric, then you're doing an equality check against an unquoted string, so really, who knows how awk will interpret it?

    $ PID="3000)"
    $ echo hello | mawk '$2 == '"$PID"
    mawk: line 1: extra ')'
    

Passing the shell variable to awk as an awk variable (with the -v option) clears that up.

Cleaning up your code in other ways, we have:

netstat -nlp46 | 
tail -n +3 | 
while IFS=" " read -r -a fields; do 
    nb=${#fields[@]}
    PID=${fields[nb-1]%%/*}
    CMD=$( ps -ef | awk -v pid="$PID" '$2 == pid {out=$8; for(i=9;i<=NF;i++){out=out $i}; print out}' );
    echo "$PID^$CMD"; 
done

Notes:

  • proper indentation goes a long way towards readable code
  • the index of a numerically indexed array is already evaluated in arithmetic context so ${ary[n-1]} will work
  • You can remove a slash and all subsequent characters with shell parameter expansion, so you don't need awk to get the PID
  • you don't need to pipe awk into awk: consolidate
  • pass a shell variable into awk with the -v option
0

Could you try that:

for i in $(netstat -atnp | awk '{ print $7 }' | grep ^[0-9] | awk -F\/ '{ print $1 }'); do echo "PID: $i " $(ps faxuwwww | grep $i); done

1
  • 1
    A code snippet is not enough, it is not a real answer.
    – peterh
    Commented Apr 21, 2015 at 22:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .