GNU/Linux >> Linux の 問題 >  >> Linux

Bash `(())` が `[[]]` 内で動作しないのはなぜですか?

[[..]] の GNU bash man ページ 演算子が条件式を実行することを説明し、

<ブロック引用>

0 のステータスを返します または 1 条件式 expression の評価に応じて .式は、以下の Bash 条件式で説明されているプラ​​イマリで構成されます。

しかし、算術演算子はそうではありません サポートされている条件式の一部 (プライマリ ) [[..]] 内 これは、式が強制的に文字列比較として実行されることを意味します。つまり、

(( $n < 3))

算術コンテキストでは実行されません ただし、

と同じくらい単純な辞書式 (文字列) 比較
[[ 100 < 3 ]] 

1 の ASCII 値は常に true になります。 、 00 3 の前に出現

[[..]] の内部 -lt を使用すると、算術演算がサポートされます 、 -gt

<ブロック引用>

arg1 OP arg2

OP は -eq の 1 つです 、 -ne-lt-le-gt 、または -ge . arg1 の場合、これらの算術二項演算子は true を返します。 arg2 と等しい、等しくない、より小さい、以下、より大きい、または以上 、それぞれ。

式を次のように書いたでしょうか

a=start; n=100; [[ " stop start status " =~ " $a " && $n -lt 3 ]] && echo ok || echo bad
bad

期待どおりに機能したはずです。

または、前に $ を付けて算術式の使用を強制した場合でも ((..)) より前 以下のように記述します (bash には $((..)) の動作が文書化されていないことに注意してください) [[..]] 内 )。予想される動作として、算術式が [[..]] の前に展開されます。 が評価され、結果の出力は文字列コンテキストで [[ 0 ]] として評価されます これは、空でない文字列を意味します。

a=start; n=5; [[ " stop start status " =~ " $a " && $(( $n < 3 )) ]] && echo ok || echo bad

[[..]] 内の算術式が

のように、空の比較式ではない単項文字列に分解されます
$(( 5 < 3 ))
0
[[ -n 0 ]]

算術評価 0 の結果 (false) は、テスト オペレーターによってゼロ以外のエンティティと見なされ、&& の右側で true をアサートします。 .同じことが他のケースにも当てはまります。 n=1 と言ってください

$(( 1 < 3 ))
1
[[ -n 1 ]]

簡単に言えば、[[..]] 内の算術演算には正しいオペランドを使用してください .


(( 算術文を導入する「キーワード」です。 [[ 内 ただし、他のステートメントは使用できません。 できます ただし、括弧を使用して式をグループ化するので、それが (( ... )) です は:冗長な「二重グループ」です。 < の優先順位により、以下はすべて同等です。 と && :

  • [[ " stop start status " =~ " $2 " && (($#<3)) ]]
  • [[ " stop start status " =~ " $2 " && ($#<3) ]]
  • [[ " stop start status " =~ " $2 " && $#<3 ]]

整数比較が必要な場合は、-lt を使用します < の代わりに 、ただし、すべてを [[ ... ]] 内に収める必要はありません .コマンド リストでは、条件文と算術文を一緒に使用できます。

{ [[ " stop start status " =~ " $2 " ]] && (($#<3)) ; } || { echo "Usage $0 file_name command"; exit 1;}

この場合、... && ... || ... 一般的にはそうではありませんが、期待どおりに動作します。 if を好む

if [[ " stop start status " =~ " $2 " ]] && (($#<3)); then
  echo "Usage $0 file_name command"
  exit 1
fi

Linux
  1. 〜/ .bash_profileが機能しないのはなぜですか?

  2. 一部のコマンドでBashプロセス置換が機能しないのはなぜですか?

  3. DebugfsのLsdelが機能しないのはなぜですか?

  1. BashスクリプトでCdを使用できないのはなぜですか?

  2. ヒアドキュメントの親シェルがダッシュのサブコマンドでは機能しないのに、Bashは機能するのはなぜですか?

  3. Rust ツールチェーンを Docker にインストールすると、Bash の「source」コマンドが機能しません

  1. hostname --fqdn が Ubuntu コンピューターで機能しないのはなぜですか?

  2. シンボリック リンクが機能しないのはなぜですか?

  3. Bash の正規表現の問題:[^negate] が機能しないようです