2011-09-17 4 views
3

私は何か非常に簡単にしようとしています。私はそれに多くの問題を抱えています。PIDをbashで比較する

私はpstreeに似た機能を実行するクラスのために書かなければならないbashスクリプトを持っています。それはpstree自体について報告します。出力は次のようになります。ここでは

PID 
| 
PPID 
| 
. 
. 
. 
| 
1 

は、これまでの私のコードです:それは失敗だ

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 

は、比較のステートメントである:

if [$pid == $tmp] 

私が見つからないエラーが発生します。比較がうまくいかない理由があれば教えてください。事前に助けていただきありがとうございます。私が何かを明確にすることができれば教えてください。

答えて

4

文字列を比較するために単一の等号が使用されます(if [ $pid = $tmp ])。

+3

そして '['と ']'文字の周囲にスペースが必要です。 –

+0

@Keith:そうですね、ありがとう、私はそれを正しく書いたが、それを指摘しなかった。 –

+0

変更を加えて、それの後ろにセミコロンを追加しました。まだ完全には機能しませんが、私は進歩しています。ありがとうございました – Casbar77

2

質問を編集してコードをインデントしました。 while文とif文をそれぞれインデントすると読みやすくなります。

あなたが文句を言っているラインは、すでに指摘した理由のカップルのため無効です

if [$pid == $tmp] 

です。他のプログラミング言語とは異なり、BASHは等号を1つ使用し、角括弧のまわりに空白を入れなければなりません。角括弧はコマンドであり、空白で区切られていなければなりません。これはtestコマンドのエイリアスです。 [であるため、

if [ $pid -eq $tmp ] 

そして:この行は次のようになります。

if [ $pid = $tmp ] 

を、=はあなたが数値比較をやっている場合は、あなたの代わりに-eqを使用する必要があり、文字列の比較でありますtestコマンドのエイリアスは、このように書かれた(しかし、めったにありません)することができます:なぜあなたのn

if test $pid -eq $tmp 

しかし、それはあなたを示してい角かっこの周りにスペースを置いてください。

+0

フィードバックをお寄せいただきありがとうございます。インデントの欠如はコピーアンドペーストの問題でした。私はあまりにも多くの環境の間を移動していて、それらを追加するのを忘れていました。 – Casbar77

0

コードが効率的ではありません。一時ファイルおよびネストされたループせずに、awkをして試してみてください:

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; 
    } 
}' 
+0

私はそれが非効率的であることを知っています。私はこのようにコード化する必要がありました。しかし、私はあなたに同意します。 awkの中でそれをすべて実行する方が優れています。 – Casbar77

0

興味を持ってあなたのそれらのための私の最終的なコードは次のようになります。そこにあなたのすべてのジェダイマスターへ

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 

感謝。

+0

あなたはまだ一時ファイルを避けることができます(いつも手間がかかりますが、通常の成功例でも削除していないようです)、 'read'で分割します。 'ps -ef |のようなものです。一方、読者はp p restを読んでいる。ケース$ pidを$ pで実行する)pid = $ pp ;;エサック;完了 – tripleee