我在做什么错了?在shell命令中使用循环时出现错误消息
unset list
list=("A" "B" "C")
/bin/sh -c "for i in `seq 1 ${#list[@]}` ; do echo $i ; done "
它应该返回:代替
1
2
3
:
/bin/sh: -c: line 1: syntax error near unexpected token `2'
/bin/sh: -c: line 1: `2'
我在做什么错了?在shell命令中使用循环时出现错误消息
unset list
list=("A" "B" "C")
/bin/sh -c "for i in `seq 1 ${#list[@]}` ; do echo $i ; done "
它应该返回:代替
1
2
3
:
/bin/sh: -c: line 1: syntax error near unexpected token `2'
/bin/sh: -c: line 1: `2'
在你的原代码,你传递给/bin/sh
双引号的字符串被shell调用sh
前处理。特别是,扩展了涉及seq
的命令替换和参数$i
。其结果是,你得到如下(可以通过运行代码之前调用set -x
确认):
for i in 1
2
3 ; do echo ; done
以下1的序列for
将遍历的终止治疗的换行符。此时,sh
会预期关键字do
,但它会看到2
。
解决此问题的一种方法是,假设您确实需要将字符串传递给另一个shell实例,请告知seq
使用不同的分隔符(例如空格)。您还需要在$i
中跳过 美元符号,以便它通过子shell而不是当前shell进行评估。
unset list
list=("A" "B" "C")
/bin/sh -c "for i in `seq -s' ' 1 ${#list[@]}` ; do echo \$i ; done "
这将sh
工作,因为子shell没有看到阵列,它会看不明白。 sudo_O提供了一个不同的答案,它涉及保护传递给sh
的整个字符串,并在该字符串中包含list
的定义,以便它在子shell中可见。请注意,sh
必须是一个shell,如bash
,因为POSIX sh
不支持数组,正如jordanm所指出的那样。
我们的答案以不同的方式解决了这个问题。我让'seq'命令在当前shell中计算,以便将序列'1 2 3'(不带换行符)传递给子shell。您将'list'的定义移动到子shell中并在其中执行操作。他原来的语法错误是由于他传递给'/ bin/[ba] sh'的字符串包含嵌入的换行符,导致'for'循环被错误地解析。用'set -x'运行他的原始代码来查看问题。 – chepner 2013-03-07 15:34:25
它为我工作。 – 2013-03-07 15:35:11
阵列时产卵子外壳list
不会被定义,因此它不会有任何长度制作:视为
for i in `seq 1 ${#list[@]}`
:
for i in seq 1 0
参见:
$ sh -c 'echo ${#list[@]}'
0
和seq 1 0
不产生输出,因此看不到任何结果。
要么设置list
并在当前shell打印出的每个值:在子shell
$ list=("A" "B" "C")
$ for i in `seq 1 ${#list[@]}`;do echo $i;done
1
2
3
或定义list
:
$ sh -c 'list=("A" "B" "C");for i in `seq 1 ${#list[@]}`;do echo $i;done'
1
2
3
@chepner给你正确的答案。
顺便说一句,你还可以缩短了命令像这样(没有进一步的外壳参与)
unset list
list=("A" "B" "C")
for i in `seq 1 ${#list[@]}` ; do echo $i ; done
我不确定OP是否有很好的理由将命令传递给子shell,但这绝对简单。 – chepner 2013-03-07 15:24:35
如果你在当前的shell中,你不需要担心换行符,所以只需放下'-s \' – 2013-03-07 15:39:41
@sudo_O这是真的! – 2013-03-07 15:40:41
你确定'sh'是bash的? POSIX'sh'没有数组。 – jordanm 2013-03-07 15:19:05