Search code examples
juliastdinsudo

Asynchronously executed command captures REPL input


I'm running an external command like this in Julia REPL:

stream, process = open(`sudo cat file.txt`, "w", STDOUT)

The command, sudo cat file.txt, when executed standardly in shell, asks for a password and then prints the file.

So I paste this into the REPL, press enter and it immediately returns, because the process runs asynchronously. Everything works as expected so far.

But when I start typing something else into the REPL, the characters I'm typing don't appear on screen (sudo is asking for the password), because the asynchronous process is (presumably) "stealing" the text I'm typing.


Solution

  • Your understanding of how open works is correct. As you've clarified in the comments, your question is about why sudo is asking for the password in the terminal instead of reading from stream. This is explained well by Bob at https://serverfault.com/a/731943. Quoting the relevant parts of the answer:

    Actually, a typical invocation of sudo does not read the password from stdin at all. Instead, sudo will directly access the controlling terminal (a tty or pty, via the /dev/tty special file) and output the prompt and read characters directly. This can be seen in the tgetpass.c file in the sudo source.

    sudo is capable of reading from stdin using the -S flag. You can use this if you'd like to write the password yourself from the script:

    Otherwise, if you specifically request sudo to read from stdin, e.g. with the -S flag -- and it will also write the prompt to stderr. This is the case where MadHatter's answer applies.