0

大きなシェル スクリプトを作成するために使用する簡単な debug_print シェル関数があります。一般的に、私は Bourne 互換のスクリプトのみを作成し、Bash 主義を避けるようにしています。この場合、私の debug_print 関数の Bash バージョンは正常に動作しますが、私の Bourne 互換バージョンが失敗する理由を一生理解できません。具体的には、printf で %s フォーマット修飾子を使用する際に問題が発生します。

以下にテストスクリプトを含めました。debug_print 関数は、ラベル付きのヘッダー バー、その文字列またはファイル引数の内容、最後にヘッダーと同じ幅のフッター バーを表示します。問題はフッター バーの表示にあり、「フッター行を表示する...」というコメントで始まります。それに続くコメントされていない2行は、うまくいくと私が信じているものですが、うまくいきません。

それに続いて、「None of these work」コメントの下にいくつかのコメント行があり、問題を解明しようとしているときに使用したさまざまなテスト/分散の一部を確認できます。これらの行の後に、動作する Bourne バージョンがあり、最後に動作する Bash バージョンがあります。

私はマンページを詳細に読み、思いつく限りのさまざまなフォーマット文字列、引用、および変数の使用を試しました。これまでのところ、これらの試みはどれも正しく機能していません。「これらの機能はありません」というコメントの下で、機能しないコマンドはすべて、フィールド幅修飾子で指定された文字数だけではなく、文字列全体を出力します。

「Bourne 互換性」を判断するために、私のシステムではダッシュを /bin/sh として使用します。これは Debian システムの典型です。Dash は効率的なスクリプトの実行を目的としており、インタラクティブな使用を目的としていません。マンページによると、Bourne との厳密な互換性を目指して努力しているため、私のスクリプトがダッシュで動作する場合は、Bourne との互換性が十分にあり、bash-ism がないはずであると判断しました。また、この機能はデバッグ印刷のすべて/最終的なものではなく、多くのコーナーケースと改善できる領域がある可能性が高いことを認識しています. 私はすべての提案を歓迎しますが、特にこの printf の問題に関心があります。これがいかに単純であるべきかを考えると、何かばかげた間違いを犯しているに違いないように思えますが、それを見つけることはできません。

これが私の debug_print テスト スクリプトです。

#!/bin/sh
#
# Purpose: Debug print function.  Outputs delimiting lines and will display
#     either the contents of a file or the contents of a variable.
#
#   Usage: debug_print label input
#     Where label is the title to print in the header bar, usually the name of
#     the input variable.  Input is either a file on disk to be printed, or, 
#     if the argument is not a file then it is assumed to be a string and that
#     will be displayed instead.
#
# Returns: If two parameters are not provided, returns false, otherwise it
#     will always return true.
#
debug_print()
{
    local header_bar header_len dashes

    # Check for arguments
    if [ $# -ne 2 ]; then
        printf "Error: debug_print takes two parameters: 'label' and 'input'\n"
        return 1
    fi

    header_bar="-------------------------$1-------------------------"
    header_len=${#header_bar}
    printf "%s\n" "$header_bar"

    # Display either the contents of the input file or the input string
    if [ -r "$2" ]; then
        cat "$2"
    else
        printf "%s\n" "$2"
    fi

    # Display a footer line with the same length as the header line
    dashes="------------------------------------------------------------"
    printf "%*s\n" "$header_len" "$dashes"

    # None of these work
#    printf "%${header_len}s\n" "$dashes"
#    printf "%${header_len}s\n" "------------------------------------------------------------"
#    printf "%5s\n" xxxxxxxxxxxxxxxxxxxx
#    printf '%5s\n' "xxxxxxxxxxxxxxxxxxxx"
#    xxx="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
#    printf '%5s\n' $xxx

    # This works with dash
#    i=$header_len
#    while [ $i -gt 0 ]; do
#        printf "-"
#        i=$(( $i - 1 ))
#    done
#    printf "\n"

    # Working bash version
#    printf -v foot_line '%*s' $header_len
#    echo ${foot_line// /-}

    return 0
}


# Test debug printing
debug_print "Label" "The contents of the debug input..."

助けてくれてありがとう。

4

1 に答える 1