在shell中声明全局数组

时间:2014-07-17 10:54:20

标签: arrays bash shell pipe

以下是我需要将数据分离到数组中的代码,但是使用PIPE它正在生成子shell,因此无法访问数组normal,executable和directory.and它不能打印任何内容或者不会打印任何内容。知道#////////之后发生了什么。请帮我解决这个问题。

i=0
j=0
k=0
normal[0]=
executable[0]=
directory[0]=
ls | while read line
do
if [ -f $line ];then
#echo "this is normal file>> $line"
normal[i]=$line
i=$((i+1))
fi

if [ -x $line ];then
#echo "this is executable file>> $line"
executable[j]=$line
j=$((j+1))
fi


if [ -d $line ];then
#echo "this is directory>> $line"
directory[k]=$line
k=$((k+1))
fi
 done

#//////////////////////////////////////
echo "normal files are"
for k in "${normal[@]}"
do
 echo "$k" 
done

echo "executable files are"

for k in "${executable[@]}"
do
echo "$k"
done


echo "directories are"
 for k in "${directory[@]}"
  do
  echo "$k"
  done

2 个答案:

答案 0 :(得分:1)

您的脚本有几个缺陷:

  • 您的if测试应使用[[而不是[编写,这是用于二进制比较(更多信息:here)。如果您想保留[或未使用bash,则必须引用line变量,即写下您所有的测试:if [ -f "$line" ];then

  • 不要使用ls列出当前目录,因为在某些情况下它会出错。在您的情况下,glob更适合(更多信息:here

  • 如果您想避免使用管道,请改用for循环。将ls | while read line替换为for line in $(ls)或者,将我之前的积分改为for line in *

在这样做之后,我测试了你的脚本,它工作得非常好。您应该注意,某些文件夹将在“可执行文件”和“目录”下列出,因为它们具有+x权限(我不知道这是否是您想要的行为)。

作为旁注,在使用它们之前,您不需要在bash中声明变量。因此,您的前6行不是必需的。变量i,j,k不是必需的,您可以使用以下语法动态递增数组:normal+=("$line")

答案 1 :(得分:0)

最简单的方法是在不再需要数组之前保持子shell打开。换句话说:

ls | { while read line; do 
...
echo "directories: ${directory[@]}" | tr ' ' \\n
}

换句话说,在while之前添加一个左大括号,在脚本末尾添加一个右大括号。