ssh 会话内导出的变量为空

ssh 会话内导出的变量为空

我正在尝试在 ssh 会话中导出变量并在下一个写入命令中引用该变量。

sshpass -p "password" ssh -t -t my-box <<EOF
  export newUrl="this is a url"
  sudo -E sh -c 'echo "url=$newUrl" >> /path/to/file'
  exit
EOF

而不是打印,

url=this is a url

到文件,它只是打印,

url=

为什么在同一个 ssh 会话中无法访问变量的值?

答案1

由于此处文档由 表示<<EOF(不带任何引号),因此此处文档的内容受\$`.因此,$newUrl此处的文档扩展到其在本地 shell 中的值。

要传递$newUrl到远程 shell 并让它扩展变量,您可以保护$不扩展:\$newUrl而不是$newUrl,或者使用文字 here-document:<<'EOF'而不是 ``<

您正在将变量扩展newUrl为将由 shell 解释的字符串。这意味着变量的值将被解释为 shell 脚本片段,而不是字符串。如果该值包含 shell 特殊字符,则会发生严重破坏。 (哪些字符有问题取决于您使用的标称情况解决方案。)

不要使用多层引用和扩展,而是将 URL 作为输入传递给以 root 身份运行的命令。那么你就没什么可担心的了。即使 sudo 未配置为接受-E,这还有一个额外的优点,即可以正常工作,这是相当常见的。您可以使用sudo sh -c 'cat >>/path/to/file'或更好的方法来避免文件上任何潜在的引用问题sudo tee -a /path/to/file

sshpass -p "password" ssh -t -t my-box <<'EOF'
  newUrl="this is a url"
  printf '%s\n' "$newUrl" | sudo tee -a /path/to/file
EOF

答案2

尝试使用 sudo 导出。当您对另一个用户使用 sudo 时,该变量会丢失。您也可以Defaults env_keep += "newUrl"在 sudoers 文件中进行设置。

相关内容