user7450368
user7450368

Reputation:

Escaped ! displays as literal \!

I'm trying to write a Python program to a file in one line of Bash. I am trying this:

$ printf "#\!/usr/bin/python3\nprint('hi\!')\nwhatever()" > whatever.py

But that gives:

#\!/usr/bin/python3
print('Hi\!')
whatever()

How can I get it to output:

#!/usr/bin/python3
print('Hi!')
whatever()

Upvotes: 1

Views: 54

Answers (2)

Socowi
Socowi

Reputation: 27215

The best way would be to use a Here Document:

cat > whatever.py <<EndOfPythonProgram
#!/usr/bin/python3
print('hi!')
whatever()
EndOfPythonProgram

But since you wanted to write everything in one line, you may use the following command:

printf '%s\n' '#!/usr/bin/python3' "print('hi"'!'"')" 'whatever()' > whatever.py
  • First, we use printf %s yourString instead of printf yourString. That's the way printf is supposed to be used (not necessary in this case, but safer for general cases).
  • With %s\n every additional argument of printf is printed as one line.
  • In the first line, there are no single quotes, so we can quote the whole first line in single quotes and don't have to escape the !.
  • In the second line, there are single quotes, so we cannot quote the whole second line in single quotes. Nevertheless, we can quote the ! in single quotes and the remaining parts in double quotes. In bash the string ab can be written as: ab, "ab", 'ab', "a"'b', ...

Upvotes: 2

anubhava
anubhava

Reputation: 785128

You can use:

set +H # disable history expansion

printf "#!/usr/bin/python3\nprint('hi!')\nwhatever()\n"

set -H # enable history expansion again

#!/usr/bin/python3
print('hi!')
whatever()

Upvotes: 0

Related Questions