我正在尝试在 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 文件中进行设置。