私がやりたいことは次のとおりです:
stdin
から変数A
に複数行の入力を読み込みますA
でさまざまな操作を行うA
区切り記号(\n
、\r
、\t
、etc)別のコマンドへ現在の問題は、read
コマンドで読み込めないことです。改行で読み込めなくなるためです。
次のように、cat
でstdinを読み取ることができます。
my_var=`cat /dev/stdin`
、しかし、それを印刷する方法がわかりません。そのため、改行、タブ、およびその他の区切り文字はそのままです。
サンプルスクリプトは次のようになります。
#!/usr/local/bin/bash
A=`cat /dev/stdin`
if [ ${#A} -eq 0 ]; then
exit 0
else
cat ${A} | /usr/local/sbin/nextcommand
fi
これは私のために働いています:
myvar=`cat`
echo "$myvar"
$myvar
を囲む引用符は重要です。
Bashには、別の方法があります。 _man bash
_言及:
コマンド置換
$(cat file)
は、同等の高速な$(< file)
に置き換えることができます。
_$ myVar=$(</dev/stdin)
hello
this is test
$ echo "$myVar"
hello
this is test
_
teeは仕事をする
#!/bin/bash
myVar=$(tee)
はい、それも私のために動作します。ありがとう。
myvar=`cat`
と同じです
myvar=`cat /dev/stdin`
はい、そうです。 bash
manページから:
文字を二重引用符で囲むと、$、 `、\、および履歴展開が有効になっている場合は!を除き、引用符内のすべての文字のリテラル値が保持されます。文字$と `は、二重引用符で囲まれた特別な意味を保持します。
出力の最後で末尾の改行を保持することに関心がある場合は、これを使用します。
myVar=$(cat; echo x)
myVar=${myVar%x}
printf %s "$myVar"
これは here のトリックを使用します。
パイプに何もない場合、この割り当ては無期限にハングします...
_var="$(< /dev/stdin)"
_
ただし、最初の文字にタイムアウトread
を実行することでこれを防ぐことができます。タイムアウトになると、戻りコードは128を超え、STDINパイプ(別名_/dev/stdin
_)が空であることがわかります。
それ以外の場合は、STDINの残りを取得します...
IFS
コマンドに対してのみread
をNULLに設定-r
_でエスケープをオフにする-d ''
_を使用して読み取りの区切り文字を削除します。したがって...
___=""
_stdin=""
read -N1 -t1 __ && {
(( $? <= 128 )) && {
IFS= read -rd '' _stdin
_stdin="$__$_stdin"
}
}
_
この手法では、var="$(command ...)"
コマンド置換の使用を回避します。これは、設計上、後続の改行を常に削除します。
コマンド置換が優先される場合、末尾の改行を保持するために、1つ以上の区切り文字を$()
内の出力に追加し、それらを外部で取り除くことができます。
たとえば、最初のコマンドでは(note $(parens)
、2番目では_${braces}
_) ...
__stdin="$(awk '{print}; END {print "|||"}' /dev/stdin)"
_stdin="${_stdin%|||}"
_