0

I am trying to run a youtube-dl command but when os.system(command) run, it is waiting an input on terminal(there is no input required). I press enter 2-3 time than it starts downloading.

url = sys.argv[1]
command = "youtube-dl " + url
print("downloading...")
os.system(command)
print("test")

I can't see "test" output. command works on cmd properly. waiting or subprocess command not working.

dont start properly

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
sabrey
  • 47
  • 1
  • 7
  • You may wish to read [this post](https://stackoverflow.com/q/89228/9374673) on the difference between `subprocess` and `system`. – Mihai Chelaru Oct 20 '20 at 16:15
  • 1
    try waiting instead of pressing enter – Divyessh Oct 20 '20 at 16:20
  • i tried to wait but it's waiting an input. – sabrey Oct 20 '20 at 16:23
  • Redirect its stdin to come from `/dev/null`, and then it _can't_ wait for inputs. – Charles Duffy Oct 20 '20 at 16:26
  • (or, better, use `subprocess` and `stdin=subprocess.DEVNULL`; particularly important to use portable practices since you're on Windows). – Charles Duffy Oct 20 '20 at 16:26
  • ...using your current code has security bugs anyhow. If someone tells you to download a URL that contains `$(rm -rf ~)` (or its Windows-y equivalent if you're running a Windows-native interpreter), you'll have a very bad day. The extra control `subprocess` gives you isn't just useful in its own right, it also prevents Bad Things from happening. – Charles Duffy Oct 20 '20 at 16:27
  • you are right.thank you. it looks dangerous.how can i transfer parameter safely?"stdin=subprocess.DEVNULL; " it's work btw – sabrey Oct 20 '20 at 16:31
  • `subprocess.run(["youtube-dl", url], stdin=subprocess.DEVNULL)` – Charles Duffy Oct 20 '20 at 16:34
  • thank you charles. it worked. I added on topic. – sabrey Oct 20 '20 at 16:35
  • ...since you consider those comments a solution, I'll add a community-wiki answer that incorporates them so the question can be properly marked solved. – Charles Duffy Oct 20 '20 at 16:36
  • 1
    youtube-dl is written in Python and you can [import it like any other module](https://github.com/ytdl-org/youtube-dl/blob/master/README.md#embedding-youtube-dl) without going through `os`. – TigerhawkT3 Oct 20 '20 at 16:37

1 Answers1

2

Using subprocess instead of os.system will let you set stdin=subprocess.DEVNULL so it can't read from stdin (without going to the TTY, which most programs don't). Also, passing a list and keeping the default shell=False avoids security issues where contents inside the URL could be treated by the shell as commands to run.

subprocess.run(["youtube-dl", url], stdin=subprocess.DEVNULL)
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Nice. @CharlesDuffy or someone else...can you explain why this fixes the problem? Is it that `you-tube.dl` really is pulling some kind of input, or will this happen with any command? Is it the redirection of `stdin` that is the key point here vs the other differences between `system` and `subprocess.run`? Either which way, if `you-tube.dl` doesn't prompt for input when run at the command line, why won't it just run with `os.system`? – CryptoFool Oct 20 '20 at 16:42
  • @Steve, a fair number of programs try to "passively" look for input -- checking whether the user is typing anything and printing out status or whatnot if they do; that's enough to trigger a SIGTTIN when not foregrounded. Without knowing anything about youtube-dl in particular, I would guess it to be one of those. – Charles Duffy Oct 20 '20 at 16:49