pilcrow 的回答提供了一个优雅的解决方案;这是对为什么 OP 的方法不起作用的解释。
OP 方法的主要问题是尝试使用分配给位置参数$1
,$1=...
这是行不通的。
LHS 由 shell 扩展为 的值,结果被解释$1
为要分配的变量的名称 - 显然,不是意图。
在 bash 中分配给$1
set
的唯一方法是通过内置的. 需要注意的是,它set
总是设置所有位置参数,所以如果有的话,你还必须包括其他参数。
set -- "${1:-/dev/stdin}" "${@:2}" # "${@:2}" expands to all remaining parameters
(如果您只期望最多1 个参数,set -- "${1:-/dev/stdin}"
就可以了。)
以上还纠正了 OP 方法的次要问题:尝试存储内容而不是stdin的文件名$1
,因为<
使用了。
${1:-/dev/stdin}
是 bash参数扩展的应用,它表示:返回 的值$1
,除非$1
未定义(未传递参数)或其值为空字符串(""
或''
已传递)。变体${1-/dev/stdin}
(no ) 只有在未定义:
时才会返回(/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"