次の構文を使用してシェルスクリプトでブール変数を宣言しようとしました。
variable=$false
variable=$true
これは正しいです?また、その変数を更新したい場合、同じ構文を使用しますか?最後に、正しい式としてブール変数を使用するための次の構文があります。
if [ $variable ]
if [ !$variable ]
修正された回答(2014年2月12日)
the_world_is_flat=true
# ...do something interesting...
if [ "$the_world_is_flat" = true ] ; then
echo 'Be careful not to fall off!'
fi
元の回答
警告: https://stackoverflow.com/a/21210966/89391
the_world_is_flat=true
# ...do something interesting...
if $the_world_is_flat ; then
echo 'Be careful not to fall off!'
fi
From: Bashでブール変数を使う
ここに元の回答が含まれるのは、2014年2月12日の改訂前のコメントは元の回答にのみ関連しており、改訂された回答に関連すると多くのコメントが間違っているためです。 2010年6月2日のbash組み込みtrue
については、元の回答にのみ適用され、改訂版には適用されません。
bool=true
if [ "$bool" = true ]
私は ではない 受け入れられた答えを推薦する1。その構文はきれいですが、いくつかの欠点があります。
次の条件があるとしましょう。
if $var; then
echo 'Muahahaha!'
fi
以下の場合2この条件は true と評価され、ネストされたコマンドが実行されます。
# Variable var not defined beforehand. Case 1
var='' # Equivalent to var="". Case 2
var= # Case 3
unset var # Case 4
var='<some valid command>' # Case 5
通常、あなたの "boolean"変数、この例ではvar
が明示的にtrueに設定されている場合にのみ、あなたの条件がtrueと評価されるようにします。他のすべての事件は危険なほど誤解を招きやすいです。
最後のケース(#5)は、変数に含まれるコマンドを実行するため(特に有効なコマンドに対して条件がtrueと評価される理由)、特に厄介です。3、4).
これは無害な例です。
var='echo this text will be displayed when the condition is evaluated'
if $var; then
echo 'Muahahaha!'
fi
# Outputs:
# this text will be displayed when the condition is evaluated
# Muahahaha!
あなたの変数を引用することはより安全です、例えばif "$var"; then
。上記の場合、コマンドが見つからないという警告が表示されます。しかし、私たちはまだもっと良いことができます(一番下の私の勧告を見てください)。
Mikuの最初の答えについてのMike Holtの説明も参照。
このアプローチも予期しない動作をします。
var=false
if [ $var ]; then
echo "This won't print, var is false!"
fi
# Outputs:
# This won't print, var is false!
上記の条件はfalseと評価されるため、入れ子になった文は実行されません。驚き!
値の引用("false"
)、変数の引用("$var"
)、または[[
の代わりにtest
または[
を使用しても違いはありません。
あなたの "booleans"をチェックすることをお勧めします。期待どおりに動作します。
bool=true
if [ "$bool" = true ]; then
if [ "$bool" = "true" ]; then
if [[ "$bool" = true ]]; then
if [[ "$bool" = "true" ]]; then
if [[ "$bool" == true ]]; then
if [[ "$bool" == "true" ]]; then
if test "$bool" = true; then
if test "$bool" = "true"; then
それらはすべてほぼ同等です。あなたは他の答えのアプローチよりもいくつかのキーストロークを入力する必要があります。5 しかし、あなたのコードはもっと防御的になるでしょう。
man woman
は有効なコマンドと見なされます。ここでは、Bashの組み込みtrue
について、さらに具体的には、Bashが括弧内の式を展開して解釈する方法について、いくつかの誤解があるようです。
miku's answer のコードは、Bashの組み込みtrue
、/bin/true
、その他のtrue
コマンドとはまったく関係ありません。この場合、true
は単なる文字列に過ぎず、変数の割り当てや条件式の評価のいずれでも、true
コマンド/組み込み関数の呼び出しは行われません。
次のコードは、mikuの回答のコードと機能的に同じです。
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
ここでのonlyの違いは、比較される4文字が「t」ではなく「y」、「e」、「a」、「h」であることです'、' r '、' u '、および' e '。それでおしまい。 yeah
という名前のコマンドまたはビルトインを呼び出そうとしたり、Bashがトークンtrue
を解析する際に特別な処理を行ったりすることはありません(mikuの例では)。これは単なる文字列であり、完全に任意の文字列です。
更新(2014-02-19):ミクの回答のリンクをたどると、混乱の原因がどこにあるかがわかります。ミクの答えは単一の括弧を使用していますが、リンク先のコードスニペットでは括弧を使用していません。それはただ:
the_world_is_flat=true
if $the_world_is_flat; then
echo 'Be careful not to fall off!'
fi
両方のコードスニペットはbehaveと同じ方法ですが、括弧は内部で行われていることを完全に変更します。
各ケースでBashが行っていることは次のとおりです。
括弧なし:
$the_world_is_flat
をストリング"true"
に展開します。"true"
をコマンドとして解析しようとしました。true
コマンド(Bashのバージョンに応じて、組み込みまたは/bin/true
のいずれか)を見つけて実行します。true
コマンドの終了コード(常に0)を0と比較します。ほとんどのシェルでは、終了コード0は成功を示し、それ以外は失敗を示します。if
ステートメントのthen
句を実行しますブラケット:
$the_world_is_flat
をストリング"true"
に展開します。string1 = string2
形式の完全に拡張された条件式を解析します。 =
演算子は、bashの文字列比較演算子です。そう..."true"
と"true"
で文字列比較を行います。if
ステートメントのthen
句を実行します。true
コマンドは成功を示す終了コード0を返すため、括弧なしのコードは機能します。 $the_world_is_flat
の値は、=
の右側にある文字列リテラルtrue
と同じであるため、括弧で囲まれたコードは機能します。
ポイントを家に戻すために、次の2つのコードスニペットを検討してください。
次のコード(root権限で実行した場合)はコンピューターを再起動します:
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
このコードは「ナイストライ」を出力します。再起動コマンドは呼び出されません。
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
更新(2014-04-14)=
と==
の違いに関するコメントの質問に答えるには、違いはありません。 ==
演算子は、=
のBash固有の同義語であり、私が見た限りでは、すべてのコンテキストでまったく同じように機能します。
ただし、=
または==
テストで使用される[ ]
および[[ ]]
文字列比較演算子について具体的に説明していることに注意してください。 =
と==
が交換可能であることを示唆しているわけではありませんeverywhereのbashです。
たとえば、==
などのvar=="foo"
を使用した変数の割り当ては明らかにできません(技術的にはcanですが、Bashには"=foo"
演算子が表示されないため、var
の値は==
になります)ここでは、=
(割り当て)演算子に続いて、リテラル値="foo"
が続きます。これは、単に"=foo"
になります)。
また、=
と==
は互換性がありますが、これらのテストの動作方法doesは、[ ]
または[[ ]]
内でテストを使用するかどうか、およびオペランドが引用符で囲まれているかどうかに依存することに注意してください。詳細については高度なBashスクリプトガイド:7.3その他の比較演算子(=
および==
の説明までスクロールしてください)で読むことができます。
算術式を使用してください。
#!/bin/bash
false=0
true=1
((false)) && echo false
((true)) && echo true
((!false)) && echo not false
((!true)) && echo not true
出力:
本当の
偽ではない
短い話:
Bashが持っているのは、比較と条件の点でブール式です。そうは言っても、bashで宣言し比較できるのは文字列と数値です。それでおしまい。
true
name__またはfalse
name__がbashで表示されているところはどこでも、その終了コードにのみ使用されるストリングまたはコマンド/組み込みのいずれかです。
この構文は...
if true; then ...
本質的には...
if COMMAND; then ...
コマンドが終了コード0を返すときはいつでも条件は真です。true
name__とfalse
name__はBashの組み込みであり、時には対応する終了コードを返す以外に何もしないスタンドアロンプログラムです。
上記の条件は、以下と同等です。
COMMAND && ...
角括弧またはtest
name__コマンドを使用するときは、その構文の終了コードに依存します。 [ ]
と[[ ]]
も、他のものと同様に単なるコマンド/ビルトインであることに留意してください。そう ...
if [[ 1 == 1 ]]; then echo yes; fi
に対応
if COMMAND; then echo yes; fi
そしてCOMMAND
name__はここで[[ 1 == 1 ]]
です
if..then..fi
構文は単なる構文上の糖です。同じ効果を得るために、コマンドをダブルアンパサンドで区切って実行するだけです。
[[ 1 == 1 ]] && echo yes
これらのテスト構成でtrue
name__およびfalse
name__を使用するときは、実際にはストリング"true"
または"false"
をテストコマンドに渡すだけです。ここに例があります:
信じられないかもしれませんが、これらの条件はすべて 同じ結果をもたらしています :
if [[ false ]]; then ...
if [[ "false" ]]; then ...
if [[ true ]]; then ...
if [[ "true" ]]; then ...
これを将来の読者に明確にするために、私は常にtrue
name__およびfalse
name__を引用符で囲むことをお勧めします。
if [[ "${var}" == "true" ]]; then ...
if [[ "${var}" == "false" ]]; then ...
if [[ -n "${var:-}" ]]; then echo "var is not empty" ...
if [ ... ]; then ... # always use double square brackets in bash!
if [[ "${var}" ]]; then ... # this is not as clear or searchable as -n
if [[ "${var}" != true ]]; then ... # creates impression of booleans
if [[ "${var}" -eq "true" ]]; then ... # `-eq` is for numbers and doesn't read as easy as `==`
if [[ "${var}" != "true" ]]; then ... # creates impression of booleans. Can be used for strict checking of dangerous operations. This condition is false for anything but the literal string "true".
昔、sh
しかなかったとき、test
プログラムの規則に基づいて処理されるブール値は、引数なしで実行するとtest
がfalse終了ステータスを返します。これにより、設定されていない変数がfalseであり、変数の値がtrueであると考えることができます。現在、テストはbash
に組み込まれており、1文字のエイリアス[
(またはドルメンが指摘しているように、それを持たないシェルで使用する実行可能ファイル)で一般的に知られています。
FLAG="up or <set>"
if [ "$FLAG" ] ; then
echo 'Is true'
else
echo 'Is false'
fi
# unset FLAG
# also works
FLAG=
if [ "$FLAG" ] ; then
echo 'Continues true'
else
echo 'Turned false'
fi
引用規則のため、スクリプト作成者はtest
を模倣するより良い構文を持つ複合コマンド[[
を使用することを好みます。スペースを含む変数は引用符で囲む必要はありません。&&
および||
奇妙な優先順位を持つ論理演算子として。用語の数にPOSIXの制限はありません。
たとえば、FLAGが設定されており、COUNTが1より大きい数値であるかどうかを判別するには、次のようにします。
FLAG="u p"
COUNT=3
if [[ $FLAG && $COUNT -gt '1' ]] ; then
echo 'Flag up, count bigger than 1'
else
echo 'Nope'
fi
このようなものは混乱を招く可能性があります スペース、長さゼロの文字列、null変数がすべて必要な場合、およびスクリプトが複数のシェルで動作する必要がある場合。
シェルスクリプトでブール変数を宣言して使用する方法
他の多くのプログラミング言語とは異なり、Bashはその変数を「タイプ」で区別しません。 [1]
だから答えはかなり明らかです。 bashにboolean variable
はありません。ただし、
宣言ステートメントを使用して、値の割り当てを変数に制限することができます。 [2]
#!/bin/bash
declare -ir BOOL=(0 1) #remember BOOL can't be unset till this Shell terminate
readonly false=${BOOL[0]}
readonly true=${BOOL[1]}
#same as declare -ir false=0 true=1
((true)) && echo "True"
((false)) && echo "False"
((!true)) && echo "Not True"
((!false)) && echo "Not false"
r
とdeclare
のreadonly
オプションは、変数が readonly であることを明示的に示すために使用されます。目的が明確であることを願っています。
ブール値を偽造して将来の読者のための罠を残す代わりに、なぜtrueとfalseよりも良い値を使わないのですか?
例えば:
build_state=success
if something-horrible; then
build_state=failed
fi
if [[ "$build_state" == success ]]; then
echo go home, you are done
else
echo your head is on fire, run around in circles
fi
Bill Parkerは、通常のコード規約とは定義が逆になっているため、 に投票されています。通常、trueは0として定義され、falseはゼロ以外として定義されます。関数の戻り値 - 0は成功、0以外は失敗です申し訳ありませんが、投票や直接返事をすることはできません。
Bashは、シングルブラケットの代わりにダブルブラケットを習慣として使用することを推奨します。MikeHoltが与えたリンクは、それらがどのように機能するかの違いを説明しています。7.3。その他の比較演算子
一つには、-eq
は数値演算子なので、コードは
#**** NOTE *** This gives error message *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
整数式を期待してエラーステートメントを発行します。どちらも整数値ではないため、これはどちらのパラメータにも当てはまります。しかし、二重括弧を囲むと、エラーステートメントは発行されませんが、間違った値になります(可能な順列の50%)。 [[0 -eq true]] = successと評価されますが、[[0 -eq false]] = successと評価されますが、これは間違っています(hmmm ....その組み込み関数は数値ですか?)。
#**** NOTE *** This gives wrong output *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then
同様に間違った出力を与える条件の他の置換があります。基本的に、変数を数値に設定してそれをtrue/false組み込み関数と比較するか、または変数をtrue/false組み込み関数と設定してそれを数値と比較するもの(上記のエラー条件以外)。また、変数をtrue/false組み込みに設定し、-eq
を使用して比較を行うものすべて。そのため、ブール比較では-eq
を避け、ブール比較では数値の使用を避けます。無効な結果になる順列の概要は次のとおりです。
#With variable set as an integer and evaluating to true/false
#*** This will issue error warning and not run: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
#With variable set as an integer and evaluating to true/false
#*** These statements will not evaluate properly: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
#
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" == true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then
#With variable set as an true/false builtin and evaluating to true/false
#*** These statements will not evaluate properly: *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = 0 ]; then
#
if [[ "${The_world_is_flat}" = 0 ]]; then
#
if [ "${The_world_is_flat}" == 0 ]; then
#
if [[ "${The_world_is_flat}" == 0 ]]; then
だから、今何がうまくいくか。比較と評価の両方にtrue/falseビルトインを使用します(Mike Huntが指摘したように、引用符で囲まないでください)。次に、シングルまたはダブルの等号(=または==)とシングルまたはダブルかっこ([]または[[]])のいずれかを使用します。個人的には、私は二重等号が好きです。なぜならそれは他のプログラミング言語における論理的な比較を思い出させるからであり、そして私がタイプするのが好きだからという理由だけで二重引用符です。だからこれらの仕事:
#With variable set as an integer and evaluating to true/false
#*** These statements will work properly: *****
#
The_world_is_flat=true/false;
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then
そこにあります。
多くのプログラミング言語では、ブール型は整数のサブタイプであるか、整数のサブタイプとして実装されます。ここで、true
name__は1
のように動作し、false
name__は0
のように動作します。
数学的に 、ブール代数は2を法とする整数演算に似ています。したがって、言語がネイティブのブール型を提供しない場合、最も自然で効率的な解決策は整数を使用することです。これは、ほぼすべての言語で機能します。たとえば、Bashでは次のことができます。
# val=1; ((val)) && echo "true" || echo "false"
true
# val=0; ((val)) && echo "true" || echo "false"
false
man bash :
((式))
式は、以下の算術評価で説明されている規則に従って評価されます。式の値がゼロ以外の場合、戻りステータスは0です。それ以外の場合、戻りステータスは1です。これはlet "expression"とまったく同じです。
ここで重要なポイント、つまり移植性が欠けています。それが私のヘッダが _ posix _ を持つ理由です。
基本的に、投票された答えはすべて正解ですが、例外として、 _ bash _ - 固有のものが多すぎます。
したがって、基本的には、移植性についての情報を追加したいだけです。
[
のように]
と[ "$var" = true ]
の括弧は必要ありません。それらを省略してtest
コマンドを直接使用することができます。
test "$var" = true && CodeIfTrue || CodeIfFalse
true
とfalse
がシェルにとって何を意味するのか想像してみてください。自分でテストしてください。
echo $((true))
0
echo $((false))
1
しかし引用符を使う:
echo $(("true"))
bash: "true": syntax error: operand expected (error token is ""true"") sh (dash): sh: 1: arithmetic expression: expecting primary: ""true""
同じことが言えます。
echo $(("false"))
シェルはそれを文字列以外に解釈することはできません。適切なキーワードなし _引用符を使用すると、どれだけ優れているかというアイデアが得られることを願っています。
しかし、誰も前の答えでそれを言いませんでした。
これはどういう意味ですか?まあ、いくつかのこと。
ブール値のキーワードは、実際には数字のように扱われます。つまり、true
= 0
およびfalse
= 1
です。ゼロ以外の値はすべてfalse
のように扱われます。
それらは数字のように扱われるので、あなたもそれらをそのように扱うべきです。
var_a=true
echo "$var_a"
true
逆の値を作成することができます:
var_a=$((1 - $var_a))
echo "$var_a"
1
ご存じのように、Shellはtrue
という文字列を初めて使用するときには印刷しますが、それ以降は、それぞれ番号0
または1
を介して機能します。
最初の良い習慣はtrue
の代わりに0
を割り当てることです。 false
ではなく1
。
2番目の習慣は、変数がゼロであるかどうかをテストすることです。
test "$var" -eq 0 && CodeIfTrue || CodeIfFalse
これは短いif true
の実装です。
# Function to test if a variable is set to "true"
_if () {
[ "${1}" == "true" ] && return 0
[ "${1}" == "True" ] && return 0
[ "${1}" == "Yes" ] && return 0
return 1
}
例1
my_boolean=true
_if ${my_boolean} && {
echo "True Is True"
} || {
echo "False Is False"
}
例2
my_boolean=false
! _if ${my_boolean} && echo "Not True is True"
これが私のために働く簡単な例です:
temp1=true
temp2=false
if [ "$temp1" = true ] || [ "$temp2" = true ]
then
echo "Do something."
else
echo "Do something else."
fi
これはmikuの 元の答え を改良したものです。これは Dennis Williamson が変数が設定されていない場合についての懸念に対処します。
the_world_is_flat=true
if ${the_world_is_flat:-false} ; then
echo "Be careful not to fall off!"
fi
そして変数がfalse
であるかどうかをテストするために:
if ! ${the_world_is_flat:-false} ; then
echo "Be careful not to fall off!"
fi
変数に厄介な内容が含まれている他のケースについては、これはプログラムに供給される外部入力に関する問題です。
信頼する前に、外部入力を検証する必要があります。しかし、その検証はその入力が受け取られたときに一度だけ行われなければなりません。
Dennis Williamson のように変数を使用するたびにプログラムの実行に影響を与える必要はありません。
私は既存の答えが分かりにくいと感じました。
個人的には、Cのように見えて動作するものが欲しいのです。
このスニペットは、プロダクションで1日に何度でも動作します。
snapshotEvents=true
if ($snapshotEvents)
then
# do stuff if true
fi
そしてみんなを幸せに保つために、私はテストしました:
snapshotEvents=false
if !($snapshotEvents)
then
# do stuff if false
fi
どれもうまくいきました。
$snapshotEvents
は、変数の値の内容を評価します。だからあなたは$
が必要です。
あなたは本当に括弧を必要としません、私はそれらが役に立つと思います。
テスト済み:GNU Bash、バージョン4.1.11(2) - リリース
初心者向けBashガイド 、Machtelt Garrels、v1.11、2008
私の調査結果と提案は他の記事とは少し異なります。私は基本的に「フープジャンプ」が示唆されることなしに、「普通の」言語のようにtrue/falseを使うことができることを知りました。 bash、ダッシュ、およびbusybox。私は彼女が強打してもしなくても走った…結果はいつも同じだった。元のトップ投票投稿が何について話しているのかわかりません。たぶん時代は変わった、そしてそれはそれにあるすべてであるか?
変数をtrue
に設定すると、条件付きではtrueと評価されます。それをfalse
に設定すると、falseと評価されます。とても簡単です。唯一の注意点は、 _ undefined _ 変数も true !と評価されることです。それが逆であればいいでしょうが、それはトリック - あなたは単にブール値をtrueまたはfalseに明示的に設定する必要があります 。
下記の例のbashと結果を参照してください。確認したい場合は自分でテストしてください。
#!/bin/sh
#not yet defined...
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;
myBool=true
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;
myBool=false
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;
収量
when set to
it evaluates to true
when set to true
it evaluates to true
when set to false
it evaluates to false
GFlagsを使用できます。 https://gflags.github.io/gflags/
以下を定義するオプションを提供します:DEFINE_bool
例:
DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");
コマンドラインから以下を定義できます:
sh script.sh --bigmenu
sh script.sh --nobigmenu # False