0

使用以下代码,如果管道到命令,我无法在 Bash 中克隆关联数组。我正在使用 Whiptail 显示进度条:

#!/bin/bash 

declare -Ar ARR1=(
[a]='asdf'
[b]='qwerty'
[c]='yuio'
)

declare -A ARR2=()

clone() {
    {
        for key in "${!ARR1[@]}"; do
            ARR2[$key]="${ARR1[$i]}"

            echo "10"  # Hardcoded percentage for Whiptail
        done
    } | whiptail --gauge "Cloning" 6 60 0
}

clone

for key in "${!ARR2[@]}"; do
  echo "$key"
  echo "${ARR2[$i]}"
done

卸下它的 Whiptail 管道:

#!/bin/bash 

declare -Ar ARR1=(
[a]='asdf'
[b]='qwerty'
[c]='yuio'
)

declare -A ARR2=()

clone() {
    {
        for key in "${!ARR1[@]}"; do
            ARR2[$key]="${ARR1[$i]}"

            echo "10"  # Hardcoded percentage for Whiptail
        done
    }
}

clone

for key in "${!ARR2[@]}"; do
  echo "$key"
  echo "${ARR2[$i]}"
done

有没有办法使用 Whiptail 管道进行这项工作?

4

2 回答 2

1

那是因为,正如man bash所说

管道中的每个命令都作为单独的进程执行(即,在子shell 中)。

子 shell 环境中的更改不会传播到父 shell。

于 2020-11-24T09:45:56.197 回答
1

请您尝试以下方法:

#!/bin/bash

declare -Ar ARR1=(
    [a]='asdf'
    [b]='qwerty'
    [c]='yuio'
)

declare -A ARR2=()

clone() {
    {
        n=${#ARR1[*]}                   # number of items
        for key in "${!ARR1[@]}"; do
            ARR2[$key]="${ARR1[$key]}"
            (( i++ ))                   # increment a counter
            echo $(( 100 * i / n ))     # percentage
            sleep 1                     # wait for 1 sec
        done
    } > >(whiptail --gauge "Cloning" 6 60 0)
}

clone

for key in "${!ARR2[@]}"; do
    echo "$key"
    echo "${ARR2[$key]}"
done

关键是在} > >(whiptail ...不使用管道的情况下将封闭块保留在前台进程中的表达式。
请注意,我已修改代码以显示百分比以使其看起来像这样。

于 2020-11-24T11:08:48.027 回答