web-dev-qa-db-ja.com

ゼロに割り当てられたこの変数の値が2であるのはなぜですか

'Enigma2'というプロセスが存在しない場合に変数にゼロを設定するスクリプトを作成しようとしています。

このスクリプトを実行すると...

_#!/bin/sh
Enigma_PID=$(ps ax|grep Enigma2|grep -v grep|wc -l | awk '{print $1}')
echo $Enigma_PID
echo "$Enigma_PID"
_

出力を取得します...

_0  
0  
_

これは私が期待することです。

しかし、このスクリプトを実行すると:

_#!/bin/sh

# Check if the no_Enigma file exists
if [ -f /home/root/no_Enigma ]; then
    # If Enigma2 is running then kill it
    Enigma_PID=$(ps ax|grep Enigma2|grep -v grep|wc -l | awk '{print $1}')
    echo $Enigma_PID
    echo "$Enigma_PID"

    re='^[0-9]+([.][0-9]+)?$'
    if ! [[ $Enigma_PID =~ $re ]] ; then
       echo "error: Not a number" >&2; exit 1
    else
        echo "It IS a number"
    fi

        if [ "$Enigma_PID" -gt 0 ]; then
            echo $Enigma_PID
            echo "$Enigma_PID"
            echo "Enigma2 is running"
            killall Enigma2
        else
            echo "Enigma2 is not running"       
        fi
    # Check if minisatip is running already, if not then start it
    MINI_PID=$(ps ax|grep minisatip|grep -v grep|wc -l | awk '{print $1}')
        if [ "$MINI_PID" -gt 0 ]; then
            echo "minisatip is already running"
        else
            echo "minisatip is not running"
            echo "starting minisatip"
            /usr/bin/minisatip --satip-xml http://127.0.0.1:8554 -R /usr/share/minisatip/html       
        fi
else
    # The no_Enigma file does not exist
    # Check if minisatip is running, if yes then kill it
    MINI_PID=$(ps ax|grep minisatip|grep -v grep|wc -l | awk '{print $1}')
        if [ "$MINI_PID" -gt 0 ]; then
            echo "minisatip is running, killing it now"
            killall minisatip
        else
            echo "minisatip is not running"
        fi  
    # Check if Enigma2 is running already, if not then start it
    Enigma_PID=$(ps ax|grep Enigma2|grep -v grep|wc -l | awk '{print $1}')
        if [ "$Enigma_PID" -gt 0 ]; then
            echo "Enigma2 is already running"
        else
            echo "Enigma2 is not running"
            echo "starting Enigma2"
            /home/root/run_Enigma.sh            
        fi
fi
_

私はこの出力を取得します...

_2  
2  
It IS a number  
2  
2  
Enigma2 is running  
killall: Enigma2: no process killed  
minisatip is already running 
_

2番目のスクリプトの先頭から_#!/bin/sh_を削除すると、予期した出力が得られます。

_0  
0  
It IS a number  
Enigma2 is not running  
minisatip is already running  
_

なぜこれらの3行を行うのですか?

_#!/bin/sh
Enigma_PID=$(ps ax|grep Enigma2|grep -v grep|wc -l | awk '{print $1}')
echo $Enigma_PID
echo "$Enigma_PID"
_

_$Enigma_PID_変数を値0として正しく報告する
しかし、2番目のスクリプトでは、同じ3行が_$Enigma_PID_変数を値2として報告していますか?

更新

以下のコメントの質問に対する回答です。

このスクリーンショットは、両方のスクリプトを実行しているところを示しています。 minisatipプロセスが実行されていて、Enigma2プロセスが実行されていなかったとき。

enter image description here

最初のスクリプトのパス(3行または4行のみ)は/home/root/test.shであり、どこからでも実行できます。これは単に_# test.sh_のようです
2番目のスクリプトのパスは/usr/bin/Enigma2.shであり、ご覧のとおり、単純に_Enigma2.sh_のように実行します。

示唆されたように、両方のスクリプトを更新して、パイプに接続されたコマンドからwcとawkを削除しました。その出力は、変数に値を割り当てるためのものです:Enigma_PID

/home/root/test.shを次のように変更しました:

_#!/bin/sh
Enigma_PID=$(ps ax|grep Enigma2|grep -v grep)
echo $Enigma_PID
echo "$Enigma_PID"
_

/usr/bin/Enigma2.shで、これらの行をスクリプトの先頭に追加しました...

_#!/bin/sh
Enigma_PID=$(ps ax|grep Enigma2|grep -v grep)
echo $Enigma_PID
echo "$Enigma_PID"

# Check if the no_Enigma file exists
...
....
_

次にスクリプトを実行し、このスクリーンショットは出力を示しています。

enter image description here

私がチェックしているプロセスは、パスが付いたバイナリ/ usr/bin/Enigma2です。このバイナリは実行されていません。ただし、Enigma2.shスクリプトを実行すると、2つのプロセスIDが存在します。これは、スクリプト自体がEnigma2と呼ばれているためですか?では、なぜ2つのプロセスIDが1つではなくEnigma2と呼ばれるのでしょうか。

質問
このコマンドで何を変更する必要がありますか
Enigma_PID=$(ps ax|grep Enigma2|grep -v grep|wc -l | awk '{print $1}')

... /usr/bin/Enigma2.shというスクリプトにある場合
...それはスクリプトを数えません、それは実行中のプロセスの一部です?
...バイナリ/ usr/bin/Enigma2が実行されていない場合、結果はゼロになります。

ありがとうございました!

フレックス

3
FlexMcMurphy

2番目のスクリプトは_Enigma2.sh_と呼ばれ、コマンドラインで_Enigma2.sh_と記述することでそれを呼び出すことが編集から明らかです。スクリプトはパスのどこかにあります(_/usr/bin/Enigma2.sh_にあることを宣言します。_/usr/bin_がPATH変数にあると仮定します)。シェルによってスクリプトが(PATHで)見つかり、スクリプトの最初の行が_#!/bin/sh_であることを組み合わせると、カーネルは次のコマンドラインを持つ新しいプロセスを開始します。

_/bin/sh Enigma2.sh
_

これを確認するには、スクリプトの最初の行を次のようにします。

_#!/bin/sh 
ps ax|grep Enigma2
exit 0
...
_

スクリプトを消去する必要はありません。上記の行をスクリプトの先頭に配置し、残りはすべて下に残してください。

それを実行して取得します:

_$ Enigma2.sh
 3109 pts/6    S+     0:00 /bin/sh Enigma2.sh
 3111 pts/6    S+     0:00 grep Enigma2
_

Word _Enigma2_を含む2つのプロセスがあります。

それが問題の一部を説明しています。スクリプトを次のように変更すると、

_#!/bin/sh 
Enigma_pid=$(ps ax|grep Enigma2)
echo "$Enigma_pid"
exit 0
...                     # leave the old script below (no need to erase it).
_

そしてそれを実行します:

_$ Enigma2.sh
 3509 pts/6    S+     0:00 /bin/sh ./Enigma2.sh
 3510 pts/6    S+     0:00 /bin/sh ./Enigma2.sh
 3512 pts/6    S+     0:00 grep Enigma2
_

$(…)を使用すると、1つの追加プロセスが表示されます。

_grep -v grep_を使用してgrepプロセスを削除すると、2つのプロセスが残ります。

これが_2_を取得する数です。

:大文字の変数名は使用しないでください。これらは環境変数用に予約されています。
使用しないでください Enigma_PID

ソリューション

  • まず、プロセスをその名前で識別する場合は、他のプログラムやスクリプトでまったく同じ名前を使用しないでください。スクリプトは_Enigma33.sh_と呼ぶことができます。

  • 2番目:この場合、grepが_2_で終わる名前と一致するように制限できます。スクリプトは_.sh_で終わり、カウントされません。使用する

    _ grep '[e]nigma2$'
    _

そして、必要なのは一致する行の数だけなので(_-c_)を使用します。

_Enigma_pid=$(ps ax | grep -c '[e]nigma2$')
_

はい、正規表現_grep -v grep_を_[e]nigma2$_と(文字列として)等しくすることはできないため、_Enigma2_は不要です。

編集されたスクリプト:

_#!/bin/sh


# Detect If Enigma2 is running.
Enigma_pid=$(ps ax|grep -c '[e]nigma2$')
echo "$Enigma_pid"    

# Deetct if minisatip is running.
mini_pid=$(ps ax|grep -c '[m]inisatip$' )


# Check if the no_Enigma file exists
if [ -f /home/root/no_Enigma ]; then
    if [ -z "${Enigma_pid##*[!0-9]*}" ] ; then
       echo "error: Not a number" >&2; exit 1
    else
        echo "It IS a number"
    fi
    
    if [ "$Enigma_pid" -gt 0 ]; then
        echo "$Enigma_pid"
        echo "Enigma2 is running"
        killall -r '[e]nigma2$'           # make killing more restrictive
    else
        echo "Enigma2 is not running"
    fi
    # Check if minisatip is running already, if not then start it
    if [ "$mini_pid" -gt 0 ]; then
        echo "minisatip is already running"
    else
        echo "minisatip is not running"
        echo "starting minisatip"
        /usr/bin/minisatip --satip-xml http://127.0.0.1:8554 -R /usr/share/minisatip/html       
    fi
else    
    # The no_Enigma file does not exist
    # Check if minisatip is running, if yes then kill it
    if [ "$mini_pid" -gt 0 ]; then
        echo "minisatip is running, killing it now"
        killall minisatip
    else
        echo "minisatip is not running"
    fi  
    # Check if Enigma2 is running already, if not then start it
    if [ "$Enigma_pid" -gt 0 ]; then
        echo "Enigma2 is already running"
    else
        echo "Enigma2 is not running"
        echo "starting Enigma2"
        /home/root/run_Enigma.sh            
    fi
fi
_
4
Isaac

説明したように、2番目のスクリプトから実行した場合、ps axコマンドは異なる結果を生成します。

そのコマンドが異なる値を生成している理由を理解するために、2番目のスクリプトをデバッグする必要があります(そうするために(そしてデバッグの目的でのみ))。

Enigma_PID=$(ps ax|grep Enigma2|grep -v grep|wc -l | awk '{print $1}')
echo $Enigma_PID
echo "$Enigma_PID"

Enigma_PID=$(ps ax|grep Enigma2|grep -v grep)
echo $Enigma_PID
echo "$Enigma_PID"

そして、出力の実際の違いと問題の原因を確認し、それに応じてスクリプトを調整します。また、スクリプトnameEnigma2が含まれている場合、コメントで提案されているように、誤検知として検出されます。

5
flowb