私はこれでどこにも行けません。
10回繰り返し、出力に「Connection成功した」文字列が含まれている場合は、中断されるbashスクリプトを作成したいと思います。
ret=$?
thenと同じことを試しましたが、1であっても引き続きif [$ret -ne 0]
elseステートメントが表示されます。ret
今、「接続成功」という単語を見つけようとしていますが、その構文の使い方がわかりません。
だから私は次のようなものが欲しい:
for i in {1..10}
do
ret=bluetoothctl connect 26:EE:F1:58:92:AF | grep "connection successful"
if [$ret -ne ""]; then
break
fi
done
しかし、明らかに正しい構文を使用すると、$ret=bluetoothctl connect 26:EE:F1:58:92:AF | grep "connection successful"
どんな助けでも大変感謝します。
答え1
grep
一部のテキストがパターンと一致するかどうかをテストする場合は、出力を保存する必要はほとんどありません。代わりにオプションをgrep
使用して呼び出し-q
て、終了状態に応じて対処してください。
#!/bin/sh
tries=10
while [ "$tries" -gt 0 ]; do
if bluetoothctl connect '26:EE:F1:58:92:AF' | grep -q 'connection successful'
then
break
fi
tries=$(( tries - 1 ))
done
if [ "$tries" -eq 0 ]; then
echo 'failed to connect' >&2
exit 1
fi
失敗および成功時に正常な終了状態が返される場合、ループのステートメントはbluetoothctl
不要で、次のように短縮できgrep
ます。if
if bluetoothctl connect '26:EE:F1:58:92:AF' >/dev/null
then
break
fi
実際には、bluetoothctl
ループ条件を一部として含めることもできます(ここに示すように、for
ループからループの使用に切り替えると仮定します)。while
#!/bin/sh
tries=10
while [ "$tries" -gt 0 ] && ! bluetoothctl connect '26:EE:F1:58:92:AF'
do
tries=$(( tries - 1 ))
done >/dev/null
if [ "$tries" -eq 0 ]; then
echo 'failed to connect' >&2
exit 1
fi
使用を検討してくださいhttps://www.shellcheck.netシェルスクリプトの構文を確認してください。問題のスクリプトについては、テストには次のスペースが必要であると指定されています[ ... ]
。
if [$ret -ne ""]; then
^-- SC1009 (info): The mentioned syntax error was in this if expression.
^-- SC1035 (error): You need a space after the [ and before the ].
^-- SC1073 (error): Couldn't parse this test expression. Fix to allow more checks.
^-- SC1020 (error): You need a space before the ].
^-- SC1072 (error): Missing space before ]. Fix any mentioned problems and try again.
空でない文字列のテストは、または[ -n "$ret" ]
を使用して実行されます[ "$ret" != "" ]
。-ne
これは山水テスト。
また、パイプの出力をret
。あなたが使う計画は
ret=$( bluetoothctl ... | grep ... )
答え2
Kusalanandaはコードを改善する方法についてのヒントを提供しますが、正確に何が間違っているかを説明しません。復習してみましょう:
ret=$?
私はthenのようなものを試しましたが、if [$ret -ne 0]
retが1にもかかわらずまだelseステートメントを取得します。
[
はコマンドなので、コマンドと引数の間にスペースを入れる必要があります。それ以外の場合、引数はコマンド名の一部として理解されます。ret
に設定すると、1
bashはエラーを印刷し、[1: command not found
エラーif
にはfalseを表示する必要があります。繰り返しますが、[
最後のパラメータは必須ですが、]
そうではありません0]
。そこにもスペースが必要です。
あなたが望むもの:
if [ "$ret" -ne 0 ]
次の部分:
ret=bluetoothctl connect 26:EE:F1:58:92:AF | grep "connection successful"
ここで行うことは、コマンド(存在しない可能性があります)に値を持つ環境変数をconnect 26:EE:F1:58:92:AF | grep "connection successful"
提供しながらパイプラインを実行することです。connect
ret
bluetoothctl
出力を収集するには、コマンドを次にまとめる必要があります$()
。
ret="$(bluetoothctl connect 26:EE:F1:58:92:AF | grep "connection successful")"
これで:
if [$ret -ne ""]; then
空白の欠落と同じ問題がありますが、より深く理解すると、基本的にほとんどの項目は bash で暗黙的に文字列であり、引用符はほとんどの拡張の一部の詳細を制御することに加えて、より明示的な方法にすぎないということです。つまり、[$ret -ne ""]
次のようにほぼ正確に計算されます。
[$ret -ne ]
[$ret -ne ""''""'']
"["$ret "-ne" """]"
"["$ret"" "-ne""""" """]"""
空の場合$ret
と同じです[ -ne ]
。空でない文字列であることを確認するために検証される引数(無視]
)が1つしかないため、trueと評価されます。[
-ne
$ret
それと似たようなものは、引用符がないためfoo bar baz
にトークン化され、[foo bar baz -ne ]
4つの引数(インクルード)を取り、]
bashがコマンドを見つけることができないため、falseのコマンドを取得します[foo
。$ret
likeを引用すると、2つの引数(含む)があり、bashがコマンドを見つけることができないため、falseになる["$ret" -ne ""]
同等の結果が得られます。"[foo bar baz" -ne ]
]
[foo bar baz
ここで犯すもう一つの間違いは、-ne
特に数値比較に使用することです。空白と引用符の問題を解決しても、bashはエラーを引き起こしますinteger expression expected
。あなたが望むのは!=
文字列比較のためのものです。
これらすべての問題を要約して解決するには、次のものが必要です。
if [ "$ret" != "" ]; then
次のように書くこともできます。
if [ -n "$ret" ]; then
または
if [ "$ret" ]; then