0

I am working in Linux using Ansible. I am trying to run a script from a playbook, but I need to pass the script a few arguments: a string and 2 numbers. The first number is the number of times I need to retry to run the script, the second number variable is the retry attempt (which comes from a implement retry counter).

cat playbook.yml

---

- name: Increment variable
      ansible.builtin.set_fact:
        attempt_number: "{{ attempt_number | d(0) | int + 1 }}"

- name: Running Script
      command: "{{ my_dir }}/script.py {{ string }} {{ max_retries }} {{ attempt_number | int }}"

The python script looks like this: cat script.py

var1=sys.argv[0]
var2=sys.argv[1]
var3=sys.argv[2]

print "String %s" % var1
print "Num1 %d" % var2
print "Num2 %d" % var3

First I am just trying to check If the variable are being passed to the python script but I am getting this error:

" File "", line 6, in ", "TypeError: %d format: a number is required, not str"]

What am I doing wrong? How can I change this, so my python script receive all the 3 parameters?

fr0zt
  • 733
  • 4
  • 12
  • 30
  • 1
    The parameters are all strings. So just wrap them in `int()`, like `int(var2)` or `int(sys.argv[1])`. Although a bigger problem is that this script is written in Python 2, but that's been deprecated for over 3 years. You generally should use Python 3 unless you have a really specific reason to dig up Python 2. – Random Davis Feb 16 '23 at 17:13

3 Answers3

3

Command line argument values are always strings. If you mean for them to be something else (e.g. int) you have to do that yourself - including any error handling when users pass in the wrong thing:

var1 = sys.argv[0]
var2 = int(sys.argv[1])
var3 = int(sys.argv[2])

try:
    int_arg = int(sys.argv[1])
except ValueError:
    print("invalid command; usage: ...")
Woodford
  • 3,746
  • 1
  • 15
  • 29
3

Your issue is because command line args in sys.argv are strings. You need to cast them to an int before you can use them (int(sys.argv[0]).

Would also recommend using Python3 instead of Python2. Python2 is deprecated and should not be used for any purposes.

As Python2 is a requirement for your task:

var1=sys.argv[0]
var2=int(sys.argv[1])
var3=int(sys.argv[2])

print "String %s" % var1
print "Num1 %d" % var2
print "Num2 %d" % var3

You may want to consider looking at importing from the __future__ module if you are on Python 2.6+. This will allow you to use the print function instead of the keyword. See this Stack Overflow thread for more info.

Python3 would allow you to use f strings for printing:

foo = sys.argv[0]
bar = sys.argv[1]

print(f"First arg is {foo}")
print(f"Second arg is {bar}")
blackbrandt
  • 2,010
  • 1
  • 15
  • 32
  • I am working with python 2, as this is a must of a technology which I am using – fr0zt Feb 16 '23 at 17:59
  • That is extremely unfortunate. The first part of the answer still applies, however. I have made some edits to give some more information and tips on Python2. – blackbrandt Feb 16 '23 at 19:47
1

Another way of doing this would be to use f strings (Only for python 3+). It looks very clean, and it's easy to read.

var1=sys.argv[0]
var2=sys.argv[1]
var3=sys.argv[2]

print(f"String {var1}")
print(f"Num1 {var2}")
print(f"Num2 {var3}")
Blue Robin
  • 847
  • 2
  • 11
  • 31