当我想在没有传递参数(文件)时使用标准输入时,脚本不起作用。有没有办法在这段代码中使用stdin而不是文件?
我试过了:
if [ ! -n $1 ] # check if argument exists
then
$1=$(</dev/stdin) # if not use stdin as an argument
fi
var="$1"
while read line
do
... # find the longest line
done <"$var"
答案 0 :(得分:10)
对于想要在缺少参数时从stdin读取值的一般情况,这将起作用。
$ echo param | script.sh
$ script.sh param
<强> script.sh 强>
#!/bin/bash
set -- "${1:-$(</dev/stdin)}" "${@:2}"
echo $1
答案 1 :(得分:7)
只需将bash特别解释的/dev/stdin
替换为文件名:
VAR=$1
while read blah; do
...
done < "${VAR:-/dev/stdin}"
(请注意,bash实际上会使用那个特殊的文件 /dev/stdin
if built for an OS that offers it,但是因为bash 2.04可以解决该文件在不支持它的系统上的缺席。)
答案 2 :(得分:2)
pilcrow's answer提供了一个优雅的解决方案;这是对为什么OP的方法不起作用的解释。
OP方法的主要问题是尝试使用{分配位置参数$1
{1}},它不会起作用。
LHS通过shell扩展为$1=...
的值,结果被解释为要分配的变量的名称 - 清楚而不是意图。
在bash中分配给$1
的唯一方法是通过$1
内置。
需要注意的是set
总是设置所有位置参数,因此如果有的话,你还必须包含其他
set
(如果您只希望最多 1 参数,set -- "${1:-/dev/stdin}" "${@:2}" # "${@:2}" expands to all remaining parameters
会这样做。)
上述内容还纠正了OP方法的第二个问题:尝试在{中存储内容而不是stdin的 filename {1}},因为使用了set -- "${1:-/dev/stdin}"
。
$1
是bash parameter expansion的一个应用程序,它表示:返回<
的值,除非${1:-/dev/stdin}
未定义(未传递任何参数)或其值为空字符串($1
或$1
已通过)。如果""
未定义(如果它包含 any ,则变体''
(无${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}
答案 3 :(得分:1)
变量按Var=Value
分配一个值,该变量由例如echo $Var
使用。 1=$(</dev/stdin)
。在你的情况下,这相当于
{{1}}
分配标准输入时。但是,我不认为允许变量名以数字字符开头。有关解决此问题的方法,请参阅问题bash read from file or stdin。
答案 4 :(得分:1)
这是我的脚本版本:
#!/bin/bash
file=${1--} # POSIX-compliant; ${1:--} can be used either.
while IFS= read -r line; do
printf '%s\n' "$line"
done < <(cat -- "$file")
如果参数中没有文件,请阅读标准输入。
在stackoverflow SE中查看更多示例:How to read from file or stdin in bash?