単純なシェルスクリプトで2つの文字列を比較しようとしています。私は/bin/sh
の代わりに/bin/bash
を使用していましたが、数え切れないほどのデバッグ時間の後、sh(実際にはダッシュです)はこのコードブロックを処理できないことがわかります。
if [ "$var" == "string" ]
then
do something
fi
/bin/sh
を使用して文字列を比較するポータブルな方法は何ですか?私は!=を使用して常に反対のことができることを知っていますが、よりクリーンでポータブルな方法について疑問に思っています。
dash
は非常に厳密なPOSIXシェルです。dash
で動作する場合、他のPOSIXシェルでも動作することはほぼ確実です。
試してください:
if [ "$var" = "string" ]
then
some_command
fi
スクリプトが「間違った」シェルによって実行される可能性さえあるのはなぜですか?スクリプトの上部にある標準のsh-bang行を使用して、製品の必須条件にすることができると思います。
#!/bin/bash
ユーザーが別のシェルsesを使用している場合でも、他のシェルは通常はまだ存在し、そうでない場合は、単に不満を示して前提条件であることを述べます。
特定のカーネルレベルまたはawkの存在が前提条件になることができるのとまったく同じ方法。
あなたの特定の質問については、sh
とbash
の両方で、単一の '='を文字列比較に使用できると考えています。つまり、POSIXの動作です。
if [ "a" = "a" ] ; then
echo yes
fi
yes
=
の代わりに==
を使用してください。比較はtest(1)によって処理されます。 /usr/bin/[
は通常、/usr/bin/test
へのリンクです。唯一の違いは、シェルスクリプトで[
を使用する場合、]
も必要であることです。
Bashにはtest
/[
が組み込まれているため、実際には/usr/bin/test
を使用しないことに注意してください。
すでに投稿されている答えは確かに正しいですが、場合によっては、パラメーターの拡張が同じ目的を果たし、おそらくいくつかの追加の柔軟性が得られることに注意することは価値があります。
% p() { printf 'notvar = %b\n' "${notvar##"${string1}"}${string2}" ; }
% string1='some stuff about things\c'
% string2='some different stuff maybe'
% notvar="$string1" p
> 'some different stuff maybe'
% notvar="$string2" p
> 'some stuff about things'
わかりましたので、上記はそのままではあまり役に立ちませんが、同様の方法を使用して、ヒアドキュメントの変数をテストしたり、必要に応じてインライン変数の割り当て(ある程度)をテストしたり、さらには短い(そして速い!)と同じように、最初のステートメントを記述します。
[ ! "${var##"string"}" ] && _MATCH || _NOMATCH
あるいは...
[ ${#var#*"${s=string}"} -lt ${#var} ] && _SUB_STRING_TEST=TRUE
たぶん...
% p() { printf '%s is %s of %s' "$2" "${var_chk-not}" "$1"
> }<<HEREDOC
> ${in="${1##*"${2}"*}"}
> ${in:-
> ${in="${1##"${2}"}"}
> ${in:-${var_chk=all}
> ${var_chk=some}
> }
> HEREDOC
%