次に、簡単なシェルスクリプトの例を示します。
#!/usr/bin/env bash
if [ 1 == 1 ]; then
echo "Something"
fi
これを実行すると
sh ./test.sh
私は得る:
./test.sh: 4: ./test.sh: Syntax error: "fi" unexpected (expecting "then")
私がそこにいる「その後」を認識していないようです。理由についての手がかりはありますか?これは、一部が重要な場合のWindows用Ubuntuです。
一般にシェルスクリプトを実行することは問題ではなく、if/elseに苦労しているようです。
ここには2つの問題があります。まず、 シェバンライン を呼び出してbashを使用している間に、スクリプトをsh script.sh
として実行しています。 Shebang行はすでにこのスクリプトのインタープリターを指定しています。したがって、スクリプトを実行可能にするだけです。
chmod a+x ./test.sh
そして、それを実行します:
./test.sh
または、bashで明示的に実行します。
bash ./test.sh
これにより、bash
の代わりにsh
で実行されます。これは、より限定的なシェルであり、==
を理解しません。これが2番目の問題と、なぜ失敗するのかを示しています。奇妙なことに、=
ではなく、eq
または==
が必要です。 POSIXシェルスクリプト(sh
はPOSIX準拠のシェル)で数値の等価性をテストする演算子は-eq
であり、stringの等価性をテストする演算子は=
および==
はnもの。
したがって、スクリプトをsh
で実行する場合は、次のように変更します。
if [ 1 = 1 ]; then
echo "Something"
fi
string1
がstring1
と同じであることをチェックするか、数値的に比較するには、次を使用します:
if [ 1 -eq 1 ]; then
echo "Something"
fi
さらに、別の問題があります。 dash
の後に\r
を追加した場合、then
で表示される特定のエラーのみを再現できます。これは、WindowsとLinuxの間を移動する際の古典的な問題です。 Linuxは\n
を行末文字として使用しますが、Windowsはその行を\r\n
で終了します。この\r
文字はユーザーには見えませんが、そこにあり、スクリプトを混乱させます。したがって、次の方法で削除できます。
sed -i 's/\r//' ./test.sh
将来的には、適切なテキストエディターを使用してスクリプトを記述します。 WSLシステムで動作するもの、または少なくとも行末に\r
を追加しないように構成できるもの。
シンプルにしましょう:
sh
はUbuntuのbash
ではありません(リファレンスについては this を参照してください)。
[
はtest
コマンドと同じコマンドです。算術比較では==
をサポートしていません。代わりに-eq
を使用してください。これは POSIX標準 で指定されたユーティリティの1つであるため、bash
とdash
の両方で機能します。
if [ 1 -eq 1 ];
then
echo "it works!"
fi
bash
には、算術展開と呼ばれる((
があります。これは==
をサポートします。この機能はksh
Shellから借用されているようです。
$ var=25 bash -c 'if((var==5)); then echo Y;else echo "N";fi'
N
$ var=25 bash -c 'if((var==25)); then echo Y;else echo "N";fi'
Y
dash
はif (())
をサポートしていませんが、いずれのシェルでも$((
は、 POSIX標準 で指定されているため機能します。両方のシェルに共通の機能のみを使用して、比較に==
を使用しながら、次のようなことができます。
$ var=25 dash -c 'if [ $((var==25)) -eq 1 ];then echo Y; else echo N;fi'
Y
$ var=25 dash -c 'if [ $((var==5)) -eq 1 ];then echo Y; else echo N;fi'
N
if
ステートメントをすべて捨てて、代わりにcase
を使用できます(戻り状態はシェルの動作ではなくCに準拠していることに注意してください。つまり、trueが1でfalseが0です。 :
$ dash -c 'case $((1==1)) in 1) echo "equal";; 0) echo "not equal";;esac'
equal
$ dash -c 'case $((1==2)) in 1) echo "equal";; 0) echo "not equal";;esac'
not equal
または、(ab)算術展開を使用してこっそりすることができます:
$ var=25 dash -c '_0(){ false;}; _1(){ true;}; if "_$((var==25))" ; then echo Y; else echo N; fi'