How to find the exact CLI command for Python?

I want to find out the script inside - the exact command I used to run it. I tried the following:

#!/usr/bin/env python import sys, os print os.path.basename(sys.argv[0]), sys.argv[1:] 

But he is losing information:

 $ 1.py -1 dfd 'gf g' "df df" 1.py ['-1', 'dfd', 'gf g', 'df df'] 

You see - he already lost information about what is fading, I used double quotes, single quotes or no quotes at all - in the command.

Edit

Here is what I use. All arguments in my script have default values, and after parsing args with argparse :

 args = parser.parse_args() 

I will write them to the journal, or if there is a journal, rewrite them:

 logName = "." + (os.path.splitext(os.path.basename(sys.argv[0])))[0] + ".json" if os.path.exists(logName): print "!!! I've found log", logName Args = bk_loads_json(logName) for arg in Args: exec('args.{0} = Args["{0}"]'.format(arg)) else: print "!!! the log of args is saved to", logName bk_saves_json(args.__dict__, logName) 

defuns mentioned:

 def bk_saves_json(myCustomDct, flNm): "Takes dict, and writes it to the file." FlNm = open(flNm, 'w') tmpJsn = json.dumps(myCustomDct, sort_keys=True, indent=4) FlNm.write(tmpJsn) FlNm.close() def bk_loads_json(flNm): "Takes file of the json and returns it as a dict." json_data=open(flNm) data = json.load(json_data) json_data.close() return data 
+6
source share
2 answers

The information you are looking for (command options, including quotation marks) is not available.

The shell (bash), not python, reads and interprets the quotation marks — by the time python or any other spawned program sees the parameters, the quotation marks are removed. (Excluding quotes, of course.)

More details

When you enter a command in the shell, you use quotation marks to tell the shell that tokens on the command line are treated as a single parameter. Spaces are used to split the command line into separate parameters, and quotation marks are used to override: include spaces inside the parameter instead of individual parameters.

Then the shell opens the executable file and passes it a list of parameters. Any unquoted quotes were already "used up" by the shell when parsing your command line, so they actually no longer exist at this stage, and your team (python) does not see them.


By the way, I need to wonder why you care about getting quotes. I must say that at first glance it seems erroneous. Perhaps we can help if you tell us why you feel that you need them?

EDIT

In response to the OP comment below, here you can output the original command line - or at least functionally equivalent:

 import pipes # or shlex if python3 print sys.argv[0], ' '.join( [pipes.quote(s) for s in sys.argv[1:]] ) 

It simply adds quotes around all parameters.

+9
source

I would suggest using:

 import subprocess, sys print subprocess.list2cmdline(sys.argv[1:]) 

list2cmdline used to convert the argument list to a single line used from the shell. From the doc:

Translate the sequence of arguments into the string command line using the same rules as the MS C runtime:

1) The arguments are limited to a space, which is either a space or a tab.

2) A string surrounded by double quotes is interpreted as a single argument, regardless of the space contained in. The quoted string can be embedded in an argument.

3) The double quotation mark preceded by a backslash is interpreted as a literal double quotation mark.

4) Backslashes are interpreted literally, as long as they are immediately preceded by a double quote.

5) If the backslash immediately precedes the double quote character, each pair of backslashes is interpreted as a literal backslash. If the number of backslashes is odd, the last backslash resets the next double quote as described in rule 3.

+4
source

Source: https://habr.com/ru/post/925342/


All Articles