【问题标题】:Pass value of variable to complex command将变量的值传递给复杂的命令
【发布时间】:2019-09-07 20:35:40
【问题描述】:

我正在尝试将值从字符串变量传递到复杂的 bash 命令,但我遇到了问题。当我执行命令时:

files=($(ls abc*))

for file in "${files[@]}"
do
    scp $file user@domain.com:~
    ssh user@domain.com 'PGPASSWORD="abcd" psql -h domain.com -U user -d dbb -f ~/$file'
    ssh user@domain.com 'rm ~/$file'
done

我遇到了一些错误。只有 'scp' 是正确执行的,但它们之后的行会失败。我看到“psql -f 缺少参数”和“找不到文件/无法删除字典” 这段代码有什么问题?如何将字符串值传递给 ssh 命令?

【问题讨论】:

  • 单引号不展开变量。
  • 我会设置一个 SSH 隧道并在本地运行 psql

标签: bash ssh psql scp


【解决方案1】:

单引号将阻止远程 shell 接收您的变量。 Don't use ls in scripts. Quote your variables. 在要求人工审核之前使用http://shellcheck.net/

for file in abc*
do
    scp "$file" user@domain.com:~
    ssh user@domain.com "PGPASSWORD='abcd' psql -h domain.com -U user -d dbb -f ~/'$file'; 
        rm ~/'$file'"
done

这里的引用有点棘手,如果您的文件名可能包含例如文字单引号。双引号导致本地shell扩展$file;然后扩展值用单引号括起来,以防止远程 ssh 进一步对其进行操作。

我取出了数组,因为它似乎没有任何用处。如果你想要一个数组,只需用通配符分配它:

files=(abc*)

【讨论】:

  • 绝妙的答案!您准确地描述了这里发生的所有问题。祝你有美好的一天@tripleee :)
【解决方案2】:

这段代码有什么问题?如何将字符串值传递给 ssh 命令?

双引号 (") 和单引号 (') 之间的重要区别之一是后者抑制了参数扩展。您需要将$file 移到引号之外,或者更改为双引号样式。但是,此外,您应该正确引用 $file 的扩展名,否则在出现异常文件名(例如包含空格的文件名)时,您可能会受到破坏甚至令人讨厌的意外。

此外,您正在格式化将由不同的 shell 处理的命令字符串这一事实增加了一些复杂性。确保正确引用的最简单方法是使用 bash 的 printf 内置函数,其 %q 格式化选项正是用于引用任意字符串的目的,以便可以将结果作为 shell 输入重新读取以重现相同的字符串。总的来说,这是我对循环的建议:

for file in "${files[@]}"
do
    scp "${file}" user@domain.com:~
    ssh user@domain.com "PGPASSWORD='abcd' psql -h domain.com -U user -d dbb -f $(printf %q "~/${file}")"
    ssh user@domain.com "rm $(printf %q "~/${file}")"
done

【讨论】:

    【解决方案3】:

    不要将每个文件复制到远程主机执行,而是设置一个 SSH 隧道并在本地运行psql,通过隧道连接到远程数据库。

    ssh -N -L 12345:domain.com:$DB_PORT user@domain.com & ssh_pid=$!
    
    files=(abc*)
    
    for file in "${files[@]}"
    do
        psql -p 12345 -U user -d dbb -f "$file"
    done
    
    kill "$ssh_pid"
    

    这样做的好处是不会暴露数据库密码,因为您可以简单地手动输入密码或使用本地 .pgpass 文件。

    请注意,仅当远程数据库未配置为接受网络连接时才需要隧道。

    【讨论】:

    • 有趣的想法。也许有一天我会使用它。谢谢:) +1
    猜你喜欢
    • 2019-02-16
    • 2017-12-15
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多