web-dev-qa-db-ja.com

プロセスパイプラインの代替

私が取り組んでいるシェルスクリプトは、DBから複数の列と複数の行をフェッチする1つのSQLクエリを持っています。

get_names() {
    $Oracle_HOME/bin/sqlplus -s usr/pwd <<EOF
        SELECT id,name,age FROM table;
        Exit;
EOF
}

次に、この結果を読み取るために、関数の出力をパイプ処理します。

get_names | while read sid p_name p_age ; do ... done

さて、|、サブシェルが作成されていますが、これは避ける必要があります。この問題に代わるものはありますか?

そのパイプステートメントを壊して、その子プロセスを回避したいと思います。

2
vidya31

プロセス置換をサポートするシェル(bash、ksh、zshなど)を使用している場合は、プロセス置換を使用できます。

while read sid p_name p_age ; do ...; done <  <(get_names)

これは、パイプラインの最終リンクを実行中のシェルにする場合(実行中のシェルに影響を与える可能性があるため)、bashで必要です。

for sh in bash ksh zsh; do 
     echo $sh:; $sh -c 'while read var; do i=$var
     done < <(printf "%s\n" 1 2); echo $i '
done

出力:

bash:
2
ksh:
2
zsh:
2

一方、通常のパイプラインでは:

for sh in bash ksh zsh; do 
     echo $sh:; $sh -c 'printf "%s\n" 1 2 | 
         while read var; do i=$var; done ; echo $i '; 
done

bashは現在のシェルではなくサブシェルでwhileループを実行するため、割り当ては固定されません。

bash:

ksh:
2
zsh:
2
3
PSkocik