-1

I have a bash script that contains lines:

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

It should produce a file that looks like this (in notepad++ on windows): enter image description here

instead the file looks like this: enter image description here

or in vim: enter image description here

What is wrong with the script? Because when I copy those lines into bash it works, only if I run the script it does produce those strange characters...

atapaka
  • 1,172
  • 4
  • 14
  • 30
  • The script is not recorded. It is written in a file by hand. Then when it is executed, it causes the problem. WhenI open the sh file in text editor, copy the lines and paste them into terminal, it works as it should. – atapaka Mar 01 '18 at 22:15
  • What does `$(basename $remote_temp_dir)` expand to? – DBedrenko Mar 01 '18 at 22:32
  • 1
    How do you run the script? Does the script begin with `#!/bin/bash`? – Barmar Mar 01 '18 at 22:45

1 Answers1

3

You've run into part of the mess of inconsistent behavior that plagues the echo command. Specifically, some versions of echo (in some modes) interpret escape (backslash) sequences in the string they're asked to print. Others don't. When you ask echo to print %SYSTEMROOT%\era_rd_6HbUKJTR\EraAgentInstaller.bat, it might see the \e part and think it's supposed to convert that to the ASCII escape character.

Note that there are two different characters being called "escape" here: The backslash is used by the shell as an escape character, meaning that it and the characters immediately following it have some special meaning. The ASCII escape, on the other hand, is treated as a special character by the terminal (and vim and some other things) in a somewhat similar manner. Since the ASCII escape is a nonprinting character, when notepad++ and vim have to display it, they show some sort of alternate representation ("ESC" or "^]").

Anyway, since echo is inconsistent about its treatment of the backslash character, it's best to avoid it for strings that might contain backslash. Use printf instead (see "Why is printf better than echo?" on unix.se). It's a little more complicated to use, but not too bad. The main things to realize are that the first argument to printf is a "format" string that's used to control how the rest of the arguments are printed, and that unlike echo it doesn't automatically add a newline to the end.

What you want to use is:

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

Or you can simplify it to:

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

That first argument, %s\n, says to print a plain string followed by a newline. Backslash escapes in the format string are always interpreted, but strings formatted with the %s format never have escapes interpreted. Note that in the single-command version, the format string gets applied to each of the other two arguments, so each gets a newline at the end, so each winds up on a separate line in the output file.

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151