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.
Related
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?
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
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
I need to invoke make (build a makefile) in a directory different from the one I'm in, from inside a Python script. If I simply do:
build_ret = subprocess.Popen("../dir1/dir2/dir3/make",
shell = True, stdout = subprocess.PIPE)
I get the following:
/bin/sh: ../dir1/dir2/dir3/make: No such file or directory
I've tried:
build_ret = subprocess.Popen("(cd ../dir1/dir2/dir3/; make)",
shell = True, stdout = subprocess.PIPE)
but the make command is ignored. I don't even get the "Nothing to build for" message.
I've also tried using "communicate" but without success. This is running on Red Hat Linux.
I'd go with #Philipp's solution of using cwd, but as a side note you could also use the -C option to make:
make -C ../dir1/dir2/dir3/make
-C dir, --directory=dir
Change to directory dir before reading the makefiles or doing anything else. If multiple -C options are specified, each is interpreted relative to the previous one: -C / -C etc is equivalent to -C /etc. This is typically used with recursive invocations of make.
Use the cwd argument, and use the list form of Popen:
subprocess.Popen(["make"], stdout=subprocess.PIPE, cwd="../dir1/dir2/dir3")
Invoking the shell is almost never required and is likely to cause problems because of the additional complexity involved.
Try to use the full path, you can get the location of the python script by calling
sys.argv[0]
to just get the path:
os.path.dirname(sys.argv[0])
You'll find quite some path manipulations in the os.path module
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']