Get command line arguments as string

48,805

Solution 1

An option:

import sys
' '.join(sys.argv[1:])

The join() function joins its arguments by whatever string you call it on. So ' '.join(...) joins the arguments with single spaces (' ') between them.

Solution 2

None of the previous answers properly escape all possible arguments, like empty args or those containing quotes. The closest you can get with minimal code is to use shlex.quote (available since Python 3.3):

import shlex
cmdline = " ".join(map(shlex.quote, sys.argv[1:]))

EDIT

Here is a Python 2+3 compatible solution:

import sys

try:
    from shlex import quote as cmd_quote
except ImportError:
    from pipes import quote as cmd_quote

cmdline = " ".join(map(cmd_quote, sys.argv[1:]))

Solution 3

The command line arguments are already handled by the shell before they are sent into sys.argv. Therefore, shell quoting and whitespace are gone and cannot be exactly reconstructed.

Assuming the user double-quotes strings with spaces, here's a python program to reconstruct the command string with those quotes.

commandstring = '';  

for arg in sys.argv[1:]:          # skip sys.argv[0] since the question didn't ask for it
    if ' ' in arg:
        commandstring+= '"{}"  '.format(arg) ;   # Put the quotes back in
    else:
        commandstring+="{}  ".format(arg) ;      # Assume no space => no quotes

print(commandstring); 

For example, the command line

./saferm.py sdkf lsadkf -r sdf -f sdf -fs -s "flksjfksdkfj sdfsdaflkasdf"

will produce the same arguments as output:

sdkf lsadkf -r sdf -f sdf -fs -s "flksjfksdkfj sdfsdaflkasdf"

since the user indeed double-quoted only arguments with strings.

Solution 4

You're getting a list object with all of your arguments when you use the syntax [1:] which goes from the second argument to the last. You could run a for each loop to join them into one string:

args = sys.argv[1:]
result = ''

for arg in args:
    result += " " + arg
Share:
48,805
KocT9H
Author by

KocT9H

Updated on July 09, 2022

Comments

  • KocT9H
    KocT9H about 2 years

    I want to print all command line arguments as a single string. Example of how I call my script and what I expect to be printed:

    ./RunT.py mytst.tst -c qwerty.c
    
    mytst.tst -c qwerty.c
    

    The code that does that:

    args = str(sys.argv[1:])
    args = args.replace("[","")
    args = args.replace("]","")
    args = args.replace(",","")
    args = args.replace("'","")
    print args
    

    I did all replaces because sys.argv[1:] returns this:

    ['mytst.tst', '-c', 'qwerty.c']
    

    Is there a better way to get same result? I don't like those multiple replace calls

  • TryToSolveItSimple
    TryToSolveItSimple about 8 years
    but you shouldn't name your variable after a class (reserved keyword) 'str'.
  • Brice
    Brice about 8 years
    @TryToSolveItSimple You're very right, I forgot which language I was using for a secong :P thanks!
  • KocT9H
    KocT9H about 8 years
    Thanks a lot! Worked for me
  • Natesh bhat
    Natesh bhat about 6 years
    this doesn't work when the original arguments contained spaces and were enclosed within double quotes , check out my answer , it covers that too .
  • cxw
    cxw about 6 years
    Interesting point --- you are right that it is impossible to exactly reconstruct the user's input 100% of the time. However, your answer above also will not work for single-quoted strings ('foo bar') or double-quoted strings without spaces ("foo") in bash, and maybe some other shells. Ah well! (Also, we can't exactly reconstruct the whitespace between arguments.)
  • Natesh bhat
    Natesh bhat about 6 years
    ya the purpose is to not alter the actions of the command. Even if we miss the quotes , it won't matter almost always if it doesn't contain any spaces in between . So we can't expect an exact match but a working one , we can .
  • mathewguest
    mathewguest over 5 years
    Works great. Here's the same thing as a list comprehension: commandstring = ' '.join(['"{}"'.format(a) if ' ' in a else '{}'.format(a) for a in sys.argv])
  • Maksym Ganenko
    Maksym Ganenko over 5 years
    I agree - this answer is antipattern because it doesn't escape spaces within arguments
  • Maksym Ganenko
    Maksym Ganenko over 5 years
    And what about escaping double/single quotes itself?
  • Maksym Ganenko
    Maksym Ganenko over 5 years
    Well, you forgot about escape symbols. Also it's not pythonic way to concatenate items of a list.
  • hola
    hola almost 5 years
    Any alternative for python 2?
  • Laurent LAPORTE
    Laurent LAPORTE almost 5 years
    @pushpen.paul, you can use pipes.quote. See my edit.
  • Laurent LAPORTE
    Laurent LAPORTE almost 5 years
    We should cosider szali's answer.
  • urben
    urben about 4 years
    there is an excess space at the front of the string
  • Jimm Chen
    Jimm Chen almost 4 years
    Thank you for pointing out shlex.quote. I think any attentive programmer dealing with Unix subprocess should know this vital escaping function.
  • redbmk
    redbmk almost 4 years
    If you're only targeting python 3 you could simplify this with shlex.join(sys.argv[1:])