14歳の自分に衝撃の事実を告げてください

以下のシェルスクリプトで、

#!/bin/sh
ls texistdir 2> /dev/null
ret=$?
[ "$ret" -eq "0" ] || echo "error: $ret"

でtexistdirが存在する場合、
上の場合、$retが数値の0で、"$ret"で文字列の0に変換されてイコールが成立すると思うのですが、
また、
[ $ret -eq 0 ]
の場合は、両方とも数値なので条件が成立すると思うのですが、
[ "$ret" -eq 0 ]

[ $ret -eq "0" ]
も条件が成立しているようなのですが、
この書き方では、数値と文字列は区別されないと理解して良いのでしょうか?

A 回答 (2件)

シェルスクリプトは仕組みとして、文字列だけしか扱えないので、区別などしようがありません。



$? や $ret などは、パラメーター展開された文字列です
引用符で囲ったものは、クォート除去された文字列です
囲ってないものは、単語分割された複数の文字列です

test コマンドにとっては 0 も "0" も $ret も "$ret" も、パラメーター展開やクォート除去された文字列として受け取ることになります。

例)
test $ret -eq "0"
test, $ret, -eq, "0" ← 単語分割
test, 0, -eq, "0" ← パラメーター展開
test, 0, -eq, 0 ← クォート除去
→ /usr/bin/test の引数として [ "test", "0", "-eq", "0" ] が渡される
    • good
    • 0
この回答へのお礼

ご説明、ありがとうございます。

お礼日時:2022/08/13 14:26

$? は文字列です。

詳しく言うと、直前のコマンドのリターンコードの数値を10進数表現の文字列に変換した物です。
シェルの場合、目で見える物はずべて文字列です。
「0は数値で"0"は文字列」というのは多くのプログラミング言語では正しいのですが、シェルの場合はどちらも文字列です。" " ' ' のような引用符はシェルからコマンドに渡る時に取り除かれますので、
[ $ret -eq 0 ] [ "$ret" -eq 0 ] [ $ret -eq "0" ] [ "$ret" -eq "0" ] はどれもtestコマンドに渡る時には、[ 0 -eq 0 ] となっており、同じです。

A=1
let A=A+2
echo $A
とすると3が表示されます。「この場合はAは数値だろ」と思うかもしれませんが、let A=A+2 は、Aの中身の文字列を数値化した物と2という文字列を数値化した物を足した結果の数値を文字列化してAに代入します。つまり、目に見える物は全て文字列です。
    • good
    • 0
この回答へのお礼

ご説明、ありがとうございます。

お礼日時:2022/08/13 14:26

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報