typeset -f は実際の定義を出力しません。検出/修正できますか?

typeset -f は実際の定義を出力しません。検出/修正できますか?

このバグが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_aliasesaliastypeset -f

これを使用して、このエラーや他のエラーによって引き起こされる構文エラーを検出できますが、上記の考慮事項は完全ではないだけでなく、エラーが誤って有効なコードを生成する可能性があるためです。

関連情報