在bash脚本中重定向到文件时出现奇怪的字符

时间:2018-03-01 21:40:46

标签: linux bash shell

我有一个包含行的bash脚本:

remote_installer_svc_args="$local_cifs_mount/eset-remote-installer.args"    
svc_arg_x86="%SYSTEMROOT%\\$(basename $remote_temp_dir)\\$(basename $INSTALLER_BAT)"
svc_arg_x64="%SYSTEMROOT%\\$(basename $remote_temp_dir)\\$(basename $INSTALLER_BAT)"
echo "$svc_arg_x86" > $remote_installer_svc_args
echo "$svc_arg_x64" >> $remote_installer_svc_args

它应该生成一个看起来像这样的文件(在Windows上的notepad ++中): enter image description here

而是文件看起来像这样: enter image description here

或在vim中: enter image description here

脚本有什么问题?因为当我将这些行复制到bash中时它才起作用,只有当我运行脚本时才会生成那些奇怪的字符......

1 个答案:

答案 0 :(得分:3)

你遇到了困扰echo命令的不一致行为的一部分。具体来说,某些版本的echo(在某些模式下)会解释它们被要求打印的字符串中的转义(反斜杠)序列。其他人没有。当您要求echo打印%SYSTEMROOT%\era_rd_6HbUKJTR\EraAgentInstaller.bat时,可能会看到\e部分并认为它应该将其转换为ASCII escape character

请注意,这里有两个不同的字符称为“escape”:shell使用反斜杠作为转义字符,这意味着它和紧随其后的字符具有一些特殊含义。另一方面,ASCII转义被终端(以及vim和其他一些东西)以某种类似的方式视为特殊字符。由于ASCII转义是非打印字符,当notepad ++和vim必须显示它时,它们会显示某种替代表示形式(“ESC”或“^]”)。

无论如何,由于echo与反斜杠字符的处理不一致,因此最好避免使用包含反斜杠的字符串。请改用printf(请参阅"Why is printf better than echo?" on unix.se)。使用起来有点复杂,但也不算太糟糕。要实现的主要内容是printf的第一个参数是一个“格式”字符串,用于控制其余参数的打印方式,与echo不同,它不会自动添加新行到最后。

您想要使用的是:

printf '%s\n' "$svc_arg_x86" > $remote_installer_svc_args
printf '%s\n' "$svc_arg_x64" >> $remote_installer_svc_args

或者您可以将其简化为:

printf '%s\n' "$svc_arg_x86" "$svc_arg_x64" > $remote_installer_svc_args

第一个参数%s\n表示打印一个纯字符串后跟一个换行符。格式字符串中的反斜杠转义符总是解释,但使用%s格式从不格式化的字符串会解释转义符。请注意,在单命令版本中,格式字符串将应用于其他两个参数中的每一个,因此每个参数都会在结尾处获取换行符,因此每个参数都会在输出文件中的单独行上结束。