「while」ループの奇妙な変数の動作

「while」ループの奇妙な変数の動作

誰かが私に何が起こっているのかを説明できますか?

スクリプト:

#!/bin/sh
SKIP="unity-launcher|unity-panel|unity-dash|Hud|XdndCollectionWindowImp|Desktop"
WINS=()
wmctrl -l | grep -Ev " (${SKIP})" | cut -d \  -f 1 | while read window; do
    WINS=( ${WINS[@]} $window )
    echo "Found window: $window; New size: ${#WINS[@]}"
done
echo "Total window count: ${#WINS[@]}"
echo "Window IDs:"
for i in "${WINS[@]}"; do
    echo "  $i"
done

出力:

Found window: 0x0380000a; New size: 1
Found window: 0x038002ae; New size: 2
Found window: 0x03800a33; New size: 3
Found window: 0x03000001; New size: 4
Found window: 0x04c00004; New size: 5
Total window count: 0
Window IDs:

期待される:

Found window: 0x0380000a; New size: 1
Found window: 0x038002ae; New size: 2
Found window: 0x03800a33; New size: 3
Found window: 0x03000001; New size: 4
Found window: 0x04c00004; New size: 5
Total window count: 5
Window IDs:
    0x0380000a
    0x038002ae
    0x03800a33
    0x03000001
    0x04c00004

本質的にループが終わると、配列は何とかリセットされますが、whileそのWINS理由はわかりません。 bashに私が知らない奇妙なスコープがありますか?

答え1

パイプは、上記のプロセスで値を変更できないサブシェルを生成します。努力する:

while read window; do
    WINS=( ${WINS[@]} $window )
    echo "Found window: $window; New size: ${#WINS[@]}"
done < <(wmctrl -l | grep -Ev " (${SKIP})" | cut -d \  -f 1)

関連情報