pilcrow's answerはエレガントなソリューションを提供します。これは、OP のアプローチが機能しなかった理由の説明です。
OPのアプローチの主な問題は、 を使用して位置パラメータに割り当てようとし$1
$1=...
たことでした。これは機能しません。
LHS はシェルによって の値に展開され$1
、結果は割り当て先の変数の名前として解釈されます - 意図ではなく、明らかに。
bash でに割り当てる唯一$1
set
の方法は、ビルトインを使用することです。注意点は、set
常にすべての位置パラメーターを設定することです。そのため、他のパラメーターがあればそれも含める必要があります。
set -- "${1:-/dev/stdin}" "${@:2}" # "${@:2}" expands to all remaining parameters
(最大で1 つの引数のみを期待する場合は、十分set -- "${1:-/dev/stdin}"
です。)
上記は、OP のアプローチに関する二次的な問題も修正します。標準入力のファイル名ではなく、内容を保存しようとする試みが使用されているためです。$1
<
${1:-/dev/stdin}
は、 bashパラメーター展開のアプリケーションであり、が未定義 (引数が渡されなかった場合) またはその値が空の文字列 (またはが渡された場合)$1
でない限り、 の値を返します。バリエーション(no ) は、が定義されていない場合にのみ返されます (空の文字列であっても、値が含まれている場合は返されます)。$1
""
''
${1-/dev/stdin}
:
/dev/stdin
$1
すべてをまとめると、次のようになります。
# Default to filename '/dev/stdin' (stdin), if none was specified.
set -- "${1:-/dev/stdin}" "${@:2}"
while read -r line; do
... # find the longest line
done < "$1"
しかしもちろん、もっと簡単な方法は${1:-/dev/stdin}
、ファイル名として直接使用することです:
while read -r line; do
... # find the longest line
done < "${1:-/dev/stdin}"
または、中間変数を介して:
filename=${1:-/dev/stdin}
while read -r line; do
... # find the longest line
done < "$filename"