テスト式でパラメータを拡張できますか?

テスト式でパラメータを拡張できますか?

次の式を試してみると、bash奇妙なエラーメッセージが表示されます。

[: -lt: unary operator expected

最初は関数定義です。

some_func () {
  (( 3 + 5 ))
}

そして表現

[ $(some_func) -lt 10 ] && true

-lt問題は、コマンド置換や算術拡張などの混合演算子であると思います。

終了コード$?は2で、メッセージは次のとおりです。an unary op was expected

答え1

しなければならない

some_func() {
  echo "$(( 3 + 5 ))"
}
[ "$(some_func)" -lt 10 ]

なぜ失敗したのか

$(some_func)次に展開出力function* (末尾改行減算)、しかし何も出力しません。したがって、テストは

[ -lt 10 ]

最も基本的な形では、テスト[では1〜3個のパラメータを受け入れます。。上記の引数は2つあるため、Bashは最初の引数が単項演算子であると予想します。-ltバイナリなので、エラーメッセージが表示されます。

あなたはそれを持っていますか?拡張子を正しく引用してくださいそして

[ "$(some_func)" -lt 10 ]

テストに空の文字列があるため、エラーは「予測整数式」です。

[ "" -lt 10 ]

そしてそうでなければ特別な状況&& true重複しています。

*拡張は引用されていないので、出力も通過します。噴射そしてファイル名拡張子。デフォルト値が変更されない限り、この$IFS例ではこれらの要素が役割を果たしてはいけません。

答え2

$(cmd)得る標準出力したがって、cmdこれを結果に拡張するには、次のものがcmd必要です。出力それ:

some_func() {
  echo "$(( 3 + 5 ))"
}
[ "$(some_func)" -lt 10 ]

他の人がすでに言ったように。ただし、これはsome_funcサブシェル環境で実行されることを意味するため、変数やその他の点に対する変更は後で失われます。

たとえば、次のことは意味がありません。

counter=0
incr() { echo "$((++counter))"; }
while [ "$(incr)" -le 10 ]...

常に$(incr)1に拡張されます(counterサブシェルでのみ増加)。

次のように数値結果を返す関数の場合算術評価、これをサポートするシェルが必要です。数学関数または。しないksh93でください。zshbash

存在するzsh

counter=0
incr() (( ++counter ))
functions -M incr

while (( incr() <= 10 )); do
  print $counter
done

存在するksh93

function .sh.math.incr i {
  # ksh93 functions must take at least one argument
  (( .sh.value = (counter += i) ))
}
while (( incr(1) <= 10 )); do
  print "$counter"
done

ksh93 または mksh の最新バージョンの別の代替案は、サブシェルを導入しないコマンド置換形式を使用することです。

counter=0
function incr { print "$(( ++counter ))"; }
while [ "${ incr; }" -le 10 ]; do
  print "$counter"
done

またはmksh:

counter=0
incr() (( REPLY = ++counter ))
while [ "${| incr; }" -le 10 ]; do
  print "$counter"
done

を含むすべてのPOSIXシェルでは、bash常に事前定義された変数($REPLY通常はこの目的で使用されます)で値を返すことができます。

counter=0
incr() { REPLY=$(( counter += 1 )); }
while incr; [ "$REPLY" -le 10 ]; do
  echo "$counter"
done

詳細は以下で確認できます。mkshのvalsub機能に対する別のQ&Aに対する答えは次のとおりです。


¹末尾の改行文字を削除し、bashNUL文字の場合は引用符を忘れたため、ここで分割+globが適用されます。

答え3

コマンドの置き換え出力キャプチャコマンドや機能の。この関数には出力はありません。

この$?変数は戻りコード関数。

次のいずれかを実行します。

some_func
(( $? < 10 )) && echo yes

または、機能を次のように変更します。

some_func() {
    echo $(( 3 + 5 ))
}

[[ $(some_func) -lt 10 ]] && echo yes

[[...]]代わりに私がどのように使用しているかに注意してください[...]。二重括弧条件は、NULL値にさらに寛大です。

関連情報