You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash技术问询:使用循环将find命令结果追加至索引数组失败及数组+=运算符疑问

Let's break down your two issues one by one, since they're related but have distinct fixes:

1. Why your manual array test didn't work

Your pids+="foo1" syntax is incorrect for adding elements to a Bash array. When you use += without parentheses, you're appending the string directly to the first element of the array, not adding a new element. That's why you ended up with pids[0]="foo1foo2" instead of two separate elements.

The correct way to add elements to an array is to wrap the value in parentheses:

declare -a pids
pids+=("foo1")  # Adds "foo1" as pids[0]
pids+=("foo2")  # Adds "foo2" as pids[1]

2. Why your find/while loop didn't populate the array

The bigger issue here is subshell behavior in Bash. When you pipe output from find to a while loop (find ... | while read ...), the while loop runs in a separate subshell. Any changes you make to the pids array inside this subshell won't be reflected in the parent shell where you later try to iterate over it. That's why your final for loop has nothing to output.

Here are three reliable fixes for this:

Fix 1: Use process substitution (most portable for modern Bash)

Replace the pipe with process substitution to run the while loop in your current shell instead of a subshell:

declare -a pids
while read -d $'\0' file
do
    pids+=("$file")
done < <(find /foo/bar/ -iname "*.pid" -print0)

# Now pids is populated in the parent shell
for i in "${pids[@]}"
do
    echo "$i"
done

The < <(command) syntax feeds the output of find directly into the while loop's standard input, keeping the loop in the main shell context.

Fix 2: Group all logic in the same subshell (if you don't need the array later)

If you only need to process the files immediately and don't need the pids array outside the loop, wrap the entire array setup and iteration in a subshell group:

find /foo/bar/ -iname "*.pid" -print0 | {
    declare -a pids
    while read -d $'\0' file
    do
        pids+=("$file")
    done
    for i in "${pids[@]}"
    do
        echo "$i"
    done
}

This works because all operations happen in the same subshell, so the array is accessible to the for loop inside the group.

Fix 3: Enable lastpipe (Bash 4.2+)

If you're using Bash 4.2 or newer, you can enable the lastpipe option to make the last command in a pipe run in the current shell:

shopt -s lastpipe
declare -a pids
find /foo/bar/ -iname "*.pid" -print0 | while read -d $'\0' file
do
    pids+=("$file")
done
for i in "${pids[@]}"
do
    echo "$i"
done

This preserves your original pipe structure but modifies how Bash handles the last command in the pipeline.

Quick Recap

  • Always use array+=("value") to add new elements to a Bash array (parentheses are mandatory).
  • Pipe-induced subshells are the root cause of your empty array; use process substitution, lastpipe, or subshell grouping to fix it.

内容的提问来源于stack exchange,提问作者Icoryx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 11:57:39