stdinから変数に複数行の入力を読み込む方法と、shell(sh、bash)で出力する方法

StackOverflow https://stackoverflow.com/questions/212965

  •  03-07-2019
  •  | 
  •  

質問

やりたいことは次のとおりです:

  1. stdinから変数A
  2. への複数行入力の読み取り
  3. \n
  4. でさまざまな操作を行う
  5. パイプ\r区切り記号(\treadcatなど)を別のコマンドに失わずに

現在の問題は、改行で読み取りを停止するため、<=>コマンドで読み取ることができないことです。

次のように、<=>で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"

これは、こちらのトリックを使用しています。

[更新済み]

パイプに何もない場合、この割り当ては無期限にハングします...

var="$(< /dev/stdin)"

最初の文字にタイムアウトreadを行うことで、これを防ぐことができます。タイムアウトになると、戻りコードは128を超え、STDINパイプ(別名/dev/stdin)が空であることがわかります。

それ以外の場合は、STDINの残りの部分を取得します...

  • IFSコマンドに対してのみ-rをNULLに設定
  • -d ''
  • でエスケープをオフにする
  • var="$(command ...)"を使用して読み取りの区切り文字を削除します。
  • そして最後に、最初に得たキャラクターにそれを追加します

したがって...

__=""
_stdin=""

read -N1 -t1 __  && {
  (( $? <= 128 ))  && {
    IFS= read -rd '' _stdin
    _stdin="$__$_stdin"
  }
}

この手法は、設計上、後続の改行を常に削除する$()コマンド置換の使用を回避します。

コマンド置換が優先される場合、末尾の改行を保持するために、1つ以上の区切り文字を$(parens)内の出力に追加し、外部でそれらを削除できます。

たとえば、(最初のコマンドでは${braces}に、2番目のコマンドでは<=>に注意) ...

_stdin="$(awk '{print}; END {print "|||"}' /dev/stdin)"
_stdin="${_stdin%|||}"
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top