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