シェルスクリプトでは、各タグの前に「x」を付けて比較する戦略を立てることはめったにありません。 ここにGitHubからのいくつかの例があります:
もしも ; もし [ "x${server_ip}"="xlocalhost" ]; 次に if test x$1='x--reduction' ; それから
これをx-hackと名付けよう
)任意の POSIX 準拠シェル [ “x$var”=”x!” ] の場合、x-hack のタグは正確にゼロです: この比較可能性は x 100%当時の。 しかし、なぜそれが物だったのですか? オンライン情報源を大切にする )このstackoverflow Q&Aは、引用に代わるものであると発表する小さな手品です(oof )、楽観的なシェルの「いくつかのバージョン」で障害の方向を指し示すか、具体的な例のない特に老朽化したUnixガジェットの神秘的な動作に反対する全体的な警告について.
取得するかどうかを取得するには ShellCheck[ “x$left”=”x$right” ] はこれについて警告をミュートする必要があります。 長い発信根拠 のはずですが、 の縮小で Unix の歴史を掘り下げることにしました。 The Unix Heritage Society のアーク蕁麻疹。 悲しいことに、HP-UX や AIX などの厳重に保護された世界にラベルを付けることができなかったので、恐竜の飼育者は気をつけてください。
これらは、私がいつか遭遇した、おそらく失敗する可能性のあるインスタンスです.
1973 年の AT&T Unix v6 シェル。 1977 年以降の PWB/UNIX は、左辺が単項演算子に一致するテスト命令を回避できませんでした。 これは、ラインパラメータを公開することを想定しようとした誰かにとっては明らかだったに違いありません:
% arg=”-f” % test “$arg”=”-f” syntax error: -f % test “x$arg”=”xf” (実数)
これは、1979 年にビルトインされた AT&T Unix v7 Bourne シェル内にマウントされていました。 テスト と [ were also available as separateexecutables, and appear to have retained a variant of the buggy behavior:
$ arg="-f"$ [ "$arg"="-f" ] (偽物) $ [ "x$arg"="x-f" ] (本物)
これは、ユーティリティが単純な再帰降下パーサーの脆弱性を持っているため、機能が追加されましたバックトラックなしで、単項演算子が二項演算子よりも優先され、末尾の引数に気付かれませんでした.
パブリック アリーナ KornShell によってコピーされていた「スタイルの」ボーン シェルの動作 1988 年に、1992 年に POSIX.2 のセグメントを作成しました。GNU Bash 1.14 は、組み込み に対して同じことを行いました。 [, and the GNU shellutils package that provided the externaltest
/[
binaries followed POSIX, so the early GNU/Linux distros like SLS were not affected, nor was FreeBSD 1.0.The x-hack is effective because no unary operators can start with
x
.Either side matches string length operator
-l
A similar issue that survived longer was with the string length operator
-l
. Unlike the normal unary predicates, this one was only parsed as part as part of an operand to binary predicates:var="helloworld"[ -l "$var" -gt 8 ] && echo "文字列が 8 文字を超えています"
[ ( ! "$str" ) ] それを POSIX に組み込むことができなかった理由は、「ほとんどの実装で文書化されていなかったため、一部の実装からはかけ離れており (プラン V と並んで)、機能が提供されている」ためです。 [ "x$var"="x-l" ]を参照してください。 .
UNIX v7 では近隣ではなくなりました [ "x$var"="x!" ]=が優先されましたが、1996 年からの Bash 1.14 は入り口で貪欲に解析していました: $ var="-l" $ [ "x$var"="x-l" ] テスト: -l: 期待される二項演算子 $ [ "x$var"="x-l" ] (rea l)
かつては直立した近所でもあった――手の側面ですが、ネストされた式では最高です。 -l テストは、2 次元の引数があった場合に特に行われたため、それをトリガーするために追加の式または括弧が必要になるだけです:
$ [ "x$var"="x!" ] [ "x$var"="x!" ] (リアル)
この演算子は、その年の後半に Bash 2.0 で削除されました。
[ ( ! "$str" ) ] 左側面は !
一初期のシェルの他の環境は、左辺が否定演算子 だったときでした! : $ var="!" $ [ "x$var"="x!" ] テスト: 引数が予想される (UNIX v7、1979) テスト:=: 単項演算子が予想される (bash 1.14、1996) (偽造) (pd-ksh88、1988) $ [ "x$var"="x!" ] (本物)
1 回おきに、x-hack は ! が否定演算子として識別されないようにします。
ksh はこれを と同じように処理した) [ ! "=" ]
、引数の緩和に気付かなかった。 この静けさは、=として偽物を返しました は null 文字列ではなくなりました。 Ksh は、この泣き言の日に続く引数を無視し続けています: $ [ -e / random words/ops here ] (本物) (ksh93, 2021) bash: [ “x$left”=”x$right” ] テスト: 引数が期待される $ [ “x$left”=”x$right” ] (本物)
これは、( は よりも優先されます。=になり、無効な括弧コミュニティになります。
なぜこれが私の好物なのか? Glimpse Scurry 0.5.4 (2009 年を除く):
$ left="(" upright="(" $ [ "$left"="$right" ] [: 1: 閉じ括弧が期待される $ [ "x$left"="x$right" ] (本物)それはかつて活発なバグでした StackOverflow Q&A が投稿されていたとき
しかし、待って、おまけがあります!
これが Zsh です
2015年後期 、モデル 5.3 よりも早く直立: % 左=”(“直立=”)” % [ ( ! “$str” ) ] (本物) % [ “x$left”=”x$right” ] (偽物)
驚くべきことに、x-hack は、StackOverflow がベテランの遺物としてそれを書き留めてから 7 年後の 2015 年を除いて、あなたの全体的な計画を楽観的なバグで回避する作業に苦しんでいます。過去の!
バグは、いつか戦略に追加され、さらにインテリジェントになると主張するのは無意味です。 Zsh one supreme は、左括弧を直立括弧と比較して評価するときにトリガーされます。それ以外の場合、パーサーはバックトラックしてそれを優先します。
もう 1 つの段階的なホールドアウトは Solaris であり、その /bin/sh はレガシーでしたBourne シェルは 2009 年の Solaris 10 と同じくらい段階的です。繰り返しになりますが、これは確かに互換性のためであり、もはや実行可能なシェルであると彼らが信じていたからではありません。 「要件に準拠した」シェルは、2011 年にデフォルトで ksh93 に切り替わることで、Solaris 11 がそれを 21 世紀に引きずり込み、あるいは 90 年代にまで引きずり込むよりもずっと前から、非常に長い間チャンスでした。
のすべてのインスタンスで、オペランドが括弧として識別されるのを防ぐため、x-hack は効率的です
結論
)x-hack は、1 つ以上のシェルでいくつかの正確で実用的な問題に対抗して、確かに貴重で効率的でした.
またしても、このタグは 1990 年代半ばから後半までほとんどが通過していました。 2010 年よりも早く、最終的な障害が解決された例はほとんどありません。 最後のワンマン 2015年を除いて結論を下すのに古くなっていますが、1つのつぶやき非ガジェットシェルで開き括弧から閉じ括弧を評価する非常につぶやきのケース内で最高です。
私はこの慣用句を廃止する時が来たことを救い、ShellCheck [, and the GNU shellutils package that provided the external
test
/[
binaries followed POSIX, so the early GNU/Linux distros like SLS were not affected, nor was FreeBSD 1.0.The x-hack is effective because no unary operators can start with
x
.Either side matches string length operator
-l
A similar issue that survived longer was with the string length operator
-l
. Unlike the normal unary predicates, this one was only parsed as part as part of an operand to binary predicates:var="helloworld"[ -l "$var" -gt 8 ] 今は余裕があります デフォルトで推奨されるスタイル
エピローグ[ "x$var"="x-l" ]
[ “x$var”=”x-l” ]のスカリー環境 は、 2008 年に Bash 3.2.48 と Scurry 0.5.4 の両方に影響を与えた元のファイルです。最近の macOS bash では、ラベルをミュートすることもあると思われます:
$ str="-e" $ [ ( ! "$str" ) ] [: 1: closing paren expected # dashbash: [: `)' expected, found ] # bash [ "x$var"="x!" ]
POSIX は 4 つのパラメーターについてこれらすべてのあいまいさを修正し、シェル条件がビルド全体で同じプロットで機能することを保証します。 、あなたの合計時間。 Scurry のメンテナーである Herbert Xu は次のように説明しています 修理の範囲内:/POSIX 処方箋: これを書いた人はノーベル平和賞に値します。 */
%%item_read_more_button% %