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が機能しない理由については繰り返すことができず、関数がそうするようになっているようではありません。