15

I have a script that I run from the command line which I would like to be able to pass string arguments into. As in

script.py --string "thing1\nthing2"

such that the program would interpret the '\n' as a new line. If string="thing1\nthing2" I want to get

print string

to return:

thing1
thing2

rather than thing1\nthing2

If I simply hard-code the string "thing1\nthing2" into the script, it does this, but if it's entered as a command line argument via getopt, it doesn't recognize it. I have tried a number of approaches to this: reading in the cl string as r"%s" % arg, various ways of specifying it on the commandline, etc, and nothing seems to work. Ideas? Is this completely impossible?

Astro_Dart
  • 195
  • 1
  • 1
  • 9
  • This seems more like a shell question than a python question. Perhaps you should show some of the shell code that you're using and tag with your the shell you're using (e.g. `bash`) – mgilson Oct 22 '14 at 21:47

3 Answers3

16

From https://stackoverflow.com/a/4918413/478656 in Bash, you can use:

script.py --string $'thing1\nthing2'

e.g.

$ python test.py $'1\n2'
1
2

But that's Bash-specific syntax.

Community
  • 1
  • 1
TessellatingHeckler
  • 27,511
  • 4
  • 48
  • 87
11

This is really a shell question since the shell does all the command parsing. Python doesn't care what's happening with that and only gets what comes through in the exec system call. If you're using bash, it doesn't do certain kinds of escaping between double quotes. If you want things like \n, \t, or \xnn to be escaped, the following syntax is a bash extension:

python test.py $'thing1\nthing2'

Note that the above example uses single quotes and not double quotes. That's important. Using double quotes causes different rules to apply. You can also do:

python test.py "thing1
thing2"

Here's some more info on bash quoting if you're interested. Even if you're not using bash, it's still good reading:

http://mywiki.wooledge.org/Quotes

David Sanders
  • 4,069
  • 1
  • 24
  • 38
  • The 1st suggestion with $'...', which is also the accepted answer, does not allow for variable substitution. The 2nd one does – NameOfTheRose May 04 '20 at 15:14
  • @NameOfTheRose True, although people forget or often don't realize that variables don't *have* to be substituted between quotes. For example, you can do something like this: `echo $above$'\nbetween\n'$below`. – David Sanders May 05 '20 at 16:23
-2

This one is relatively simple and I am surprised no one has said it.

In your python script just write the following code

print string.replace("\\n", "\n")

and you will get the string printed with the new line and not the \n.

biw
  • 3,000
  • 4
  • 23
  • 40
  • 4
    That's really more of a hack to compensate for bad argument data. – David Sanders Oct 22 '14 at 22:11
  • I wouldn't say it is a hack. It gives a simple solution that reverses the escaping that python is doing to the string. Every other solution requires the user to be in bash. This gives a python solution. – biw Oct 22 '14 at 22:13
  • Though they use bash as an example, the other answers are really about the user interacting with the shell correctly. Since he/she is clearly invoking python through a shell, the shell-centered answers are the correct ones. Furthermore, python isn't doing any escaping to the string. Python is getting a string with the characters '\' and 'n' in it. Since this string was not a literal in a python file, it was not escaped. – David Sanders Oct 22 '14 at 22:16
  • I suppose I read the question incorrect. Good points but this still fixes the most general cases in python. Depending on what the program is for, you cannot always trust the argument data. – biw Oct 22 '14 at 22:21
  • 1
    This is the only one that worked. For whatever reason, the bash-related solutions (which I'm sure are valid, depending on the shell config) seemed to not really have any effect in my case. Thanks! – Astro_Dart Oct 22 '14 at 22:22
  • This worked for me! I'm passing a string with a `\n` into Python through windows shell. +1! – Captain Jack Sparrow May 28 '21 at 14:21