21

I am trying to create a bash script which passes its own argument onto a python script. I want it to work like this.

If I run it as this:

script.sh latest

Then within the bash script it runs a python script with the "latest" argument like this:

python script.py latest

Likewise if the bash script is run with the argument 123 then the python script as such:

python script.py 123

Can anyone help me understand how to accomplish this please?

1
  • 1
    What have you tried, so far? Passing and using arguments in bash scripts is part of any decent tutorial. Commented Jan 15, 2013 at 15:19

4 Answers 4

43

In this case the trick is to pass however many arguments you have, including the case where there are none, and to preserve any grouping that existed on the original command line.

So, you want these three cases to work:

script.sh                       # no args
script.sh how now               # some number
script.sh "how now" "brown cow" # args that need to stay quoted

There isn't really a natural way to do this because the shell is a macro language, so they've added some magic syntax that will just DTRT.

#!/bin/sh

python script.py "$@"
Sign up to request clarification or add additional context in comments.

Comments

7

In the pythonscript script.py use getopt.getopt(args, options[, long_options]) to get the arguments.

Example:

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError as err:
        # print help information and exit:
        print str(err) # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        elif o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-o", "--output"):
            output = a
        else:
            assert False, "unhandled option"
    # ...

if __name__ == "__main__":
    main()

Comments

4

A very goo buit-in parser is argparse. Yo can use it as follows:

  import argparse

  parser = argparse.ArgumentParser(description='Process some integers.')
  parser.add_argument('integers', metavar='N', type=int, nargs='+',
                   help='an integer for the accumulator')
  parser.add_argument('--sum', dest='accumulate', action='store_const',
                     const=sum, default=max,
                   help='sum the integers (default: find the max)')

  args = parser.parse_args()
  print(args.accumulate(args.integers))

Comments

1

In bash, arguments passed to the script are accessed with the $# notation (# being a number. Using $# exactly like that should give you the number of args passed). So if you wanted to pass arguments:

Calling the script:

`#script.sh argument`

Within the script:

python script.py "$1"

2 Comments

Need to quote "$1" to preserve whitespace
Thanks @glennjackman I've updated the code for future visitors.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.