エラーメッセージのプレフィックスやリダイレクトのためのprintfなどの操作のためのラッパー

エラーメッセージのプレフィックスやリダイレクトのためのprintfなどの操作のためのラッパー

私のPOSIXシェルコードerrorに関数があります。sh本質的には

error () {
    printf 'utility: ERROR: ' >&2
    printf "$@" >&2
}

2番目は、printfたとえば関数を呼び出すことを可能にします。

error 'Something relating to "%s" went wrong!\n' "$thing"
exit 1

この関数はメッセージの前に文字列を追加し、utility: ERROR:すべてのエントリが標準エラーで送信されるように準備します。しかし、まだprintf

確かに、住宅検査二人目に文句をprintf言う。

SC2059:printf形式の文字列に変数を使用しないでください。 printf "..%s.." "$foo" を使用してください。

私がしたことをしてこの警告を無視するのは「安全」ですか?障害を負う# shellcheck disable=SC2059コードにコメントがありますか?)私はいつも私のerror機能を使います。正確にそれ以外の場合を使用してくださいprintf。つまり、最初のパラメータに静的一重引用符を使用します。

「安全ですか?」ここでの意味は、「私の機能はprintf(リダイレクトに加えて)同様の操作のラッパーとして適切な方法で動作しますか?」です。

答え1

ここで型をパラメータとして渡そうとするので、これは安全です。ただし、関数を使用するときは型であることを覚えておく必要があります。したがって、関数名をerrorfリマインダーとして指定する必要があるかもしれません。

次のように使用する場合:

error "invalid arg: $arg"

$arg次のような問題が発生します。%99999999s

理想的にはshellcheckに無視するように指示したいと思います。printf そしてprintf最初のパラメータに含まれる変数の使用法を表示できます。

いくつかの注意:

  • 2回呼び出したので、printf少なくとも2回のwrite()システムコールがあります。何の違いもないようです。printfsなどの一部の実装では、いくつかのシステムコールを実行することがあります。bashそんな種類質問私が念頭に置いたのは、エラーメッセージの2つの部分が並列に実行される他のコマンドの出力と絡み合っていることです。
  • プレフィックスのerror "%s\n" error1 error2最初のエラーのみが印刷されます。そうしたいなら大丈夫です。次のようにすることもできます。

    errorf() { printf "utility: ERROR: $@" >&2; }
    

    フォーマットを再利用するたびに出力されるように、フォーマットにプレフィックスを追加します。 (これを行うと、いくつかの問題も解決されます。)write() 質問)。

    utilityしかし、変数になりたい場合は機能しません。

    PROG_NAME=${0##*/}
    errorf() { printf >&2 "$PROG_NAME: エラー: $@" }
    
    いいえ。またはを$0含めると%失敗するためです\

    そして

    PROG_NAME=${0##*/}
    間違い(){
    フォーマット= $ 1;送信
    printf >&2 "%s: エラー: $format" "$PROG_NAME" "$@"
    }
    再利用された形式の場合は機能しません(そして、ユーザーが指示を1つずつオフセットする必要があることを意味します%<n>$d(この指示は移植性がないため使用することをお勧めします))。

    \and を手動でエスケープする%$PROG_NAMEprintf0x5c\

関連情報