-1

I'm writing script to generate Autosys report using Python 2.6, and I would like to pass variables from python script to bash command:

I have 3 variables:

NextMonth, NDNextMonth, Year

When I'm using the command with 1 varibale, it works properly.

    env = os.environ.copy()
env['NextMonth'] = NextMonth
subprocess.call('forecast -J *JobABC_* -M ALL -F "${NextMonth}/01/2020 00:00" -T "${NextMonth}/31/2020 23:59" -h -n > PythonReport1.txt', env=env, shell=True)

In the opposite way, it does not work, date is not valid:

    env = os.environ.copy()
env['NextMonth'] = NextMonth
env['NDNextMonth'] = NDNextMonth
env['Year'] = Year
subprocess.call('forecast -J *JobABC_* -M ALL -F "${NextMonth}/01/${Year}" 00:00" -T "${NextMonth}/${NDNextMonth}/${Year}" 23:59" -h -n > PythonReport1.txt',env=env, shell=True)

Could you please check, how to read those 3 variables into the command? Error: TypeError: execve() arg 3 contains a non-string value

achref05
  • 1,653
  • 4
  • 16
  • 18
  • 1
    ...why are you using environment variables for this in the first place? Wouldn't it make more sense to just interpolate the values into the string? – ChrisGPT was on strike Apr 12 '20 at 17:50
  • Possible duplicate of https://stackoverflow.com/questions/13213676/subprocess-popen-execve-arg-3-contains-a-non-string-value ? – Keldorn Apr 12 '20 at 17:54
  • I think you want to end the string with ` "${'+str(NextMonth)+'}/01/'` like that? – Christopher Hoffman Apr 12 '20 at 18:05
  • 1
    You have some extra double quotes in that string. Try: `subprocess.call('forecast -J *JobABC_* -M ALL -F "${NextMonth}/01/${Year} 00:00" -T "${NextMonth}/${NDNextMonth}/${Year} 23:59" -h -n > PythonReport1.txt',env=env, shell=True)` – rici Apr 12 '20 at 18:41
  • Resolved, it works like that: os.environ['NextMonth'] = str(NextMonth) os.environ['NDNextMonth'] = str(NDNextMonth) os.environ['Year'] = str(Year) subprocess.call('forecast -J *JobABC_* -M ALL -F "${NextMonth}/01/${Year}" 00:00" -T "${NextMonth}/${NDNextMonth}/${Year}" 23:59" -h -n > PythonReport1.txt', shell=True) – achref05 Apr 12 '20 at 19:20
  • @achref05, again, _why are you using environment variables in the first place?_ – ChrisGPT was on strike Apr 13 '20 at 00:41
  • @Chris as I cannot read Python variables in command, I found the solution by using them as environment variables. – achref05 Apr 14 '20 at 11:56
  • That's why I suggested _interpolating them into the string_: `f"{NextMonth}"`, or if you're on an old version of Python `"{}".format(NextMonth)`. – ChrisGPT was on strike Apr 14 '20 at 15:56

1 Answers1

0

As pointed out in comments, your variables work fine; the problem is that you have spurious double quotes in the string.

subprocess.call('forecast -J *JobABC_* -M ALL'
    ' -F "${NextMonth}/01/${Year} 00:00"'
    ' -T "${NextMonth}/${NDNextMonth}/${Year} 23:59"'
    ' -h -n > PythonReport1.txt',
    env=env, shell=True)

Notice how there is no closing double quote after either instance of ${Year} because the string does not end there.

Incidentally, the braces are not particularly useful here; you might as well use $Year etc. But if your task is merely to pass these values from Python to the shell, just do that, using whatever Python string interpolation mechanism you are comfortable with;

subprocess.call('forecast -J *JobABC_* -M ALL'
    ' -F "{0}/01/{2} 00:00"'
    ' -T "{0}/{1}/{2} 23:59"'
    ' -h -n > PythonReport1.txt'.format(NextMonth, NDNextMonth, Year),
    shell=True)

A much better solution is to avoid the shell entirely. Also, probably use check_call instead of plain old call. See further Running Bash commands in Python.

import glob
with open('PythonReport1.txt', 'w') as handle:
    subprocess.check_call(['forecast', '-J'] + glob.glob('*JobABC_*') +
        ['-M', 'ALL', '-F', "{0}/01/{1} 00:00".format(NextMonth, Year),
         '-T', "{0}/{1}/{2} 23:59".format(NextMonth, NDNextMonth, Year),
         '-h', '-n'], stdout=handle)
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Thank you for your answer, your solution looks much better. However the glob function did not work for me. like that is Ok: with open('PythonReport1.txt', 'w') as handle: subprocess.check_call(['forecast', '-J', '*JobABC_*' '-M', 'ALL', '-F', "{0}/01/{1} 00:00".format(NextMonth, Year), '-T', "{0}/{1}/{2} 23:59".format(NextMonth, NDNextMonth, Year), '-h', '-n'], stdout=handle) – achref05 Apr 14 '20 at 12:05
  • As you can see, code in comments really doesn't work. With `shell=True` your shell would expand the wildcard; without `shell=True` you have to do that (too) yourself. If you don't want the wildcard to match any files, you should quote it from the shell (or with `shell=True`); but then you can of course just pass it as a verbatim string from Python. – tripleee Apr 14 '20 at 12:37