开发者

Comparing PID's in bash

I'm trying to something very simple and I'm having lots of trouble with it.

I've got a bash script that I have to write for class that performs a function similar to pstree. It reports pstree for itself. The output should look like:

PID
|
PPID
|
.
.
.
|
1

Here is my code so far:

ps -ef>tmp1.txt                   #save ps -ef to a file
pid=$$      
echo $pid                         #print first PID
while [ $pid != "1" ]
do
    cat tmp1.txt | while read line    #read in ps -ef file line by line
    do
        tmp=$(echo $line | cut -f2 -d' ') #return only the PID column of ps -ef
        if [$pid == $tmp]                 #compare current PID to temp PID of current line
        then
            echo "|"
            pid=$(echo $line | cut -f3 -d' ') #if they're the same we found the PPID, so save it
            echo $pid                         #and echo it
        fi
    done
done

Where it's failing is at the comparison statement:

if [$pid == $tmp]

I get a not found error. Got any ideas why the comparison isn't working? Thanks for any hel开发者_如何转开发p in advance and if I can clarify anything please tell me.


A single equals sign is used to compare strings (if [ $pid = $tmp ]).


I've edited your question to indent the code. It's much, much easier to read when you indent each while and if statement.

The line you're complaining about is

   if [$pid == $tmp]

That's invalid for a couple of reasons already pointed out. Unlike other programming languages, BASH uses a single equals sign, and you must keep a blank space around the square brackets. The square bracket is a command, and must be white space separated. It's an alias for the test command. This line should look like this:

   if [ $pid = $tmp ]

Now, = is a string comparison, if you're doing a numeric comparison, you should use -eq instead:

   if [ $pid -eq $tmp ]

And, since [ is an alias to the test command, it could be written like this (but rarely is):

   if test $pid -eq $tmp

However, it does show you why you need a space around the square braces.


Your code is not efficient. Try with awk, without temporary file and nested loop:

ps -eo pid,ppid | awk -v START=$$ '
{ PPID[$1]=$2 } # (for each line) create PPIDs table record
END { if (PPID[START]) { # (when done) if starting pid is correct
    for(pid=START; pid!=1; pid=PPID[pid]) # print the tree
      printf "%d\n|\n", pid;
    print 1;
  }
}'


For those of you interested my final code looks like this:

echo $pid
while [ $pid != "1" ]
do
     while read line
     do
          tmp="$(echo $line | cut -f2 -d' ')"
          if [ $pid = $tmp ];
          then
               pid="$(echo $line | cut -f3 -d' ')"
          fi
     done<./tmp1.txt
     echo "|"
     echo $pid
done

Thanks to all of you jedi masters out there.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜