0

I have written two python scripts A.py and B.py So B.py gets called in A.py like this:

config_object = {}
with open(config_filename) as data:
  config_object = json.load(data, object_pairs_hook=OrderedDict)
command = './scripts/B.py --config-file={} --token-a={} --token-b={}'.format(promote_config_filename, config_object['username'], config_object['password'])
      os.system(command)

In here config_object['password'] contains & in it. Say it is something like this S01S0lQb1T3&BRn2^Qt3

Now when this value get passed to B.py it gets password as S01S0lQb1T3 So after & whatever it is getting ignored.

How to solve this?

bu0603
  • 37
  • 2
  • 3
  • 1
    why are you using `os` to call a python script instead of just importing it and calling the function within python? –  Feb 03 '22 at 14:00

2 Answers2

1

os.system runs a shell. You can escape arbitrary strings for the shell with shlex.quote() ... but a much superior solution is to use subprocess instead, like the os.system documentation also recommends.

subprocess.run(
    ['./scripts/B.py',
     '--config-file={}'.format(promote_config_filename),
     '--token-a={}'.format(config_object['username']),
     '--token-b={}'.format(config_object['password'])])

Because there is no shell=True, the strings are now passed to the subprocess verbatim.

Perhaps see also Actual meaning of shell=True in subprocess

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 1
    Tangentially, running Python as a subprocess of itself is also weird. The proper solution in most cases would be to `import B` and run its main function directly from your current script. (Maybe you have to refactor `B.py` before this is feasible.) – tripleee Feb 03 '22 at 14:02
0

@tripleee has good suggestions. In terms of why this is happening, if you are running Linux/Unix at least, the & would start a background process. You can search "linux job control" for more info on that. The shortest (but not best) solution is to wrap your special characters in single or double quotes in the final command.

See this bash for a simple example:

$ echo foo&bar
[1] 20054
foo
Command 'bar' not found, but can be installed with:
sudo apt install bar
[1]+  Done                    echo foo

$ echo "foo&bar"
foo&bar
dcc310
  • 1,038
  • 1
  • 9
  • 13