CPython itself has certain command-line options that cause all further arguments to be interpreted as non-options ("terminates option list"). For example, -c cmd is such an option, so python3 -c 'import sys; print(sys.argv)' -E prints [-c, -E]; -E isn't recognized as an option.
Is there a way to define an option of this kind for an argparse parser?
Related
how can i run an easy python script and save it in a file but directly in linux command line:
fox#fox:/opt/gera# python -c print "aaaaa" > myfileName
but it is just print nothing instead of "aaaaa".
You have to quote the whole command:
python -c 'print "aaaaa"' > myfileName
Otherwise you execute print in Python (which, in Python 2 prints a linebreak and in Python 3 does nothing since you'd just evaluate the function print without calling it) and pass aaaaa as an argument to the script.
You need to put quotes around the code.
python -c 'print "aaaaa"' > myfileName
python -c 'print "aaaaa"' > myfileName
in your example python is running python -c print and giving "aaaaa" as an argument.
man python:
-c command
Specify the command to execute. This terminates the option list (following options are passed as arguments to the command).
passed as arguments to the command -- means everything after the command is available as sys.argv:
$ python -c 'import sys; print sys.argv' -a -b -c -d
['-c', '-a', '-b', '-c', '-d']
To make a single argument (command in terms of the man excerpt above) out of a list of arguments you just take these in quotes:
$ python -c 'print "aaaaa"'
aaaaa
The following command opens a new shell and opens nano in it, when I type it into bash:
gnome-terminal -e "bash -c 'nano test; bash'"
So I tried the same in my python code with subprocess:
import subprocess
command = "gnome-terminal"
args = " -e \"bash -c 'nano test; bash'\""
subprocess.call([command, args])
I have tried already many combinations. Basically I just want to open a shell with a specific file in nano.
First I thought this would be one the easiest steps, but it turned out to be very difficult. Don't know if the problem exists due to the masking or if it's a common problem with passing variables like I am used to in shells. So it might be rather a question for AskUbuntu or the Unix section ... not sure ...
The args should be the same set of individual strings you use on the command line. It's easier to think about if you construct the list all at once. gnome-terminal is the command, and it takes two arguments. (The second argument is more commonly thought of as the argument to the -e option, but from the caller's perspective, it's just two arguments. gnome-terminal itself is the one that groups them together as an option/argument pair.)
command = ["gnome-terminal", "-e", "bash -c 'nano test; bash'"]
subprocess.call(command)
(Note that you could just pass a single string and let the shell sort it out, but the explicit argument list is superior.
subprocess.call('''gnome-terminal -e "bash -c 'nano test; bash'"''', shell=True)
)
A single command passed to Python interpreter via '-c' option works perfectly:
$ python3 -c "print('Hi')"
Hi
$
However, I couldn't figure out how to send multiple lines (from the Windows command prompt), since the statements are grouped by indentation. Passing multiple lines in a single line will not work.
A Linux terminal supports multiple lines with newline character as argument:
$ python3 -c "
>import sys
>print(sys.argv[0])"
$ -c
But in Windows it is not possible because the command get terminated with a newline
$ python3 -c "
$
How do I make this work in the Windows command prompt?
I am just checking out the options of Python interpreter, so I am not looking for any workaround solution!
You could use the ^ operator here. Something like
C:\>python3 -c "print('Hai')"
Hai
C:\>python3 -c "import sys; print(sys.argv)"
['-c']
C:\>python3 -c ^
More? "import sys; ^
More? print(sys.argv)"
['-c']
And,
C:\>python3 -c ^
More? "if 2*2 == 4: ^
More? print('Testing')"
Testing
And,
C:\>python3 -c ^
More? "if True: ^
More? print('First Line'); ^
More? print('Second Line')"
First Line
Second Line
Quoting from docs.python.org:
"sys.argv The list of command line arguments passed to a Python script. argv[0] is the script name (it is operating system dependent whether this is a full pathname or not). If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c'. If no script name was passed to the Python interpreter, argv[0] is the empty string."
Am I missing something, or sys.argv[0] always returns the script name, and to get '-c' I'd have to use sys.argv[1]?
I'm testing with Python 3.2 on GNU/Linux.
No, if you invoke Python with -c to run commands from the command line, your sys.argv[0] will be -c:
C:\Python27>python.exe -c "import sys; print sys.argv[0]"
-c
When Python is invoked as python script.py then sys.argv[0] == 'script.py'. When you invoke python -c 'import sys; print sys.argv' then sys.argv[0] == '-c' indicating the script body was passed as a string on the command line.
python -c executes a command passed on the command line, rather than a script from a file. sys.argv[0] will be set to "-c".
If you run a script with a -c flag, then yes, sys.argv[1] will be set to "-c" and sys.argv[0] will be set to the name of the script.
For a Bash completion script I need to get all the variables from an installed Python module that match a pattern. I want to use only Python-aware functionality, to avoid having to parse comments and such.
You can use python -c to execute a one-line Python script if you want. For example:
bash$ python -c "import os; print dir(os)"
If you want to filter by a pattern, you could do:
bash$ python -c "import os; print [x for x in dir(os) if x.startswith('r')]"
['read', 'readlink', 'remove', 'removedirs', 'rename', 'renames', 'rmdir']