Bashスクリプト/コマンドで欠落している入力処理

Bashスクリプト/コマンドで欠落している入力処理

head修正されたスクリプト(コマンド?)を〜/ .bashrcに追加します。手動で入力するかワイルドカードから派生するか、stdinで提供するかを期待どおりに処理します。ただし、引数を指定するのを忘れた場合、headj端末は中断され、Ctrl-Cを使用して再起動できません。

echoこれは私のコードです(デバッグ目的でいくつかの呼び出しを含む)。

headj(){
    echo "script makes it this far without arguments"
    IFS=" " read -r -a input <<< "${@:-$(</dev/stdin)}"
    echo "but but crashes before getting here"
    # 
    for i in ${input[@]}; do
        echo -e "███████████████████████████████████████████████████████████████████████████████"
        echo -e "headj $i start"
        head -50 "$i"
    done
}

次のように動作します。

$ headj list1
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b

$ headj list*
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b

███████████████████████████████████████████████████████████████████████████████
headj list2 start
c
d

$ ls -1 li* | headj
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b

███████████████████████████████████████████████████████████████████████████████
headj list2 start
c
d

$ headj
script makes it this far without arguments

それがかかっているところです。

読み取り入力を試しましたinput=( ${@:-$(</dev/stdin)} )が、同じエラーが発生しました。エラーを処理するには、スクリプトの先頭にこのコードを追加してください。

if [ -z ${*:+x} ]; then
    echo "headj requires at least one argument"
    return
fi

もっと良い方法がありますか?また、このような質問には必ず検索すべきキーワードがありますか?

ベストアンサー1

引数や間違ったパイプなしで実行していて、関数のstdinにファイル名を書きたくないと仮定すると(そうする理由)、stdinがttyであることを確認するチェックを追加します。

headj() {
    local files=()
    if [ "$#" -gt 0 ]; then
        files=("$@")
    elif ! tty >/dev/null; then
        readarray -t files
    else
        echo "Will not read filenames from a tty!" >&2
    fi
    for file in "${files[@]}"; do
        echo "do something with $file..."
    done
}

したがって、これはうまくいきます。

$ ls *.txt |headj
do something with test.txt...

しかし、これは以下について文句を言います。

$ headj
Will not read filenames from a tty!

使用するコマンドはreadファイル名をスペースに分割するため、そうしません。したがって、パラメータの数と上記の配列の条件は異なります。改行readarrayで区切られた項目のリストを読む必要があります。これはパイプで接続されたlsときにfind生成されるものですが、もちろん、改行を含むファイル名が機能しないことを意味します。

(少しトリッキーかもしれませんが、パラメータや操作では複数の単語を生成する必要があるため使用しません。ただし、そうしないでください。使用すると、意図が単一の"$@"文字列を変換することをより明確にすることができます。)<<<<<< "$*"

^Cが機能しない理由については繰り返すことができず、関数がそうするようになっているようではありません。

おすすめ記事