0

I want to restart nginx using subprocess.call. I'm using

subprocess.call("sudo systemctl restart nginx",shell=True)

However, when using shell=True the command didn't do anything while, I'm using shell=False it said no directory or files "command I implemented the subprocess.call in a button.

  • We have no idea why this fails, though. Does `subprocess.check_call(["sudo", "-l"])` succeed? If you have a GUI in front, there is no good way for `sudo` to ask you for a password. – tripleee Jan 09 '19 at 05:23
  • @tripleee i tried the command you give me and the server responded by no such file or directory "sudo". everytime i drop the shell=False they always return no such file or directory. i tried to call ("./ file.sh",shell=True) a shellscript i made consisting the restart command and it return non-zero exit status 127. and when using shell=False it return no such file... – Richard Khonan Jan 09 '19 at 06:43
  • If you do not have the `sudo` command installed, that certainly explains why you can't run this code. – tripleee Jan 09 '19 at 06:44
  • Again, with `shell=False`, you need to split it into a list yourself. But the token `./` is not valid syntax with or without a shell. Do you mean `"./file.sh"`? The way to run that with `shell=False` is `subprocess.call(["./file.sh"])`; notice how I have manually converted the command to a list of tokens (where of course because there is only one token, the list is also just one item). – tripleee Jan 09 '19 at 06:45
  • @tripleee sorry, now i get it. i try it and it doesn't return an error but the service itself didn't restart. – Richard Khonan Jan 09 '19 at 07:00
  • If you can't run `sudo` on the command line then obviously you cannot run it from Python either. Find instructions for how to install `sudo` for your platform (basically `apt-get` for Debian, `yum` for Red Hat, probably something like `emerge` for Gentoo, etc) and how to configure it properly. – tripleee Jan 09 '19 at 07:06
  • @tripleee I already have sudo installed. just now, i tried to reconfigure the sudo configuration but it stays the same so nothing happened. thanks btw for patiently responding. – Richard Khonan Jan 09 '19 at 07:27
  • Then if Python can't find `sudo` you have the wrong `PATH` inside Python. What's the value of `import os; print(os.environ["PATH"])` and how does it differ from your interactive `PATH` in a session where `sudo` does work? – tripleee Jan 09 '19 at 07:35
  • @tripleee thankyou its working now. :DD – Richard Khonan Jan 09 '19 at 08:04

1 Answers1

0

The difference between shell=True and shell=False on Unix-like systems is that the shell takes care of breaking up the command line for exec, whereas if you don't have a shell, you have to do that yourself.

The shell offers no benefits here, so you can safely drop it.

subprocess.call(["sudo", "systemctl", "restart", "nginx"])

So in the general case anything which looks like

subprocess.something("blah 'blah' \"blah\"", shell=True)

needs to be converted into a list without shell quoting to run it without shell=True:

subprocess.something(['blah', 'blah', "blah"])

and of course anything which is specific to the shell (redirection, pipelines, globbing, etc) will need to be replaced with native Python code.

More details at Actual meaning of 'shell=True' in subprocess and Running Bash commands in Python

If your original code didn't work, this also probably won't work, though.

tripleee
  • 175,061
  • 34
  • 275
  • 318