据我所知,bash 的推荐模式是始终引用 shell 变量。
例如,"$VAR"
而不是$VAR
.
但是我怎样才能实现引号为要解释的变量提供的相同安全性远程?
例如在以下内容中:
ssh server.com<<CODE
TARGET="target dir"
COUNT= \$( ls /foo/bar/\$TARGET | wc -l )
echo \$COUNT > count.txt
CODE
为了使代码正常工作,我需要转义$COUNT
和$TARGET
.
但是,如何实现与“$COUNT”或“$TARGET”针对此特定情况提供的相同安全性呢?
更新
我只粘贴了有问题的部分。
我还有其他行,变量是在定界文档之外定义的,因此如果我使用,<<'CODE'
则代码片段会中断。
更完整的例子:
SOME_STRING="SOME VALUE"
ssh server.com<<CODE
echo $SOME_VALUE > test_file.txt # <--- does not work if I use <<'CODE'
TARGET="target dir"
COUNT= \$( ls /foo/bar/\$TARGET | wc -l )
echo \$COUNT > count.txt
CODE
答案1
看起来这里文档保留了双引号。例如,考虑以下命令:
cat <<HEREDOC
"this will still be quoted"
HEREDOC
这将产生以下带引号的字符串作为其输出:
"this will still be quoted:
所以你应该能够像往常一样引用你的变量:
SOME_STRING="SOME VALUE"
ssh server.com<<CODE
echo "$SOME_VALUE" > test_file.txt
TARGET="target dir"
COUNT="\$( ls /foo/bar/\$TARGET | wc -l )"
echo "\$COUNT" > count.txt
CODE
关于命令替换中引用变量,请参考以下帖子:在 Bash 中的 $(命令替换) 内引用
请注意,我已经逐字复制了您的代码片段,但看起来您可能打算使用该变量SOME_STRING
而不是SOME_VALUE
.这是您的代码片段的稍作修改的版本,我可以在本地运行它并获得预期的结果:
mkdir -p "/foo/bar/target dir"
SOME_STRING="SOME VALUE"
ssh localhost<<CODE
echo "$SOME_STRING" > test_file.txt
TARGET="target dir"
COUNT="\$( ls "/foo/bar/\$TARGET" | wc -l )"
echo "\$COUNT" > count.txt
CODE
答案2
在过去的几天里,我们似乎对这个问题有很多不同的看法。
在这种情况下,请引用此处文档:
ssh server.com <<'CODE'
TARGET="target dir"
COUNT= $( ls /foo/bar/$TARGET | wc -l )
echo $COUNT > count.txt
then
fi
CODE
'CODE'
(与仅相对)CODE
将确保此处文档在编写时传递给实用程序,而无需扩展变量或执行命令替换。
请注意,此处文档中也存在语法错误(周围有空格=
且与 不if
匹配then
)。您还应该像往常一样对扩展$COUNT
和进行双引号$TARGET
。
ssh server.com <<'CODE'
TARGET="target dir"
COUNT=$( ls "/foo/bar/$TARGET" | wc -l )
printf '%s\n' "$COUNT" >count.txt
CODE
如果您尝试计算远程目录中的文件数量,请使用以下命令:
ssh server 'find "/path/to/dir" -maxdepth 1 -type f -exec echo . \;' | wc -l
这将正确计算/path/to/dir
.
要将结果写入远程文件:
ssh server 'find "/path/to/dir" -maxdepth 1 -type f -exec echo . \; | wc -l >file'
如果您需要远程执行的代码非常复杂,那么最好在服务器上创建一个脚本来运行它。您需要传递给脚本的变量可以在其命令行上传递:
ssh server ./script.sh "$SOME_VARIABLE"
剧本:
#!/bin/sh
VAR="$1"
# do stuff