13

当我想在没有传递参数(文件)的情况下使用标准输入时,脚本不起作用。有什么办法可以在这段代码中使用标准输入而不是文件?

我试过这个:

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"
4

5 回答 5

16

对于在缺少参数时想要从标准输入读取值的一般情况,这将起作用。

$ echo param | script.sh
$ script.sh param

脚本.sh

#!/bin/bash

set -- "${1:-$(</dev/stdin)}" "${@:2}"

echo $1
于 2015-07-24T05:31:56.060 回答
11

只需替换 bash 的特别解释/dev/stdin为文件名:

VAR=$1
while read blah; do
  ...
done < "${VAR:-/dev/stdin}"

(请注意,如果为提供它的操作系统构建,bash 实际上会使用该特殊文件 ,但由于 bash 2.04 将在不支持它的系统上解决该文件的缺失问题。)/dev/stdin

于 2013-10-27T15:15:22.330 回答
4

pilcrow 的回答提供了一个优雅的解决方案;这是对为什么 OP 的方法不起作用的解释。

OP 方法的主要问题尝试使用分配给位置参数$1$1=...这是行不通的。

LHS 由 shell 扩展为 的值,结果解释$1为要分配的变量的名称 - 显然,不是意图。

在 bash 中分配给$1set的唯一方法是通过内置的. 需要注意的是,它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"
于 2015-02-28T20:47:08.223 回答
1

变量被赋值,Var=Value并且该变量被 eg 使用echo $Var。在你的情况下,这相当于

1=$(</dev/stdin)

分配标准输入时。但是,我认为不允许变量名以数字字符开头。有关解决此问题的方法,请参阅从文件或标准输入中读取的问题bash

于 2013-10-27T15:09:10.557 回答
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")

如果参数中不存在文件,请从标准输入中读取。

查看更多示例:如何在 bash 中读取文件或标准输入?在stackoverflow SE

于 2015-02-28T20:24:30.687 回答