大きなシェル スクリプトを作成するために使用する簡単な 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..."
助けてくれてありがとう。