パイプラインで変数の割り当てが機能しません。

パイプラインで変数の割り当てが機能しません。

パイプ時に変数に値が割り当てられないのはなぜですか?たとえば、

a=15|echo $a

コマンドをグループ化して{}パイプに渡そうとしましたが、{}パイプの後のコマンドは初期化された値を使用できません。

答え1

このコマンドは、割り当てが出力を生成せず、echo標準入力から読み取らないため、ほとんど意味がありません。

代わりに:

a=15; printf '%s\n' "$a"

さらに、パイプラインの2つの部分は異なる環境で実行されるため、a左側を設定してもaパイプラインの右側の値には影響しません。

例:

{ a=15; printf 'on the left:\ta=%s\n' "$a"; } | { cat; printf 'on the right:\ta=%s\n' "$a"; }

出力:

on the left:    a=15
on the right:   a=

...a上記の操作を実行する前に値がないとします。その場合、右側が値を取得します。パイプラインのどの部分でも値を設定しても、a環境の値は変わりません。

lastpipeシェルオプションが設定されている場合そしてシェルはジョブ制御なしで実行され(非対話型スクリプトであるかのように)、パイプラインの最後の部分は周辺スクリプトと同じ環境で実行されます。これは、割り当てがパイプラインで「ライブ」になることを意味します。

#!/bin/bash

shopt -s lastpipe

a=10

printf 'LHS: a=%s\n' "$a" | { cat; printf 'RHS: a=%s\n' "$a"; a=30; }

printf 'a is now %s\n' "$a"

出力:

LHS: a=10
RHS: a=10
a is now 30

削除shopt -s lastpipe:

LHS: a=10
RHS: a=10
a is now 10

答え2

あなたの例はわかりませんが、より良い例を見てみましょう。

echo foo | read REPLY

pipes(予想される方法で)機能できるシェル構成であるか、POSIXがシェルでそれを設定する特定の方法を許可していないため、機能しない可能性があります。

私の例では、またはを使用しようとするとfooinになり、他のシェルには空のシェルがあります。$REPLYboshksh93zshREPLY

これは、パイプの一番右のプログラムがデフォルトシェル(組み込みシェルの場合)で実行されますが、他のシェルはbosh常にサブシェルで一番右のプログラムを実行して応答を読み取り、すぐに終了するためです。ksh93zsh

関連情報