use*_*378 6 command-line bash shell-script escape-characters
如何传递包含点 (.) 的命令行参数?是否有任何转义序列用于捕获像点这样的字符?
以下从 shell 调用 bash 脚本不起作用:
# ./deploy.sh input.txt
./deploy.sh: line 9: input.txt: syntax error in expression (error token is ".txt")
Run Code Online (Sandbox Code Playgroud)
我尝试了以下方法:
编辑
以这个用例为例:
解决方案:
这是执行 1(将工件读入数组)的简单脚本:
#!/bin/bash
declare -a artifacts
for i
do
artifacts[i]=$i
echo ${artifacts[i]}
done
Run Code Online (Sandbox Code Playgroud)
执行1
-bash-3.00$ ./simple.sh arg1 arg2 arg3
arg1
arg2
arg3
Run Code Online (Sandbox Code Playgroud)
执行2
-bash-3.00$ ./simple.sh arg1.txt arg2.txt arg3.txt
./simple.sh: line 7: arg1.txt: syntax error in expression (error token is ".txt")
Run Code Online (Sandbox Code Playgroud)
jw0*_*013 10
您需要使用declare -A而不是declare -a. 您显然正在使用具有任意字符串参数作为索引的关联数组,但declare -a仅适用于整数索引数组。 arg.txt不计算为有效整数,因此您的错误。
您似乎在使用bash第 3 版。不幸的是,直到第 4 版才能使用关联数组。我建议您发布原始deploy.sh脚本的清理版本,其中删除了敏感的个人信息,以便您可以从其他人那里获得有关替代方法的想法。
简单总结一下聊天中的一些交流:
对所有参数执行某些操作的最简单方法是使用循环遍历它们for:
for arg; do
scp login1@host1:"$arg" login2@host2:/dest/
done
Run Code Online (Sandbox Code Playgroud)
请记住双引号"$arg". 你不是需要把参数数组中的自己,因为他们在数组中已经存在$@,这是for默认情况下使用时,你不给一个明确的in list...。
每当您尝试在需要数字的地方使用字符串时,就会发生该错误。
例如
$((input.txt))
Run Code Online (Sandbox Code Playgroud)
将导致打印相同的错误。
在您的情况下,事实证明您正在分配一个使用数字索引的数组。
jw013 正确地解释了您需要做declare -A(大写 A)以使您的示例工作。
之所以:
分配给数组元素时,您通常会写
array[0]=foo
array[1]=bar
Run Code Online (Sandbox Code Playgroud)
但你也可以写任何算术表达式作为键,例如
array[0+0]=foo
array[1+0]=bar
Run Code Online (Sandbox Code Playgroud)
所以外壳看到了
array[input.txt]=input.txt
Run Code Online (Sandbox Code Playgroud)
试图将其转换为一个数字
$((input.txt))
Run Code Online (Sandbox Code Playgroud)
和失败。
点令人困惑并且没有点的参数似乎有效的原因是
$((input))
Run Code Online (Sandbox Code Playgroud)
实际上是一个有效数字。
bashsees input,确定它是一个有效的变量名,看到该变量未设置,并将其替换为0.
将其与input.txt不是有效变量名的 进行比较,因为变量名不能包含点!
为避免这种令人困惑的行为,您可以使用
set -u
Run Code Online (Sandbox Code Playgroud)
那么任何时候你尝试使用一个不存在的变量时,你都会得到一个错误,例如
set -u
artifacts[arg1]=arg1
Run Code Online (Sandbox Code Playgroud)
打印错误
scriptname: line number: arg1: unbound variable
Run Code Online (Sandbox Code Playgroud)