传递包含点的 bash 命令行参数

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. 反斜杠
  2. 引用
  3. 双引号
  4. ./deploy.sh 输入(这有效)

编辑

以这个用例为例:

  1. 我有 3 个文件: server.jar client.jar gui.jar
  2. 我需要将它们从来源 scp 到目标
  3. 源目录:login1@host1:/home/xyz/deploy/
  4. 目标目录:login2@host2:/data/apps/env/software/binary/

解决方案:

  1. 从命令行读取要复制到数组中的工件
  2. 使用正确的目录前缀创建目标路径和源路径字符串
  3. 使用 for 循环 scp 每个工件(已经找出路径)

这是执行 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脚本的清理版本,其中删除了敏感的个人信息,以便您可以从其他人那里获得有关替代方法的想法。

编辑 2

简单总结一下聊天中的一些交流:

对所有参数执行某些操作的最简单方法是使用循环遍历它们for:

    for arg; do
        scp login1@host1:"$arg" login2@host2:/dest/
    done
Run Code Online (Sandbox Code Playgroud)

请记住双引号"$arg". 你不是需要把参数数组中的自己,因为他们在数组中已经存在$@,这是for默认情况下使用时,你不给一个明确的in list...。


Mik*_*kel 5

每当您尝试在需要数字的地方使用字符串时,就会发生该错误。

例如

$((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)