web-dev-qa-db-ja.com

busyboxシェルスクリプト-不明なオペランドエラーメッセージ

pythonスクリプトを実行して結果を取得する小さなシェルスクリプトを作成する必要があります。

私がそれをこのように実行しようとすると、それは機能します:

#!/bin/sh
/usr/bin/python /etc/scripts/backup.py
result=$?

if [ $result -gt 0 ];
    then echo 'PROBLEM';
else
    echo 'OK';
fi

しかし、このようにしようとすると失敗します。

#!/bin/sh
if [ $(/usr/bin/python /etc/scripts/backup.py) -gt 0 ];
    then echo 'PROBLEM';
else
    echo 'OK';
fi

それは返します:

lab-1:/etc/scripts# ./audit_test_wrapper.sh
sh: 0: unknown operand
OK

そして、結果は間違っています。 OKではなく「PROBLEM」と表示されているはずです。

これまでに試したこと

if [ $(/usr/bin/python /etc/scripts/backup.py) -ne 0 ];

戻り値

lab-1:/etc/scripts# ./audit_test_wrapper.sh
sh: 0: unknown operand
OK

そして私もこれを試しました:

if [ "$(/usr/bin/python /etc/scripts/backup.py)" -gt 0 ];

それは返します:

lab-1:/etc/scripts# ./audit_test_wrapper.sh
sh: out of range
OK

誰かが私を正しい方向に向けることができますか?

ありがとう。

2
dot

コマンドは、標準出力に終了ステータス(_$?_)を返しません。コマンド置換($(...))は、標準出力をキャプチャします。

代わりに、ただ

_#!/bin/sh

if ! /usr/bin/python /etc/scripts/backup.py; then
   echo 'PROBLEM'
else
   echo 'OK'
fi
_

pythonスクリプトがゼロ以外の終了ステータスで終了した場合、これは最初のブランチを選択してPROBLEMを出力します。

ifステートメントは、「スクリプトが成功しなかった場合」と読むことができます。

_!_を取り除きたい場合:

_#!/bin/sh

if /usr/bin/python /etc/scripts/backup.py; then
   echo 'OK'
else
   echo 'PROBLEM'
fi
_

ifステートメントは、「スクリプトが成功した場合」と読むことができます。


errorが表示されるのは、スクリプトが何も出力しないためです。つまり、コマンドの置換は空になります。引用符で囲まれていないため、シェルが実行しようとするコマンドは次のようになります。

_if [ -gt 0 ]
_

これは構文エラーです。

コマンド置換を引用するとき、あなたは本質的に実行しようとします

_if [ "" -gt 0 ]
_

シェルは空の文字列を整数として比較できません。

4
Kusalananda

Kusalanandaが示すように、使用する必要があるのは

if cmd; then
    echo "command succeeded"
else
    echo "command failed: $?"
fi

より具体的な例では、このようなコマンドを実行して、ゼロ以外の終了コードが「false」であり、シェルコマンド構造の「if」、「while」、およびその他の論理比較で0の終了コードがtrueであることを確認できます。

$ if (exit 3); then echo succeeded ; else echo failed $?;fi
failed 3
$ if (exit 0); then echo succeeded ; else echo failed $?;fi
succeeded
$ 

Whileループは次のように機能します。

$ i=3;while ! (exit $i); do echo failed $i; ((i--));done
failed 3
failed 2
failed 1
$ 

これは、接続に失敗したコマンドを再試行するために使用できます。または、成功するまで再試行が必要です。

(exit ...)を使用すると、そのコマンドは別のプロセスとして実行されます。組み込みのシェルコマンドの場合、これは、スクリプトを実行しているシェルインスタンスが終了しないようにするために必要です。代わりに、シェルによってサブプロセスが作成され、その終了コードが$?の値を提供します。シェルのmanページに示されています。

0
Gregg Wonderly