サブシェルなしでbashでコマンド出力を繰り返す

サブシェルなしでbashでコマンド出力を繰り返す

サブシェルを作成したり、一時ファイルを使用せずにコマンド出力を繰り返したいと思います。

exit私のスクリプトの初期バージョンは次のようになりましたが、サブシェルを作成し、コマンドが必要に応じてデフォルトスクリプトの代わりにサブシェルを終了するため、機能しません。これは、ポリシー ルーティングを設定し、パス障害を引き起こす条件を検出すると実行を停止する大きなスクリプトの一部です。

sysctl -a 2>/dev/null | grep '\.rp_filter' | while read -r -a RPSTAT ; do

  if [[ "0" != "${RPSTAT[2]}" ]] ; then
    echo >&2 "RP Filter must be disabled on all interfaces!"
    echo >&2 "The RP filter feature is incompatible with policy routing"
    exit 1
  fi
done

したがって、提案された代替案の1つは、サブシェルの使用を避けるためにこのようなコマンドを使用することです。

while read BLAH ; do echo $BLAH; done </root/regularfile

したがって、サブシェルを避けながら、私が望むプログラムから出力を引き続き取得するには、このようなコマンドを使用する必要があるかもしれません。

while read BLAH ; do echo $BLAH; done <(sysctl -a 2>/dev/null | grep '\.rp_filter')

残念ながら、このコマンドを使用すると、このエラーが発生します。

-bash: syntax error near unexpected token `<(sysct ...

これは実際に動作するので本当に混乱しています。

cat <(sysctl -a 2>/dev/null | grep '\.rp_filter')

そのコマンドの出力を一時ファイルに保存し、一時ファイルへのリダイレクトを使用できますが、そうすることは避けたいと思います。

それでは、リダイレクトによってエラーが発生するのはなぜですか、一時ファイルを生成する以外に他のオプションはありますか?

答え1

あなたは1つを逃しました<。しなければならない:

while read BLAH ; do echo $BLAH; done < <(sysctl -a 2>/dev/null | grep '\.rp_filter')

<(sysctl -a 2>/dev/null | grep '\.rp_filter')ファイルだと思います。

答え2

誰かがここに戻ってきたら、より多くのオプションを提供してください...

set -o errexitシェルによっては、コマンド(サブシェルを含む)がブロックに閉じ込められたり、末尾のifOR&&なしでゼロ以外の値で終了したときに親シェルが終了することがあります||

/bin/false || echo "ignoring error"

または、kill および $PPID 環境変数 (使用可能な場合) を使用して、子シェルが親シェルにシグナルを送信できるようにすることもできます。

あるいは、whileブロックを関数に移動して0/1(whileブロックの後に明示的に0を返す)を返し、likeを使用することもできますsysctl | grep | function || exit。戻り値をインラインブロックに入れることもできますが、関数は友達です。 ;)

関連情報