このバグがBashに存在することを発見するのに昨日はほとんど時間がかかりました。
outer ()
{
function inner ()
{
cat <<_EOS
foo
_EOS
}
inner
}
次のように表示されますtypeset -f outer
。
outer ()
{
function inner ()
{
cat <<_EOS
}
foo
_EOS
inner
}
これは明らかに異なります。 CygWin(bash 4.4.12)では、出力エラーが異なる方法で発生します。
outer ()
{
function inner ()
{
cat
} <<_EOS
foo
_EOS
inner
}
このバグは、最新バージョンのBashで修正されました。
私はこれを使用してenv_parallel
...env_parallel
出力がtypeset -f
正しいかどうかによって異なります。
env_parallel
これはコーナーケースのバグなので、結果に影響を与える可能性がある実際のリスクがない限り、警告を発行したくありません。一方、実際のリスクがある場合は、昨日のように欲求不満を感じたくないので、ユーザーは警告を受けたいと思います。
出力にバグがある場合は、これを確実に検出できますかtypeset -f
? bashパーサーを書かなくても修正できますか?
答え1
一部のコードが構文的に有効であることを確認できます。
if bash -O extglob -n < some-code 2> /dev/null; then
echo that seems valid
fi
ただし、構文はextglob
、エイリアス、ロケール設定(LC_CTYPEカテゴリ)、およびbashのオプションによって影響を受ける可能性があります。
たとえば、コードスニペットは、onが使用されている場合は有効ですが、そうでない場合は有効ではない可能性がありますextglob
(たとえば)、通常は逆である可能性があるため、onを使用して構文を確認することをお勧めしますecho @(x)
。extglob
コードスニペットは、変数名の有効な文字と同様に、あるロケールでは有効ですが、別のロケールでは無効です($'\xe9=(x)'
そのロケールでは有効fr_FR.iso88591
ですが、UTF-8ロケールまたはCロケールでは無効です)。 (トークン区切り文字としても使用できます!))はロケールによって異なります(したがって、バージョンがtypeset -f
異なるか、同じシステム上の同じロケールで実行されない別のbash呼び出しの出力を提供することもしばしば危険です)。
alias forever='while true; do'
forever echo test; done
はvalidとして報告されますが、コマンドが実行されると2行目が有効になるためではbash -n
ありません。ただし、これは出力構文を確認しても問題ではありません。bash -O expand_aliases
alias
typeset -f
これを使用して、このエラーや他のエラーによって引き起こされる構文エラーを検出できますが、上記の考慮事項は完全ではないだけでなく、エラーが誤って有効なコードを生成する可能性があるためです。