it-swarm-ja.tech

サブシェルなしで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')

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

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

9
Zoredache

_<_を逃しました。する必要があります:

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

<(sysctl -a 2>/dev/null | grep '\.rp_filter')をファイルと考えてください。

13
dogbane

誰かが再びここに来た場合のいくつかの代替案について...

シェルによっては、コマンド(サブシェルを含む)がifブロックまたは末尾のset -o errexitまたは&&にトラップされずにゼロ以外で終了したときに、親シェルを終了させるために||を使用できます。

/bin/false || echo "ignoring error"

または、可能な場合は、killと$ PPID環境変数を使用して、サブシェルが親に信号を送るようにすることもできます。

または、whileブロックを関数に移動して、0/1を返し(whileブロックの後に明示的に0を返す)、sysctl | grep | function || exitのようにパイプラインを実行することもできます。リターンもインラインブロックに入れることができると思いますが、関数はあなたの友達です。 ;)

0
dannysauer