今週bashを学んでいて、ひっかかった。
#!/bin/sh
if [ false ]; then
echo "True"
else
echo "False"
fi
条件がそうでないことを示している場合でも、これは常にTrueを出力します。ブラケット[]
を削除すると機能しますが、理由はわかりません。
引数__falseを指定して[
(別名test
)コマンドを実行していますが、コマンドfalse
は実行していません。 「false」は空でない文字列であるため、test
コマンドは常に成功します。コマンドを実際に実行するには、[
コマンドをドロップします。
if false; then
echo "True"
else
echo "False"
fi
if
ステートメントは引数としてコマンドを受け取ります(&&
、||
などと同様)。コマンドの整数結果コードはブール値(0/null = true、1/else = false)として解釈されます。
test
ステートメントは演算子とオペランドを引数として取りますで、if
と同じ形式で結果コードを返します。 test
ステートメントのエイリアスは[
です。これは、if
とともに使用され、より複雑な比較を実行します。
true
およびfalse
ステートメントは何もせず、結果コードを返します(それぞれ0および1)。そのため、Bashでブールリテラルとして使用できます。しかし、文字列として解釈される場所にステートメントを配置すると、問題が発生します。あなたの場合:
if [ foo ]; then ... # "if the string 'foo' is non-empty, return true"
if foo; then ... # "if the command foo succeeds, return true"
そう:
if [ true ] ; then echo "This text will always appear." ; fi;
if [ false ] ; then echo "This text will always appear." ; fi;
if true ; then echo "This text will always appear." ; fi;
if false ; then echo "This text will never appear." ; fi;
これは、echo '$foo'
とecho "$foo"
のようなことを行うことに似ています。
test
ステートメントを使用する場合、結果は使用する演算子によって異なります。
if [ "$foo" = "$bar" ] # true if the string values of $foo and $bar are equal
if [ "$foo" -eq "$bar" ] # true if the integer values of $foo and $bar are equal
if [ -f "$foo" ] # true if $foo is a file that exists (by path)
if [ "$foo" ] # true if $foo evaluates to a non-empty string
if foo # true if foo, as a command/subroutine,
# evaluates to true/success (returns 0 or null)
略して、何かを成功/失敗(別名「true」/「false」)でテストしたい場合は、括弧なしでif
または&&
などのステートメントにコマンドを渡します。複雑な比較の場合は、適切な演算子で角括弧を使用します。
そして、はい、Bashにはネイティブのブール型のようなものは存在しないこと、そしてif
と[
とtrue
は技術的に「コマンド」であり、「ステートメント」ではないことを知っています。これは非常に基本的な機能説明です。
私は次のようなものを実行することでいくつかの基本的なロジックを実行できることがわかりました。
A=true
B=true
if ($A && $B); then
C=true
else
C=false
fi
echo $C
True/falseを使用すると、一部のブラケットクラッタが削除されます...
#! /bin/bash
# true_or_false.bash
[ "$(basename $0)" == "bash" ] && sourced=true || sourced=false
$sourced && echo "SOURCED"
$sourced || echo "CALLED"
# Just an alternate way:
! $sourced && echo "CALLED " || echo "SOURCED"
$sourced && return || exit