Bash远程追加带单引号文本时单引号丢失问题求助
解决远程追加带单引号的多行文本时单引号丢失问题
问题原因
你的脚本中,远程执行的命令经过了本地shell、SSH远程shell、sudo切换用户后的shell三层解析,单引号被当作shell语法符号处理,最终被过滤掉,导致写入文件时丢失。
方法1:使用远程heredoc传递内容(最可靠)
这种方式彻底避免多层引号嵌套的解析问题,直接通过heredoc把内容原封不动传递给远程的cat命令追加到文件:
element_list=("element1" "element2") # 遍历数组时加双引号,避免元素含空格时出错 for element in "${element_list[@]}" do # 用printf构造带单引号的目标内容 CONTENT=$(printf "field1 = on\nfield2 = '%s'\nfield3 = '%s-random-text'\n" "$element" "$element") CONFIG_FILE=/tmp/config.txt # 通过远程heredoc让other_user执行追加操作 sshpass -p vm_password ssh -t vm_user@<vm-ip> "sudo su - other_user -s /bin/bash -c 'cat >> $CONFIG_FILE' << 'EOC' $CONTENT EOC" done
关键说明:
sudo su - other_user -s /bin/bash指定用bash执行命令,避免切换用户后默认shell不兼容的问题'EOC'用单引号包裹,让远程shell不解析heredoc内的内容,确保$CONTENT里的单引号、换行符完全保留printf比heredoc更简洁,能精准插入变量和单引号
方法2:转义单引号并调整远程命令引号
如果偏好使用echo方式,需要对内容里的单引号进行转义,同时调整远程命令的引号结构:
element_list=("element1" "element2") for element in "${element_list[@]}" do # 构造内容时,用'\''实现单引号的转义(shell中在单引号串内插入单引号的标准写法) read -r -d '' CONTENT << EOM field1 = on field2 = '\''$element'\'' field3 = '\''$element-random-text'\'' EOM CONFIG_FILE=/tmp/config.txt # 远程命令的-c参数用双引号包裹,确保转义后的单引号被识别为普通字符 sshpass -p vm_password ssh -t vm_user@<vm-ip> "sudo su - other_user -c \"echo '$CONTENT' >> $CONFIG_FILE\"" done
关键说明:
'\''的逻辑是:关闭当前单引号串 → 插入一个单引号 → 重新打开单引号串,这样能在单引号包裹的内容里保留单引号字符- 远程命令用双引号包裹
-c的参数,避免多层单引号嵌套导致的语法冲突
执行任意一种方法后,远程机器的/tmp/config.txt都会生成你预期的带单引号的内容。
内容的提问来源于stack exchange,提问作者Kalit Inani
相关产品推荐
相关产品推荐

