13

引数 (ファイル) が渡されないときに標準入力を使用したい場合、スクリプトが機能しません。このコードでファイルの代わりに 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"
4

5 に答える 5

11

/dev/stdinファイル名として特別に解釈されたbashを置き換えるだけです:

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

(bash は、それを提供する OS 用に構築されている場合、実際にはその特殊ファイル を使用しますが、bash 2.04 は、それをサポートしていないシステムでそのファイルが存在しないことを回避できることに注意してください。)/dev/stdin

于 2013-10-27T15:15:22.330 に答える
4

pilcrow's answerはエレガントなソリューションを提供します。これは、OP のアプローチが機能しなかった理由の説明です。

OPのアプローチの主な問題は、 を使用して位置パラメータ割り当てようとし$1$1=...たことでした。これは機能しません。

LHS はシェルによって のに展開され$1結果は割り当て先の変数の名前として解釈されます - 意図ではなく、明らかに。

bash でに割り当てる唯一$1setの方法は、ビルトインを使用することです。注意点は、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"
于 2015-02-28T20:47:08.223 に答える
1

変数には によって値が割り当てられ、Var=Valueその変数は によって使用されecho $Varます。あなたの場合、それは

1=$(</dev/stdin)

標準入力を割り当てるとき。ただし、変数名を数字で始めることは許可されていないと思います。これを解決する方法については、質問bash read from file or stdinを参照してください。

于 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")

引数に file が存在しない場合は、標準入力から読み込みます。

他の例を参照してください: bash でファイルまたは stdin から読み取るには? スタックオーバーフローSEで

于 2015-02-28T20:24:30.687 に答える