【问题标题】:Why are my variables not being respected in this ZSH script [duplicate]为什么我的变量在这个 ZSH 脚本中没有得到尊重[重复]
【发布时间】:2021-10-18 20:54:41
【问题描述】:

我有这个 shell 脚本,我希望将 CLI 输入输入到 SSH 命令中。第一个 SSH 命令按预期运行,而第二个命令将 runTests.sh 的 $1 和 $2 设置为 ''。似乎它没有取代它们。关于为什么会这样的任何见解?

$1=7107
$2=development

ssh redacted@redacted -t 'zsh -l -c "source ~/.zshrc && ./runTests.sh 7107 development"'
ssh redacted@redacted -t 'zsh -l -c "source ~/.zshrc && ./runTests.sh $1 $2"'

【问题讨论】:

  • 标记 bash 或 zsh,不能同时标记两者。它们是两个不同的外壳,互不兼容。
  • 也就是说,在澄清编辑之后,看起来“分配给位置参数”重复项成为您问题的核心。 $1=7107 不起作用。如果您想更新位置参数的值,那是set 的用途之一。

标签: bash shell ssh zsh


【解决方案1】:

您正在调用三个不同的 shell:本地 shell、远程登录 shell 和远程 zsh shell。您需要仔细指定应由哪个人负责哪些参数替换。

您的变量存在于本地 shell 中,但您要求远程登录 shell 扩展它们。这就是它失败的原因。

您可以通过以下方式让本地 shell 替换它们:

set -- 7107 development   # Assign $1 and $2
ssh redacted@redacted -t "zsh -l -c 'source ~/.zshrc && ./runTests.sh $1 $2'"

由于 $1 和 $2 现在在本地 shell 中用双引号括起来,因此它们会扩展,从而在远程端生成 zsh -l -c 'source ~/.zshrc && ./runTests.sh 7107 development'。

这反过来会在嵌套的 zsh shell 中产生source ~/.zshrc && ./runTests.sh 7107 development。

理想情况下,您还希望转义数据中的特殊字符,以便带引号或空格的值正常工作:

ssh redacted@redacted -t "zsh -l -c 'source ~/.zshrc && ./runTests.sh \$1 \$2' _ $(printf %q "$1") $(printf %q "$2")"

【讨论】:

  • zsh 相当于${var@Q} 是什么?无论其内容如何,​​尝试安全地通过这些值都不会受到伤害。
【解决方案2】:

$1, $2, $3, ... 保留用作命令参数,例如如果你的脚本名称是script.sh,当你运行时:

./script.sh foo bar baz

$1 将是 foo,$2 将是 bar,$3 将是 baz。

另外,分配时不应使用空格。 试试:

foo=7107
bar=development

ssh redacted@redacted -t 'zsh -l -c "source ~/.zshrc && ./runTests.sh 7107 development"'
ssh redacted@redacted -t 'zsh -l -c "source ~/.zshrc && ./runTests.sh $foo $bar"'

请注意 cmets 中指出的安全问题。

【讨论】:

  • 这里存在安全问题。如果bar='$(rm -rf ~)',此代码将在redacted@redacted 上运行rm,即使这些值在本地安全引用。
  • 术语注释:$1 等。是不是变量。共有三种参数:位置($1、$2 等)、特殊($0、$#、$@ 等)和变量。变量是名称为有效标识符的参数,是唯一可以使用直接赋值设置的参数。
猜你喜欢
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
  • 2017-08-17
  • 2013-05-10
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多