SSH 远程执行 - 如何在 EOF 块内声明变量(Bash 脚本)

SSH remote execution - How to declare a variable inside EOF block (Bash script)

我在 bash 脚本中有以下代码:

    remote_home=/home/folder
    dump_file=$remote_home/my_database_`date +%F_%X`.sql
    aws_pem=$HOME/my_key.pem
    aws_host=user@host
    local_folder=$HOME/db_bk
    pwd_stg=xxxxxxxxxxxxxxxx
    pwd_prod=xxxxxxxxxxxxxxx
    
    ssh -i $aws_pem $aws_host << EOF
    mysqldump --column-statistics=0 --result-file=$dump_file -u user -p$pwd_prod -h $db_to_bk my_database
    mysql -u user -p$pwd_prod -h $db_to_bk -N -e 'SHOW TABLES from my_database' > $remote_home/test.txt
    sh -c 'cat test.txt | while read i ; do mysql -u user -p$pwd_prod -h $db_to_bk -D my_database --tee=$remote_home/rows.txt -e "SELECT COUNT(*) as $i FROM $i" ; done'
EOF

我的循环 while 不工作,因为“i”变量变空了。谁能帮帮我好吗?我想了解在这种情况下如何处理数据。

本地 shell 正在“扩展”here-document 中的所有 $variable 引用,但您希望将 AIUI $i 传递到远程 shell 并在那里扩展。为此,转义(使用反斜杠)您不希望本地 shell 扩展的 $ 字符。我认为它看起来像这样:

ssh -i $aws_pem $aws_host << EOF
mysqldump --column-statistics=0 --result-file=$dump_file -u user -p$pwd_prod -h $db_to_bk my_database
mysql -u user -p$pwd_prod -h $db_to_bk -N -e 'SHOW TABLES from my_database' > $remote_home/test.txt
sh -c 'cat test.txt | while read i ; do mysql -u user -p$pwd_prod -h $db_to_bk -D my_database --tee=$remote_home/rows.txt -e "SELECT COUNT(*) as $i FROM $i" ; done'
EOF

您可以通过仅将 ssh -i $aws_pem $aws_host 命令替换为 cat 来测试它,因此它会打印 here-document,因为它将传递给 ssh 命令(即在本地 shell 完成解析和扩展之后,但在远程 shell 完成之前)。您应该看到大部分变量都被它们的值替换了(因为这些必须在本地发生,在定义这些变量的地方)但是 $i 按字面意思传递,因此远程 shell 可以扩展它。

顺便说一句,你应该 double-quote 几乎所有的变量引用(例如 ssh -i "$aws_pem" "$aws_host")以防止出现奇怪的解析问题; shellcheck.net 会为本地命令指出这一点(以及其他一些潜在的问题),但您也应该为远程命令修复它($i 除外,因为它已经 double-quoted作为 SELECT 命令的一部分)。