Why can't I repeat # characters! in a line in bash?

I had a tiny bash script that is supposed to have moved to my home directory, created a file, echoed it and made it executable. Here's how it looked:

cd ; touch tor.sh; echo "#!/bin/bash\n/usr/local/bin/tor" >> tor.sh; chmod +x tor.sh 

But did it continue to break in an echo complaining of an “event not found”? For some reason, I decided to try this, and it worked:

 cd ; touch tor.sh; echo -e "\x23\x21/bin/bash\n/usr/local/bin/tor" >> tor.sh; chmod +x tor.sh 

Why did I have to replace these two characters (shebang?) With hexadecimal and a -e? Is there a better way to do this?

+1
bash
source share
5 answers

This is not a mistake, and it has nothing to do with shebang, just an exclamation point.

 Enclosing characters in double quotes preserves the literal value of all characters within the quotes, with the exception of $, `, \, and, when history expansion is enabled, !. 

So either avoid it, use single quotes, or disable the history extension.

eg.

 > echo "How dare you put an '!' in this string?" bash: !: event not found > set +o histexpand > echo "How dare you put an '!' in this string?" How dare you put an '!' in this string? 
+4
source share

You must use single quotes to prevent extrapolation of strings:

 echo '#!/bin/bash\n/usr/local/bin/tor' 

Or you can avoid shebang:

 echo "#\!/bin/bash\n/usr/local/bin/tor" 
+1
source share

try ' instead of " like this ...

 $ echo '#!/bin/bash' > thing.sh $ cat thing.sh #!/bin/bash 
+1
source share

Use "\", for example:

 echo \#\!/whatever > test 
0
source share

Two reasons:

First, the difference in behavior between double and single quote strings.

"#!/bin/bash\n/usr/local/bin/tor" "extended" - that is, the commands in quotation marks here will be executed first.

Thus,
echo "$(echo foo)" > file puts 'foo' in file , and echo '$(echo foo)' > file puts '$ (echo foo)' in file .

"#!" this is a comment, and it does not happen in other shells. If it starts a file (like shebang), POSIX indicates that this behavior is undefined; but there is no reason why this should happen here.

-one
source share

All Articles