Capture Python's shell command within the own script - python

Launching a hypothetical Python script with several arguments (with argparse) from the shell, let's say, python my_script.py --foo 7.4 --bar whatever, I want to capture this shell command from the own script and put it in a string variable.
Of course, I could save those arguments just after doing args = parser.parse_args() by converting that object into a dictionary: args_dict = vars(args). But I don't want that. What I want is to get the whole shell command python my_script.py --foo 7.4 --bar whatever as a string.
Is that possible? If not, could I still get the shell command and put it as a part of the output when saving it in a file by doing python my_script.py --foo 7.4 --bar whatever >> my_output.txt?

It's not perfectly accurate, but you can infer it like this:
import sys
print ("%s %s" % (sys.executable, " ".join(sys.argv) ) )
❯ python3 test.py --foo 7.4 --bar=whatever
/usr/bin/python3 test.py --foo 7.4 --bar=whatever
This will not catch pipes and the likes, only the command invoking python:
❯ python3 test.py | cat
/usr/bin/python3 test.py

Related

How do I pass in arguments to a curled script, that has been piped into the Python process?

I have a Python script on a Github gist, which I can curl from my terminal with
curl -s https://gist.githubusercontent.com/.../script.py
The script has a main function that is executed, and I can pipe the output of the curl statement to Python, which executes the script.
curl -s https://gist.githubusercontent.com/.../script.py | python
The above statement works, but I want to provide some command line arguments to the script, without having to download it to a file. The problems I am facing are that the Python command treats any text following it as what to execute, and not as arguments for the piped file, so
curl -s https://gist.githubusercontent.com/.../script.py | python arg1 arg2
Does not work, nor does
curl -s https://gist.githubusercontent.com/.../script.py arg1 arg2 | python
How can I pass in both arguments to the file, either as standard input or command line options that my script can read?
From CLI help:
- : program read from stdin (default; interactive mode if a tty)
So what you want is:
curl -s https://gist.githubusercontent.com/.../script.py | python - arg1 arg2
Note however, that - will also appear in sys.argv (in place of the script's filename)
$ echo "import sys; print sys.argv" | python - arg1 arg2
['-', 'arg1', 'arg2']
you could save the script locally and then execute it.
curl -o some_filename.py some_link
python some_filename.py arg1 arg2
you can also save a curl output to file with:
curl some_link > some_file.py

How to pass command line arguments to ipython

Is there any way that I pass arguments to my python script through command line while using ipython? Ideally I want to call my script as:
ipython -i script.py --argument blah
and I want to be able to have --argument and blah listed in my sys.argv.
You can use one -- more option before that:
ipython script.py -- --argument blah
Help of Ipython:
ipython [subcommand] [options] [-c cmd | -m mod | file] [--] [arg] ...
If invoked with no options, it executes the file and exits, passing the
remaining arguments to the script, just as if you had specified the same
command with python. You may need to specify `--` before args to be passed
to the script, to prevent IPython from attempting to parse them. If you
specify the option `-i` before the filename, it will enter an interactive
IPython session after running the script, rather than exiting.
Demo:
$ cat script.py
import sys
print(sys.argv)
$ ipython script.py -- --argument blah
['script.py', '--argument', 'blah']
$ ipython script.py -- arg1 arg2
['script.py', 'arg1', 'arg2']

ipython not showing argparse help message

In my python script myscript.py I use argparse to pass command-line arguments. When I want to display the help information about the input arguments, I just do:
$ python myscript.py --help
If instead I want to use ipython to run my script, the help message won't be displayed. Ipython will display its own help information:
$ ipython -- myscript.py -h
=========
IPython
=========
Tools for Interactive Computing in Python
=========================================
A Python shell with automatic history (input and output), dynamic object
introspection, easier configuration, command completion, access to the
system shell and more. IPython can also be embedded in running programs.
Usage
ipython [subcommand] [options] [files]
It's not so annoying, but is there a way around it?
You need to run your .py script inside the ipython. Something like that:
%run script.py -h
This is an IPython bug, corrected in https://github.com/ipython/ipython/pull/2663.
My 0.13 has this error; it is corrected in 0.13.2. The fix is in IPthyon/config/application.py Application.parse_command_line. This function looks for help and version flags (-h,-V) in sys.argv before passing things on to parse_known_args (hence the custom help formatting). In the corrected release, it checks sys.argv only up to the first --. Before it looked in the whole array.
earlier:
A fix for earlier releases is to define an alternate help flag in the script:
simple.py script:
import argparse, sys
print(sys.argv)
p = argparse.ArgumentParser(add_help=False) # turn off the regular -h
p.add_argument('-t')
p.add_argument('-a','--ayuda',action=argparse._HelpAction,help='alternate help')
print(p.parse_args())
Invoke with:
$ ./ipython3 -- simple.py -a
['/home/paul/mypy/argdev/simple.py', '-a']
usage: simple.py [-t T] [-a]
optional arguments:
-t T
-a, --ayuda alternate help
$ ./ipython3 -- simple.py -t test
['/home/paul/mypy/argdev/simple.py', '-t', 'test']
Namespace(t='test')

Getting output from Python script in Python tests

I've got a simple python script in file 'bin/test':
#!/usr/bin/env python
import argparse
PROGRAM_NAME = "name"
PROGRAM_VERSION = "0.0.1"
PROGRAM_DESCRIPTION = "desc"
parser = argparse.ArgumentParser(prog=PROGRAM_NAME, description=PROGRAM_DESCRIPTION)
parser.add_argument('--version', action='version', version='%(prog)s ' + PROGRAM_VERSION)
args = parser.parse_args()
When I run it with the --version param, or --help, it prints everything OK:
$ bin/test --version
name 0.0.1
$ bin/test --help
usage: name [-h] [--version]
desc
optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
When I run the file using subprocess.check_output, it doesn't get anything:
>>> subprocess.check_output(["bin/test", "--help"], stderr=subprocess.STDOUT, shell=True)
''
>>> subprocess.check_output(["bin/test", "--version"], stderr=subprocess.STDOUT, shell=True)
''
I'm using Ubuntu 11.10 with Python version:
python --version
Python 2.7.1+
I need to get the script output in tests. How should I do that?
If you're using shell=True, don't pass the program and its arguments as a list. This works:
subprocess.check_output("bin/test --help", stderr=subprocess.STDOUT, shell=True)
Edit: of course, leaving shell as False would have worked too.
Edit2: the documentation explains why
On Unix, with shell=True: If args is a string, it specifies the
command string to execute through the shell. This means that the
string must be formatted exactly as it would be when typed at the
shell prompt. This includes, for example, quoting or backslash
escaping filenames with spaces in them. If args is a sequence, the
first item specifies the command string, and any additional items will
be treated as additional arguments to the shell itself.

How do you pass script arguments to pdb (Python)?

I've got python script (ala #! /usr/bin/python) and I want to debug it with pdb. How can I pass arguments to the script?
I have a python script and would like to debug it with pdb. Is there a way that I can pass arguments to the scripts?
python -m pdb myscript.py arg1 arg2 ...
This invokes pdb as a script to debug another script. You can pass command-line arguments after the script name. See the pdb doc page for more details.
usually I use ipython
-i
If running code from the command line, become interactive afterwards.
It is often useful to follow this with `--` to treat remaining flags as
script arguments.
ipython --pdb -i -- test.py -a
python3 -m pdb myscript.py -a val if using argparse with flag "a" and value "val"
If, like me, you prefer the more graphical pudb debugger, you can pass the arguments of your script directly by doing:
pudb myscript.py arg1 arg2 ...
Indeed, invoking:
python -m pudb myscript.py arg1 arg2 ...
won't work will return with the following error:
No module named pudb.__main__; 'pudb' is a package and cannot be directly executed

Categories

Resources