2013-08-21 53 views
1

为什么不是这个bash数组填充?我相信我过去曾经这样做过。呼应${#XECOMMAND[@]}示出了没有数据..为什么不是这个BASH阵列?

DIR=$1 
TEMPFILE=/tmp/dir.tmp 

ls -l $DIR | tail -n +2 | sed 's/\s\+/ /g' | cut -d" " -f5,9 > $TEMPFILE 


i=0 
cat $TEMPFILE | while read line ;do 

    if [[ $(echo $line | cut -d" " -f1) == 0 ]]; then 

     XECOMMAND[$i]="$(echo "$line" | cut -d" " -f2)" 
     ((i++)) 
    fi 

done 
+0

这可能是由管道引起的子壳。试试像这样:'while ...... done <“$ TEMPFILE”' – user000001

+0

这样做user000001,谢谢。 – Matthew

+0

我很好奇为什么这种方法不起作用?你能否在下面发表你的答案?我很乐意给你信用 – Matthew

回答

2

当运行等

somecommand | while read ... 

然后while循环在子壳执行,即不同的工艺比主脚本while循环。因此,循环中发生的所有变量赋值都不会反​​映在主进程中。解决方法是使用输入重定向和/或命令替换,以便循环在当前进程中执行。例如,如果你想从文件中读取你做

while read .... 
do 
    # do stuff 
done < "$filename" 

,或者如果你wan't一个过程的输出,你可以做

while read .... 
do 
    # do stuff 
done < <(some command) 

最后,在bash 4.2以上,就可以设置为shopt -s lastpipe,这将导致管道中的最后一条命令在当前进程中执行。

+0

太棒了,谢谢user000001 :) – Matthew

1

我想你正在尝试构建一个由$DIR中所有零长度文件和目录的名称组成的数组。如果是这样,你可以像这样做:

mapfile -t ZERO_LENGTH < <(find "$DIR" -maxdepth 1 -size 0) 

(添加-type f到find命令,如果你只在常规文件感兴趣。)

这种类型的解决方案几乎不是试图总是更好解析ls输出。

使用进程替换(< <(...))而不是管道(... |)很重要,因为这意味着shell变量将在当前shell中设置,而不是在ephimeral子shell中。