Writing to stdin of a processConstruct a command by putting a string into a ttystop pipe() opening...

Why should I always enable compiler warnings?

How to find a reviewer/editor for my paper?

Why does low tire pressure decrease fuel economy?

The meaning of "offing" in "an agreement in the offing"

The pirate treasure of Leatherback Atoll

Yet another calculator problem

How is lower/no gravity simulated on a planet with gravity, without leaving the surface?

Methods and Feasibility of Antimatter Mining?

How to descend a few exposed scrambling moves with minimal equipment?

Chandrayaan 2: Why is Vikram Lander's life limited to 14 Days?

RANK used in 'where' returns invalid column, but exists in results set

Maze generator & animator in Python

What makes things real?

Can you mark a new target with the Hunter's Mark spell if the original target shifts to a different plane?

How can faith be maintained in a world of living gods?

How should we understand "unobscured by flying friends" in this context?

Lost & Found Mobile Telepone

How to set any file manager in Linux to show the duration like the Length feature in Windows Explorer?

When did computers stop checking memory on boot?

Distinguishing between octahedral and tetrahedral holes

Change-due function

How do I politely hint customers to leave my store, without pretending to need leave store myself?

Features seen on the Space Shuttle's solid booster; what does "LOADED" mean exactly?

Why can linguists decide which use of language is correct and which is not?



Writing to stdin of a process


Construct a command by putting a string into a ttystop pipe() opening stdinPortability of file descriptor linksHow does the shell/init create the stdio streams?Why does moving forward switch the file system here?cryptsetup - how does it print prompt bypassing stdout/stdin redirection?Can you seek to a filehandle owned by another process as root?Why I can't see port opened by a process in file descriptors?display the file descriptors of a process using pythonHow does the act of closing shared file descriptors with a write-blocked process cause it to unblock?Send string to another process stdin






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







9















As far as I understand if i type the following...



 python -i


... the python-interpreter will now read from stdin, behaving (obviously) like this:



 >>> print "Hello"
Hello


I would expect it to do the same thing if I do this:



 echo 'print "Hello"' > /proc/$(pidof python)/fd/0


But this is the output ( beeing an actual empty line):



 >>> print "Hello"
<empyline>


This to me looks like, it just took the print "Hello"n and wrote it to stdout, yet did not interpret it. Why is that not working and what would I have to do to make it working?










share|improve this question



























  • The TIOCSTI ioctl can write to a terminal's stdin as if the data has been entered from the keyboard. For example github.com/thrig/scripts/blob/master/tty/ttywrite.c

    – roaima
    Aug 13 '17 at 6:00


















9















As far as I understand if i type the following...



 python -i


... the python-interpreter will now read from stdin, behaving (obviously) like this:



 >>> print "Hello"
Hello


I would expect it to do the same thing if I do this:



 echo 'print "Hello"' > /proc/$(pidof python)/fd/0


But this is the output ( beeing an actual empty line):



 >>> print "Hello"
<empyline>


This to me looks like, it just took the print "Hello"n and wrote it to stdout, yet did not interpret it. Why is that not working and what would I have to do to make it working?










share|improve this question



























  • The TIOCSTI ioctl can write to a terminal's stdin as if the data has been entered from the keyboard. For example github.com/thrig/scripts/blob/master/tty/ttywrite.c

    – roaima
    Aug 13 '17 at 6:00














9












9








9


3






As far as I understand if i type the following...



 python -i


... the python-interpreter will now read from stdin, behaving (obviously) like this:



 >>> print "Hello"
Hello


I would expect it to do the same thing if I do this:



 echo 'print "Hello"' > /proc/$(pidof python)/fd/0


But this is the output ( beeing an actual empty line):



 >>> print "Hello"
<empyline>


This to me looks like, it just took the print "Hello"n and wrote it to stdout, yet did not interpret it. Why is that not working and what would I have to do to make it working?










share|improve this question
















As far as I understand if i type the following...



 python -i


... the python-interpreter will now read from stdin, behaving (obviously) like this:



 >>> print "Hello"
Hello


I would expect it to do the same thing if I do this:



 echo 'print "Hello"' > /proc/$(pidof python)/fd/0


But this is the output ( beeing an actual empty line):



 >>> print "Hello"
<empyline>


This to me looks like, it just took the print "Hello"n and wrote it to stdout, yet did not interpret it. Why is that not working and what would I have to do to make it working?







proc file-descriptors






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 15:19









filbranden

13.7k2 gold badges28 silver badges57 bronze badges




13.7k2 gold badges28 silver badges57 bronze badges










asked Aug 13 '17 at 4:33









SheppySheppy

581 silver badge7 bronze badges




581 silver badge7 bronze badges
















  • The TIOCSTI ioctl can write to a terminal's stdin as if the data has been entered from the keyboard. For example github.com/thrig/scripts/blob/master/tty/ttywrite.c

    – roaima
    Aug 13 '17 at 6:00



















  • The TIOCSTI ioctl can write to a terminal's stdin as if the data has been entered from the keyboard. For example github.com/thrig/scripts/blob/master/tty/ttywrite.c

    – roaima
    Aug 13 '17 at 6:00

















The TIOCSTI ioctl can write to a terminal's stdin as if the data has been entered from the keyboard. For example github.com/thrig/scripts/blob/master/tty/ttywrite.c

– roaima
Aug 13 '17 at 6:00





The TIOCSTI ioctl can write to a terminal's stdin as if the data has been entered from the keyboard. For example github.com/thrig/scripts/blob/master/tty/ttywrite.c

– roaima
Aug 13 '17 at 6:00










3 Answers
3






active

oldest

votes


















6
















Sending input to shells/interpreters in this way is very problem-prone and very difficult to get working in any reliable way.



The proper way is to use sockets, this is why they were invented, you can do this in command line using ncat nc or socat to bind a python process to a simple socket. Or write a simple python application that binds to port and listens for commands to interpret on a socket.



sockets can be local and not exposed to any web interface.





The problem is that if you start python from the command line, it is typically attached to your shell which is attached to a terminal, in fact we can see



$ ls -al /proc/PID/fd
lrwxrwxrwx 1 USER GROUP 0 Aug 1 00:00 0 -> /dev/pty1


so when you write to stdin of python, you are actually writing to the pty psuedo-terminal, which is a kernel device, not a simple file. It uses ioctl not read and write, so you will see output on your screen, but it will not be sent to the spawned process (python)



One way to replicate what you are trying is with a fifo or named pipe.



# make pipe
$ mkfifo python_i.pipe
# start python interactive with pipe input
# Will print to pty output unless redirected
$ python -i < python_i.pipe &
# keep pipe open
$ sleep infinity > python_i.pipe &
# interact with the interpreter
$ echo "print "hello"" >> python_i.pipe


You can also use screen for input only



# start screen 
$ screen -dmS python python
# send command to input
$ screen -S python -X 'print "hello"'
# view output
$ screen -S python -x





share|improve this answer




























  • If you hold the pipe open (eg sleep 300 > python_i.pipe &) the other side won't close and python will continue to accept commands down the pipe. There is no EOF as such sent by echo.

    – roaima
    Aug 13 '17 at 5:54













  • @roaima you are right, I was mistaken in my understanding that echo sends the EOF when it closes the stream. This is not avoidable with | pipes, however , correct?

    – crasic
    Aug 13 '17 at 5:56











  • I was already down the fifo road, but echo something > fifo would cause it to get an EOF which would stop many applications. The sleep infinity > fifo workaround didn't cross my mid though, thank you!

    – Sheppy
    Aug 13 '17 at 6:00











  • actually continuing your idea, you can also do python -i <> fifo which will also prevent the EOF

    – Sheppy
    Aug 13 '17 at 6:45



















8
















Accessing /proc/PID/fd/0 doesn't access file descriptor 0 of process PID, it accesses the file which PID has open on file descriptor 0. This is a subtle distinction, but it matters. A file descriptor is a connection that a process has to a file. Writing to a file descriptor writes to the file regardless of how the file has been opened.



If /proc/PID/fd/0 is a regular file, writing to it modifies the file. The data isn't necessarily what the process will read next: it depends on the position attached to the file descriptor that the process is using to read the file. When a process opens /proc/PID/fd/0, it gets the same file as the other process, but the file positions are independent.



If /proc/PID/fd/0 is a pipe, then writing to it appends the data to the pipe's buffer. In that case, the process that's reading from the pipe will read the data.



If /proc/PID/fd/0 is a terminal, then writing to it outputs the data on a terminal. A terminal file is bidirectional: writing to it outputs the data, i.e. the terminal displays the text; reading from a terminal inputs the data, i.e. the terminal transmits user input.



Python is both reading and writing to the terminal. When you run echo 'print "Hello"' > /proc/$(pidof python)/fd/0, you're writing print "Hello" to the terminal. The terminal displays print "Hello" as instructed. The python process doesn't see anything, it's still waiting for input.



If you want to feed input to the Python process, you have to get the terminal to do it. See crasic's answer for ways to do that.






share|improve this answer

































    0
















    Building off of what Gilles said, if we want to write to a process's stdin that is attached to a terminal, we actually need to send the information to the terminal. However, because a terminal serves as a form of input as well as output, when writing to it the terminal has no way of knowing that you want to write to a process running within it rather than the "screen".



    Linux however has a non-posix way of simulating user input through an ioctl request called TIOCSTI (Terminal I/O Control - Simulate Terminal Input) which allows us to send characters to a terminal as if they were typed by a user.



    I'm only superficially aware of how this works, but based on this answer, it should be possible to do this with something along the lines of



    import fcntl, sys, termios

    tty_path = sys.argv[1]

    with open(tty_path, 'wb') as tty_fd:
    for line in sys.stdin.buffer:
    for byte in line:
    fcntl.ioctl(tty_fd, termios.TIOCSTI, bytes([byte]))


    Some external resources:



    http://man7.org/linux/man-pages/man2/ioctl.2.html



    http://man7.org/linux/man-pages/man2/ioctl_tty.2.html






    share|improve this answer








    New contributor



    Christian Reall-Fluharty is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.
























      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "106"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });















      draft saved

      draft discarded
















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f385771%2fwriting-to-stdin-of-a-process%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      6
















      Sending input to shells/interpreters in this way is very problem-prone and very difficult to get working in any reliable way.



      The proper way is to use sockets, this is why they were invented, you can do this in command line using ncat nc or socat to bind a python process to a simple socket. Or write a simple python application that binds to port and listens for commands to interpret on a socket.



      sockets can be local and not exposed to any web interface.





      The problem is that if you start python from the command line, it is typically attached to your shell which is attached to a terminal, in fact we can see



      $ ls -al /proc/PID/fd
      lrwxrwxrwx 1 USER GROUP 0 Aug 1 00:00 0 -> /dev/pty1


      so when you write to stdin of python, you are actually writing to the pty psuedo-terminal, which is a kernel device, not a simple file. It uses ioctl not read and write, so you will see output on your screen, but it will not be sent to the spawned process (python)



      One way to replicate what you are trying is with a fifo or named pipe.



      # make pipe
      $ mkfifo python_i.pipe
      # start python interactive with pipe input
      # Will print to pty output unless redirected
      $ python -i < python_i.pipe &
      # keep pipe open
      $ sleep infinity > python_i.pipe &
      # interact with the interpreter
      $ echo "print "hello"" >> python_i.pipe


      You can also use screen for input only



      # start screen 
      $ screen -dmS python python
      # send command to input
      $ screen -S python -X 'print "hello"'
      # view output
      $ screen -S python -x





      share|improve this answer




























      • If you hold the pipe open (eg sleep 300 > python_i.pipe &) the other side won't close and python will continue to accept commands down the pipe. There is no EOF as such sent by echo.

        – roaima
        Aug 13 '17 at 5:54













      • @roaima you are right, I was mistaken in my understanding that echo sends the EOF when it closes the stream. This is not avoidable with | pipes, however , correct?

        – crasic
        Aug 13 '17 at 5:56











      • I was already down the fifo road, but echo something > fifo would cause it to get an EOF which would stop many applications. The sleep infinity > fifo workaround didn't cross my mid though, thank you!

        – Sheppy
        Aug 13 '17 at 6:00











      • actually continuing your idea, you can also do python -i <> fifo which will also prevent the EOF

        – Sheppy
        Aug 13 '17 at 6:45
















      6
















      Sending input to shells/interpreters in this way is very problem-prone and very difficult to get working in any reliable way.



      The proper way is to use sockets, this is why they were invented, you can do this in command line using ncat nc or socat to bind a python process to a simple socket. Or write a simple python application that binds to port and listens for commands to interpret on a socket.



      sockets can be local and not exposed to any web interface.





      The problem is that if you start python from the command line, it is typically attached to your shell which is attached to a terminal, in fact we can see



      $ ls -al /proc/PID/fd
      lrwxrwxrwx 1 USER GROUP 0 Aug 1 00:00 0 -> /dev/pty1


      so when you write to stdin of python, you are actually writing to the pty psuedo-terminal, which is a kernel device, not a simple file. It uses ioctl not read and write, so you will see output on your screen, but it will not be sent to the spawned process (python)



      One way to replicate what you are trying is with a fifo or named pipe.



      # make pipe
      $ mkfifo python_i.pipe
      # start python interactive with pipe input
      # Will print to pty output unless redirected
      $ python -i < python_i.pipe &
      # keep pipe open
      $ sleep infinity > python_i.pipe &
      # interact with the interpreter
      $ echo "print "hello"" >> python_i.pipe


      You can also use screen for input only



      # start screen 
      $ screen -dmS python python
      # send command to input
      $ screen -S python -X 'print "hello"'
      # view output
      $ screen -S python -x





      share|improve this answer




























      • If you hold the pipe open (eg sleep 300 > python_i.pipe &) the other side won't close and python will continue to accept commands down the pipe. There is no EOF as such sent by echo.

        – roaima
        Aug 13 '17 at 5:54













      • @roaima you are right, I was mistaken in my understanding that echo sends the EOF when it closes the stream. This is not avoidable with | pipes, however , correct?

        – crasic
        Aug 13 '17 at 5:56











      • I was already down the fifo road, but echo something > fifo would cause it to get an EOF which would stop many applications. The sleep infinity > fifo workaround didn't cross my mid though, thank you!

        – Sheppy
        Aug 13 '17 at 6:00











      • actually continuing your idea, you can also do python -i <> fifo which will also prevent the EOF

        – Sheppy
        Aug 13 '17 at 6:45














      6














      6










      6









      Sending input to shells/interpreters in this way is very problem-prone and very difficult to get working in any reliable way.



      The proper way is to use sockets, this is why they were invented, you can do this in command line using ncat nc or socat to bind a python process to a simple socket. Or write a simple python application that binds to port and listens for commands to interpret on a socket.



      sockets can be local and not exposed to any web interface.





      The problem is that if you start python from the command line, it is typically attached to your shell which is attached to a terminal, in fact we can see



      $ ls -al /proc/PID/fd
      lrwxrwxrwx 1 USER GROUP 0 Aug 1 00:00 0 -> /dev/pty1


      so when you write to stdin of python, you are actually writing to the pty psuedo-terminal, which is a kernel device, not a simple file. It uses ioctl not read and write, so you will see output on your screen, but it will not be sent to the spawned process (python)



      One way to replicate what you are trying is with a fifo or named pipe.



      # make pipe
      $ mkfifo python_i.pipe
      # start python interactive with pipe input
      # Will print to pty output unless redirected
      $ python -i < python_i.pipe &
      # keep pipe open
      $ sleep infinity > python_i.pipe &
      # interact with the interpreter
      $ echo "print "hello"" >> python_i.pipe


      You can also use screen for input only



      # start screen 
      $ screen -dmS python python
      # send command to input
      $ screen -S python -X 'print "hello"'
      # view output
      $ screen -S python -x





      share|improve this answer















      Sending input to shells/interpreters in this way is very problem-prone and very difficult to get working in any reliable way.



      The proper way is to use sockets, this is why they were invented, you can do this in command line using ncat nc or socat to bind a python process to a simple socket. Or write a simple python application that binds to port and listens for commands to interpret on a socket.



      sockets can be local and not exposed to any web interface.





      The problem is that if you start python from the command line, it is typically attached to your shell which is attached to a terminal, in fact we can see



      $ ls -al /proc/PID/fd
      lrwxrwxrwx 1 USER GROUP 0 Aug 1 00:00 0 -> /dev/pty1


      so when you write to stdin of python, you are actually writing to the pty psuedo-terminal, which is a kernel device, not a simple file. It uses ioctl not read and write, so you will see output on your screen, but it will not be sent to the spawned process (python)



      One way to replicate what you are trying is with a fifo or named pipe.



      # make pipe
      $ mkfifo python_i.pipe
      # start python interactive with pipe input
      # Will print to pty output unless redirected
      $ python -i < python_i.pipe &
      # keep pipe open
      $ sleep infinity > python_i.pipe &
      # interact with the interpreter
      $ echo "print "hello"" >> python_i.pipe


      You can also use screen for input only



      # start screen 
      $ screen -dmS python python
      # send command to input
      $ screen -S python -X 'print "hello"'
      # view output
      $ screen -S python -x






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Aug 13 '17 at 6:04

























      answered Aug 13 '17 at 5:36









      crasiccrasic

      3062 silver badges9 bronze badges




      3062 silver badges9 bronze badges
















      • If you hold the pipe open (eg sleep 300 > python_i.pipe &) the other side won't close and python will continue to accept commands down the pipe. There is no EOF as such sent by echo.

        – roaima
        Aug 13 '17 at 5:54













      • @roaima you are right, I was mistaken in my understanding that echo sends the EOF when it closes the stream. This is not avoidable with | pipes, however , correct?

        – crasic
        Aug 13 '17 at 5:56











      • I was already down the fifo road, but echo something > fifo would cause it to get an EOF which would stop many applications. The sleep infinity > fifo workaround didn't cross my mid though, thank you!

        – Sheppy
        Aug 13 '17 at 6:00











      • actually continuing your idea, you can also do python -i <> fifo which will also prevent the EOF

        – Sheppy
        Aug 13 '17 at 6:45



















      • If you hold the pipe open (eg sleep 300 > python_i.pipe &) the other side won't close and python will continue to accept commands down the pipe. There is no EOF as such sent by echo.

        – roaima
        Aug 13 '17 at 5:54













      • @roaima you are right, I was mistaken in my understanding that echo sends the EOF when it closes the stream. This is not avoidable with | pipes, however , correct?

        – crasic
        Aug 13 '17 at 5:56











      • I was already down the fifo road, but echo something > fifo would cause it to get an EOF which would stop many applications. The sleep infinity > fifo workaround didn't cross my mid though, thank you!

        – Sheppy
        Aug 13 '17 at 6:00











      • actually continuing your idea, you can also do python -i <> fifo which will also prevent the EOF

        – Sheppy
        Aug 13 '17 at 6:45

















      If you hold the pipe open (eg sleep 300 > python_i.pipe &) the other side won't close and python will continue to accept commands down the pipe. There is no EOF as such sent by echo.

      – roaima
      Aug 13 '17 at 5:54







      If you hold the pipe open (eg sleep 300 > python_i.pipe &) the other side won't close and python will continue to accept commands down the pipe. There is no EOF as such sent by echo.

      – roaima
      Aug 13 '17 at 5:54















      @roaima you are right, I was mistaken in my understanding that echo sends the EOF when it closes the stream. This is not avoidable with | pipes, however , correct?

      – crasic
      Aug 13 '17 at 5:56





      @roaima you are right, I was mistaken in my understanding that echo sends the EOF when it closes the stream. This is not avoidable with | pipes, however , correct?

      – crasic
      Aug 13 '17 at 5:56













      I was already down the fifo road, but echo something > fifo would cause it to get an EOF which would stop many applications. The sleep infinity > fifo workaround didn't cross my mid though, thank you!

      – Sheppy
      Aug 13 '17 at 6:00





      I was already down the fifo road, but echo something > fifo would cause it to get an EOF which would stop many applications. The sleep infinity > fifo workaround didn't cross my mid though, thank you!

      – Sheppy
      Aug 13 '17 at 6:00













      actually continuing your idea, you can also do python -i <> fifo which will also prevent the EOF

      – Sheppy
      Aug 13 '17 at 6:45





      actually continuing your idea, you can also do python -i <> fifo which will also prevent the EOF

      – Sheppy
      Aug 13 '17 at 6:45













      8
















      Accessing /proc/PID/fd/0 doesn't access file descriptor 0 of process PID, it accesses the file which PID has open on file descriptor 0. This is a subtle distinction, but it matters. A file descriptor is a connection that a process has to a file. Writing to a file descriptor writes to the file regardless of how the file has been opened.



      If /proc/PID/fd/0 is a regular file, writing to it modifies the file. The data isn't necessarily what the process will read next: it depends on the position attached to the file descriptor that the process is using to read the file. When a process opens /proc/PID/fd/0, it gets the same file as the other process, but the file positions are independent.



      If /proc/PID/fd/0 is a pipe, then writing to it appends the data to the pipe's buffer. In that case, the process that's reading from the pipe will read the data.



      If /proc/PID/fd/0 is a terminal, then writing to it outputs the data on a terminal. A terminal file is bidirectional: writing to it outputs the data, i.e. the terminal displays the text; reading from a terminal inputs the data, i.e. the terminal transmits user input.



      Python is both reading and writing to the terminal. When you run echo 'print "Hello"' > /proc/$(pidof python)/fd/0, you're writing print "Hello" to the terminal. The terminal displays print "Hello" as instructed. The python process doesn't see anything, it's still waiting for input.



      If you want to feed input to the Python process, you have to get the terminal to do it. See crasic's answer for ways to do that.






      share|improve this answer






























        8
















        Accessing /proc/PID/fd/0 doesn't access file descriptor 0 of process PID, it accesses the file which PID has open on file descriptor 0. This is a subtle distinction, but it matters. A file descriptor is a connection that a process has to a file. Writing to a file descriptor writes to the file regardless of how the file has been opened.



        If /proc/PID/fd/0 is a regular file, writing to it modifies the file. The data isn't necessarily what the process will read next: it depends on the position attached to the file descriptor that the process is using to read the file. When a process opens /proc/PID/fd/0, it gets the same file as the other process, but the file positions are independent.



        If /proc/PID/fd/0 is a pipe, then writing to it appends the data to the pipe's buffer. In that case, the process that's reading from the pipe will read the data.



        If /proc/PID/fd/0 is a terminal, then writing to it outputs the data on a terminal. A terminal file is bidirectional: writing to it outputs the data, i.e. the terminal displays the text; reading from a terminal inputs the data, i.e. the terminal transmits user input.



        Python is both reading and writing to the terminal. When you run echo 'print "Hello"' > /proc/$(pidof python)/fd/0, you're writing print "Hello" to the terminal. The terminal displays print "Hello" as instructed. The python process doesn't see anything, it's still waiting for input.



        If you want to feed input to the Python process, you have to get the terminal to do it. See crasic's answer for ways to do that.






        share|improve this answer




























          8














          8










          8









          Accessing /proc/PID/fd/0 doesn't access file descriptor 0 of process PID, it accesses the file which PID has open on file descriptor 0. This is a subtle distinction, but it matters. A file descriptor is a connection that a process has to a file. Writing to a file descriptor writes to the file regardless of how the file has been opened.



          If /proc/PID/fd/0 is a regular file, writing to it modifies the file. The data isn't necessarily what the process will read next: it depends on the position attached to the file descriptor that the process is using to read the file. When a process opens /proc/PID/fd/0, it gets the same file as the other process, but the file positions are independent.



          If /proc/PID/fd/0 is a pipe, then writing to it appends the data to the pipe's buffer. In that case, the process that's reading from the pipe will read the data.



          If /proc/PID/fd/0 is a terminal, then writing to it outputs the data on a terminal. A terminal file is bidirectional: writing to it outputs the data, i.e. the terminal displays the text; reading from a terminal inputs the data, i.e. the terminal transmits user input.



          Python is both reading and writing to the terminal. When you run echo 'print "Hello"' > /proc/$(pidof python)/fd/0, you're writing print "Hello" to the terminal. The terminal displays print "Hello" as instructed. The python process doesn't see anything, it's still waiting for input.



          If you want to feed input to the Python process, you have to get the terminal to do it. See crasic's answer for ways to do that.






          share|improve this answer













          Accessing /proc/PID/fd/0 doesn't access file descriptor 0 of process PID, it accesses the file which PID has open on file descriptor 0. This is a subtle distinction, but it matters. A file descriptor is a connection that a process has to a file. Writing to a file descriptor writes to the file regardless of how the file has been opened.



          If /proc/PID/fd/0 is a regular file, writing to it modifies the file. The data isn't necessarily what the process will read next: it depends on the position attached to the file descriptor that the process is using to read the file. When a process opens /proc/PID/fd/0, it gets the same file as the other process, but the file positions are independent.



          If /proc/PID/fd/0 is a pipe, then writing to it appends the data to the pipe's buffer. In that case, the process that's reading from the pipe will read the data.



          If /proc/PID/fd/0 is a terminal, then writing to it outputs the data on a terminal. A terminal file is bidirectional: writing to it outputs the data, i.e. the terminal displays the text; reading from a terminal inputs the data, i.e. the terminal transmits user input.



          Python is both reading and writing to the terminal. When you run echo 'print "Hello"' > /proc/$(pidof python)/fd/0, you're writing print "Hello" to the terminal. The terminal displays print "Hello" as instructed. The python process doesn't see anything, it's still waiting for input.



          If you want to feed input to the Python process, you have to get the terminal to do it. See crasic's answer for ways to do that.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 14 '17 at 0:58









          GillesGilles

          574k139 gold badges1184 silver badges1695 bronze badges




          574k139 gold badges1184 silver badges1695 bronze badges


























              0
















              Building off of what Gilles said, if we want to write to a process's stdin that is attached to a terminal, we actually need to send the information to the terminal. However, because a terminal serves as a form of input as well as output, when writing to it the terminal has no way of knowing that you want to write to a process running within it rather than the "screen".



              Linux however has a non-posix way of simulating user input through an ioctl request called TIOCSTI (Terminal I/O Control - Simulate Terminal Input) which allows us to send characters to a terminal as if they were typed by a user.



              I'm only superficially aware of how this works, but based on this answer, it should be possible to do this with something along the lines of



              import fcntl, sys, termios

              tty_path = sys.argv[1]

              with open(tty_path, 'wb') as tty_fd:
              for line in sys.stdin.buffer:
              for byte in line:
              fcntl.ioctl(tty_fd, termios.TIOCSTI, bytes([byte]))


              Some external resources:



              http://man7.org/linux/man-pages/man2/ioctl.2.html



              http://man7.org/linux/man-pages/man2/ioctl_tty.2.html






              share|improve this answer








              New contributor



              Christian Reall-Fluharty is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
              Check out our Code of Conduct.


























                0
















                Building off of what Gilles said, if we want to write to a process's stdin that is attached to a terminal, we actually need to send the information to the terminal. However, because a terminal serves as a form of input as well as output, when writing to it the terminal has no way of knowing that you want to write to a process running within it rather than the "screen".



                Linux however has a non-posix way of simulating user input through an ioctl request called TIOCSTI (Terminal I/O Control - Simulate Terminal Input) which allows us to send characters to a terminal as if they were typed by a user.



                I'm only superficially aware of how this works, but based on this answer, it should be possible to do this with something along the lines of



                import fcntl, sys, termios

                tty_path = sys.argv[1]

                with open(tty_path, 'wb') as tty_fd:
                for line in sys.stdin.buffer:
                for byte in line:
                fcntl.ioctl(tty_fd, termios.TIOCSTI, bytes([byte]))


                Some external resources:



                http://man7.org/linux/man-pages/man2/ioctl.2.html



                http://man7.org/linux/man-pages/man2/ioctl_tty.2.html






                share|improve this answer








                New contributor



                Christian Reall-Fluharty is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.
























                  0














                  0










                  0









                  Building off of what Gilles said, if we want to write to a process's stdin that is attached to a terminal, we actually need to send the information to the terminal. However, because a terminal serves as a form of input as well as output, when writing to it the terminal has no way of knowing that you want to write to a process running within it rather than the "screen".



                  Linux however has a non-posix way of simulating user input through an ioctl request called TIOCSTI (Terminal I/O Control - Simulate Terminal Input) which allows us to send characters to a terminal as if they were typed by a user.



                  I'm only superficially aware of how this works, but based on this answer, it should be possible to do this with something along the lines of



                  import fcntl, sys, termios

                  tty_path = sys.argv[1]

                  with open(tty_path, 'wb') as tty_fd:
                  for line in sys.stdin.buffer:
                  for byte in line:
                  fcntl.ioctl(tty_fd, termios.TIOCSTI, bytes([byte]))


                  Some external resources:



                  http://man7.org/linux/man-pages/man2/ioctl.2.html



                  http://man7.org/linux/man-pages/man2/ioctl_tty.2.html






                  share|improve this answer








                  New contributor



                  Christian Reall-Fluharty is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  Building off of what Gilles said, if we want to write to a process's stdin that is attached to a terminal, we actually need to send the information to the terminal. However, because a terminal serves as a form of input as well as output, when writing to it the terminal has no way of knowing that you want to write to a process running within it rather than the "screen".



                  Linux however has a non-posix way of simulating user input through an ioctl request called TIOCSTI (Terminal I/O Control - Simulate Terminal Input) which allows us to send characters to a terminal as if they were typed by a user.



                  I'm only superficially aware of how this works, but based on this answer, it should be possible to do this with something along the lines of



                  import fcntl, sys, termios

                  tty_path = sys.argv[1]

                  with open(tty_path, 'wb') as tty_fd:
                  for line in sys.stdin.buffer:
                  for byte in line:
                  fcntl.ioctl(tty_fd, termios.TIOCSTI, bytes([byte]))


                  Some external resources:



                  http://man7.org/linux/man-pages/man2/ioctl.2.html



                  http://man7.org/linux/man-pages/man2/ioctl_tty.2.html







                  share|improve this answer








                  New contributor



                  Christian Reall-Fluharty is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.








                  share|improve this answer



                  share|improve this answer






                  New contributor



                  Christian Reall-Fluharty is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.








                  answered 1 hour ago









                  Christian Reall-FluhartyChristian Reall-Fluharty

                  1




                  1




                  New contributor



                  Christian Reall-Fluharty is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.




                  New contributor




                  Christian Reall-Fluharty is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.




































                      draft saved

                      draft discarded



















































                      Thanks for contributing an answer to Unix & Linux Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f385771%2fwriting-to-stdin-of-a-process%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Taj Mahal Inhaltsverzeichnis Aufbau | Geschichte | 350-Jahr-Feier | Heutige Bedeutung | Siehe auch |...

                      Baia Sprie Cuprins Etimologie | Istorie | Demografie | Politică și administrație | Arii naturale...

                      Nicolae Petrescu-Găină Cuprins Biografie | Opera | In memoriam | Varia | Controverse, incertitudini...