Arrays Shell脚本:声明空数组的正确方法
我试图在Shell脚本中声明空数组,但遇到错误Arrays Shell脚本:声明空数组的正确方法,arrays,bash,shell,Arrays,Bash,Shell,我试图在Shell脚本中声明空数组,但遇到错误 #!/bin/bash list=$@ newlist=() for l in $list; do newlist+=($l) done echo "new" echo $newlist 当我执行它时,我得到test.sh:5:test.sh:语法错误:“(“意外的用bash运行它: bash test.sh 看到这个错误,看起来你实际上是在用dash运行它: > dash test.sh test.sh: 5
#!/bin/bash
list=$@
newlist=()
for l in $list; do
newlist+=($l)
done
echo "new"
echo $newlist
当我执行它时,我得到test.sh:5:test.sh:语法错误:“(“意外的用bash运行它:
bash test.sh
看到这个错误,看起来你实际上是在用dash运行它:
> dash test.sh
test.sh: 5: test.sh: Syntax error: "(" unexpected
只有这一次您可能使用了指向它的链接(/bin/sh->/bin/dash)。如果数组为空,请执行以下操作:
NEWLIST=
您可以通过以下方式进行检查:
if [ $NEWLIST ] ; then
# do something
fi
非空数组声明如下所示:
NEWLIST=('1' '2' '3')
要在过程中填充数组,请执行以下操作:
ARRAY=("$(find . -name '*.mp3')")
希望这对你有所帮助试试看你是喜欢dash还是bash
ls -al /bin/sh
如果显示的是/bin/sh->/bin/dash
,请键入以下内容:
sudo rm /bin/sh
sudo ln -s /bin/bash /bin/sh
然后再次键入:
ls -al /bin/sh*
那么必须这样说:
/bin/sh -> /bin/bash
这意味着现在sh
正确地面向Bash,您的数组将正常工作。我发现以下语法更具可读性
declare -a <name of array>
declare-a
有关更多详细信息,请参见。在BASH 4+中,您可以使用以下命令声明空数组:
declare -a ARRAY_NAME=()
然后,您可以通过以下方式附加新项目new_ITEM1和new_ITEM2:
ARRAY_NAME+=(NEW_ITEM1)
ARRAY_NAME+=(NEW_ITEM2)
请注意,添加新项时需要括号()。这是必需的,以便将新项附加为数组元素。如果确实缺少(),则新的\u ITEM2将成为附加到第一个数组元素数组\u名称[0]的字符串
上述示例将导致:
echo ${ARRAY_NAME[@]}
NEW_ITEM1 NEW_ITEM2
echo ${ARRAY_NAME[0]}
NEW_ITEM1
echo ${ARRAY_NAME[1]}
NEW_ITEM2
echo ${ARRAY_NAME[@]}
NEW_ITEM1NEW_ITEM3 NEW_ITEM2
echo ${ARRAY_NAME[0]}
NEW_ITEM1NEW_ITEM3
echo ${ARRAY_NAME[1]}
NEW_ITEM2
接下来,如果执行了(请注意缺少括号):
这将导致:
echo ${ARRAY_NAME[@]}
NEW_ITEM1 NEW_ITEM2
echo ${ARRAY_NAME[0]}
NEW_ITEM1
echo ${ARRAY_NAME[1]}
NEW_ITEM2
echo ${ARRAY_NAME[@]}
NEW_ITEM1NEW_ITEM3 NEW_ITEM2
echo ${ARRAY_NAME[0]}
NEW_ITEM1NEW_ITEM3
echo ${ARRAY_NAME[1]}
NEW_ITEM2
感谢@LenW纠正了我的追加操作。代码运行时没有错误您确定使用bash
运行脚本吗?脚本似乎是使用sh
运行的,在这种情况下不支持数组。此外,将$@
指定给另一个参数会失去$
的好处,即t保留单个命令行参数中的空白。在“$@”中删除list
并对l使用;直接执行
。谢谢!运行bash脚本。sh
有效。但是…为什么即使使用#!/bin/bash
它也会在破折号上执行?我键入了export
,我的SHELL被设置为bash。可能是因为sh
。你可以用ls-l/bin/sh
或readlink$(哪个sh)看到它指向的位置
。顺便说一句,根据参数声明数组变量newlist
的最快方法是newlist=(“$@”)
。请注意,如果args是“a b”“c”“d”
,没有引号($@
),则在展开(“a”“b”“c”
)时,由于分词,它将拆分为4个参数,而使用“$@”
值在空格中保持不变。#!
仅在作为命令运行时有效-通过使文件可执行(chmod+x test.sh
)然后只需键入文件名,前面不带任何*sh:/test.sh
。如果您显式地键入shell的名称,如sh
或bash
作为要运行的命令,那么这就是要运行的命令;#!
行对shell来说只是一个注释。@MarkReed是的,但我想他已经说过了他用/test.sh
运行脚本,但是dash
仍然是一个executed@konsolebox如果是这样的话,它会在bash中执行,并且与/bin/sh
链接的内容无关,因为shebang行中有/bin/bash
。NEWLIST
在该示例中的长度为1。试试看之后回显${#NEWLIST[@]}
以查看this.ofc,这很正常,但正如我的示例所示,“if”将按它应该的方式工作,并显示里面没有任何内容。因此,真正的测试是它是否存在,而不是检查长度,这在我的示例中实际上是3。测试它,并且不要否决正确工作的内容空数组是长度为0的数组。NEWLIST
不是空数组,因为它的长度为1。对不起,您没有回答正确回答了问题。您的if
语句没有正确测试此问题。您认为长度为1的数组为“空”?我说,我的样本运行良好,测试也正确,对任何变量都进行相同的测试。但无论如何,我接受了你的意见,尽管我将停止讨论。我还说,你是对的,你测试它的方式将返回1。但在你返回长度之前,你可以使用[var]进行测试。我还发现,您可以使用ARRAY\u NAME+=(NEW\u ITEM1 NEW\u ITEM2)
一次附加多个项。因此,您实际上只是将两个数组连接起来。如果不将任何一个数组指定为文本,这也是可能的,尽管在这种情况下语法有点笨拙:ARRAY1+=(${ARRAY2[@])
。谢谢,我遇到了一个类似的问题,但您的回答帮助了我,问题仍然存在。如果我在脚本顶部提到#!/bin/bash,那么为什么在执行shell脚本时出现dash。我使用了./tesh.sh来执行脚本。任何解释都会非常有用。