How to pass subprocess control to regular stdin after using a pipe?












0















What I'd like to do is to, in Python, programmatically send a few initial commands via stdin to a process, and then pass input to the user to let them control the program afterward. The Python program should simply wait until the subprocess exits due to user input. In essence, what I want to do is something along the lines of:



import subprocess

p = subprocess.Popen(['cat'], stdin=subprocess.PIPE)

# Send initial commands.
p.stdin.write(b"threeninitialncommandsn")
p.stdin.flush()

# Give over control to the user.
# …Although stdin can't simply be reassigned
# in post like this, it seems.
p.stdin = sys.stdin

# Wait for the subprocess to finish.
p.wait()


How can I pass stdin back to the user (not using raw_input, since I need the user's input to come into effect every keypress and not just after pressing enter)?










share|improve this question



























    0















    What I'd like to do is to, in Python, programmatically send a few initial commands via stdin to a process, and then pass input to the user to let them control the program afterward. The Python program should simply wait until the subprocess exits due to user input. In essence, what I want to do is something along the lines of:



    import subprocess

    p = subprocess.Popen(['cat'], stdin=subprocess.PIPE)

    # Send initial commands.
    p.stdin.write(b"threeninitialncommandsn")
    p.stdin.flush()

    # Give over control to the user.
    # …Although stdin can't simply be reassigned
    # in post like this, it seems.
    p.stdin = sys.stdin

    # Wait for the subprocess to finish.
    p.wait()


    How can I pass stdin back to the user (not using raw_input, since I need the user's input to come into effect every keypress and not just after pressing enter)?










    share|improve this question

























      0












      0








      0








      What I'd like to do is to, in Python, programmatically send a few initial commands via stdin to a process, and then pass input to the user to let them control the program afterward. The Python program should simply wait until the subprocess exits due to user input. In essence, what I want to do is something along the lines of:



      import subprocess

      p = subprocess.Popen(['cat'], stdin=subprocess.PIPE)

      # Send initial commands.
      p.stdin.write(b"threeninitialncommandsn")
      p.stdin.flush()

      # Give over control to the user.
      # …Although stdin can't simply be reassigned
      # in post like this, it seems.
      p.stdin = sys.stdin

      # Wait for the subprocess to finish.
      p.wait()


      How can I pass stdin back to the user (not using raw_input, since I need the user's input to come into effect every keypress and not just after pressing enter)?










      share|improve this question














      What I'd like to do is to, in Python, programmatically send a few initial commands via stdin to a process, and then pass input to the user to let them control the program afterward. The Python program should simply wait until the subprocess exits due to user input. In essence, what I want to do is something along the lines of:



      import subprocess

      p = subprocess.Popen(['cat'], stdin=subprocess.PIPE)

      # Send initial commands.
      p.stdin.write(b"threeninitialncommandsn")
      p.stdin.flush()

      # Give over control to the user.
      # …Although stdin can't simply be reassigned
      # in post like this, it seems.
      p.stdin = sys.stdin

      # Wait for the subprocess to finish.
      p.wait()


      How can I pass stdin back to the user (not using raw_input, since I need the user's input to come into effect every keypress and not just after pressing enter)?







      python subprocess pipe stdin






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 14 '18 at 1:49









      obskyrobskyr

      658520




      658520
























          1 Answer
          1






          active

          oldest

          votes


















          1














          Unfortunately, there is no standard way to splice your own stdin to some other process's stdin for the duration of that process, other than to read from your own stdin and write to that process, once you have chosen to write to that process in the first place.



          That is, you can do this:



          proc = subprocess.Popen(...)  # no stdin=


          and the process will inherit your stdin; or you can do this:



          proc = subprocess.Popen(..., stdin=subprocess.PIPE, ...)


          and then you supply the stdin to that process. But once you have chosen to supply any of its stdin, you supply all of its stdin, even if that means you have to read your own stdin.



          Linux offers a splice system call (documentation at man7.org, documentation at linux.die.net, Wikipedia, linux pipe data from file descriptor into a fifo) but your best bet is probably a background thread to copy the data.






          share|improve this answer
























          • So Python doesn't have any built-in way to forward input from stdin to a subprocess pipe? If not, do you happen to know of a way in Python to get input from the user that's low-level enough to send on every keypress and not just every newline?

            – obskyr
            Nov 14 '18 at 2:44











          • "keypress" is a difficult notion in general: you might be run from something that's not connected to a keyboard at all. If you do have a keyboard, there are various ways to read from it, depending on OS and other items. How portable do you wish to be?

            – torek
            Nov 14 '18 at 2:48











          • Not very portable at all – this particular thing's just going to run on a Raspberry Pi. There's a program (omxplayer) that does keyboard shortcuts via stdin (e.g. space for play/pause), and I'd like to run a few keyboard commands on startup and then let the user control the video until it ends. Could I perhaps just use sys.stdin.read over and over and send that into the pipe…?

            – obskyr
            Nov 14 '18 at 2:52











          • (As a side note, omxplayer supports DBUS commands too, which I might look into – but I'd rather not if I don't have to.)

            – obskyr
            Nov 14 '18 at 2:53











          • In that case (the thing runs Linux) you might want to borrow the input reading routines from the curses package: this will put the tty into character-at-a-time mode for you. But it might be much easier if whatever program you're running can do its own keyboard-mode-thing and take command-line setup, so that you don't have to relay characters like that.

            – torek
            Nov 14 '18 at 2:58











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          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: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          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/3.0/"u003ecc by-sa 3.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%2fstackoverflow.com%2fquestions%2f53292056%2fhow-to-pass-subprocess-control-to-regular-stdin-after-using-a-pipe%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          Unfortunately, there is no standard way to splice your own stdin to some other process's stdin for the duration of that process, other than to read from your own stdin and write to that process, once you have chosen to write to that process in the first place.



          That is, you can do this:



          proc = subprocess.Popen(...)  # no stdin=


          and the process will inherit your stdin; or you can do this:



          proc = subprocess.Popen(..., stdin=subprocess.PIPE, ...)


          and then you supply the stdin to that process. But once you have chosen to supply any of its stdin, you supply all of its stdin, even if that means you have to read your own stdin.



          Linux offers a splice system call (documentation at man7.org, documentation at linux.die.net, Wikipedia, linux pipe data from file descriptor into a fifo) but your best bet is probably a background thread to copy the data.






          share|improve this answer
























          • So Python doesn't have any built-in way to forward input from stdin to a subprocess pipe? If not, do you happen to know of a way in Python to get input from the user that's low-level enough to send on every keypress and not just every newline?

            – obskyr
            Nov 14 '18 at 2:44











          • "keypress" is a difficult notion in general: you might be run from something that's not connected to a keyboard at all. If you do have a keyboard, there are various ways to read from it, depending on OS and other items. How portable do you wish to be?

            – torek
            Nov 14 '18 at 2:48











          • Not very portable at all – this particular thing's just going to run on a Raspberry Pi. There's a program (omxplayer) that does keyboard shortcuts via stdin (e.g. space for play/pause), and I'd like to run a few keyboard commands on startup and then let the user control the video until it ends. Could I perhaps just use sys.stdin.read over and over and send that into the pipe…?

            – obskyr
            Nov 14 '18 at 2:52











          • (As a side note, omxplayer supports DBUS commands too, which I might look into – but I'd rather not if I don't have to.)

            – obskyr
            Nov 14 '18 at 2:53











          • In that case (the thing runs Linux) you might want to borrow the input reading routines from the curses package: this will put the tty into character-at-a-time mode for you. But it might be much easier if whatever program you're running can do its own keyboard-mode-thing and take command-line setup, so that you don't have to relay characters like that.

            – torek
            Nov 14 '18 at 2:58
















          1














          Unfortunately, there is no standard way to splice your own stdin to some other process's stdin for the duration of that process, other than to read from your own stdin and write to that process, once you have chosen to write to that process in the first place.



          That is, you can do this:



          proc = subprocess.Popen(...)  # no stdin=


          and the process will inherit your stdin; or you can do this:



          proc = subprocess.Popen(..., stdin=subprocess.PIPE, ...)


          and then you supply the stdin to that process. But once you have chosen to supply any of its stdin, you supply all of its stdin, even if that means you have to read your own stdin.



          Linux offers a splice system call (documentation at man7.org, documentation at linux.die.net, Wikipedia, linux pipe data from file descriptor into a fifo) but your best bet is probably a background thread to copy the data.






          share|improve this answer
























          • So Python doesn't have any built-in way to forward input from stdin to a subprocess pipe? If not, do you happen to know of a way in Python to get input from the user that's low-level enough to send on every keypress and not just every newline?

            – obskyr
            Nov 14 '18 at 2:44











          • "keypress" is a difficult notion in general: you might be run from something that's not connected to a keyboard at all. If you do have a keyboard, there are various ways to read from it, depending on OS and other items. How portable do you wish to be?

            – torek
            Nov 14 '18 at 2:48











          • Not very portable at all – this particular thing's just going to run on a Raspberry Pi. There's a program (omxplayer) that does keyboard shortcuts via stdin (e.g. space for play/pause), and I'd like to run a few keyboard commands on startup and then let the user control the video until it ends. Could I perhaps just use sys.stdin.read over and over and send that into the pipe…?

            – obskyr
            Nov 14 '18 at 2:52











          • (As a side note, omxplayer supports DBUS commands too, which I might look into – but I'd rather not if I don't have to.)

            – obskyr
            Nov 14 '18 at 2:53











          • In that case (the thing runs Linux) you might want to borrow the input reading routines from the curses package: this will put the tty into character-at-a-time mode for you. But it might be much easier if whatever program you're running can do its own keyboard-mode-thing and take command-line setup, so that you don't have to relay characters like that.

            – torek
            Nov 14 '18 at 2:58














          1












          1








          1







          Unfortunately, there is no standard way to splice your own stdin to some other process's stdin for the duration of that process, other than to read from your own stdin and write to that process, once you have chosen to write to that process in the first place.



          That is, you can do this:



          proc = subprocess.Popen(...)  # no stdin=


          and the process will inherit your stdin; or you can do this:



          proc = subprocess.Popen(..., stdin=subprocess.PIPE, ...)


          and then you supply the stdin to that process. But once you have chosen to supply any of its stdin, you supply all of its stdin, even if that means you have to read your own stdin.



          Linux offers a splice system call (documentation at man7.org, documentation at linux.die.net, Wikipedia, linux pipe data from file descriptor into a fifo) but your best bet is probably a background thread to copy the data.






          share|improve this answer













          Unfortunately, there is no standard way to splice your own stdin to some other process's stdin for the duration of that process, other than to read from your own stdin and write to that process, once you have chosen to write to that process in the first place.



          That is, you can do this:



          proc = subprocess.Popen(...)  # no stdin=


          and the process will inherit your stdin; or you can do this:



          proc = subprocess.Popen(..., stdin=subprocess.PIPE, ...)


          and then you supply the stdin to that process. But once you have chosen to supply any of its stdin, you supply all of its stdin, even if that means you have to read your own stdin.



          Linux offers a splice system call (documentation at man7.org, documentation at linux.die.net, Wikipedia, linux pipe data from file descriptor into a fifo) but your best bet is probably a background thread to copy the data.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 14 '18 at 2:24









          torektorek

          187k18236318




          187k18236318













          • So Python doesn't have any built-in way to forward input from stdin to a subprocess pipe? If not, do you happen to know of a way in Python to get input from the user that's low-level enough to send on every keypress and not just every newline?

            – obskyr
            Nov 14 '18 at 2:44











          • "keypress" is a difficult notion in general: you might be run from something that's not connected to a keyboard at all. If you do have a keyboard, there are various ways to read from it, depending on OS and other items. How portable do you wish to be?

            – torek
            Nov 14 '18 at 2:48











          • Not very portable at all – this particular thing's just going to run on a Raspberry Pi. There's a program (omxplayer) that does keyboard shortcuts via stdin (e.g. space for play/pause), and I'd like to run a few keyboard commands on startup and then let the user control the video until it ends. Could I perhaps just use sys.stdin.read over and over and send that into the pipe…?

            – obskyr
            Nov 14 '18 at 2:52











          • (As a side note, omxplayer supports DBUS commands too, which I might look into – but I'd rather not if I don't have to.)

            – obskyr
            Nov 14 '18 at 2:53











          • In that case (the thing runs Linux) you might want to borrow the input reading routines from the curses package: this will put the tty into character-at-a-time mode for you. But it might be much easier if whatever program you're running can do its own keyboard-mode-thing and take command-line setup, so that you don't have to relay characters like that.

            – torek
            Nov 14 '18 at 2:58



















          • So Python doesn't have any built-in way to forward input from stdin to a subprocess pipe? If not, do you happen to know of a way in Python to get input from the user that's low-level enough to send on every keypress and not just every newline?

            – obskyr
            Nov 14 '18 at 2:44











          • "keypress" is a difficult notion in general: you might be run from something that's not connected to a keyboard at all. If you do have a keyboard, there are various ways to read from it, depending on OS and other items. How portable do you wish to be?

            – torek
            Nov 14 '18 at 2:48











          • Not very portable at all – this particular thing's just going to run on a Raspberry Pi. There's a program (omxplayer) that does keyboard shortcuts via stdin (e.g. space for play/pause), and I'd like to run a few keyboard commands on startup and then let the user control the video until it ends. Could I perhaps just use sys.stdin.read over and over and send that into the pipe…?

            – obskyr
            Nov 14 '18 at 2:52











          • (As a side note, omxplayer supports DBUS commands too, which I might look into – but I'd rather not if I don't have to.)

            – obskyr
            Nov 14 '18 at 2:53











          • In that case (the thing runs Linux) you might want to borrow the input reading routines from the curses package: this will put the tty into character-at-a-time mode for you. But it might be much easier if whatever program you're running can do its own keyboard-mode-thing and take command-line setup, so that you don't have to relay characters like that.

            – torek
            Nov 14 '18 at 2:58

















          So Python doesn't have any built-in way to forward input from stdin to a subprocess pipe? If not, do you happen to know of a way in Python to get input from the user that's low-level enough to send on every keypress and not just every newline?

          – obskyr
          Nov 14 '18 at 2:44





          So Python doesn't have any built-in way to forward input from stdin to a subprocess pipe? If not, do you happen to know of a way in Python to get input from the user that's low-level enough to send on every keypress and not just every newline?

          – obskyr
          Nov 14 '18 at 2:44













          "keypress" is a difficult notion in general: you might be run from something that's not connected to a keyboard at all. If you do have a keyboard, there are various ways to read from it, depending on OS and other items. How portable do you wish to be?

          – torek
          Nov 14 '18 at 2:48





          "keypress" is a difficult notion in general: you might be run from something that's not connected to a keyboard at all. If you do have a keyboard, there are various ways to read from it, depending on OS and other items. How portable do you wish to be?

          – torek
          Nov 14 '18 at 2:48













          Not very portable at all – this particular thing's just going to run on a Raspberry Pi. There's a program (omxplayer) that does keyboard shortcuts via stdin (e.g. space for play/pause), and I'd like to run a few keyboard commands on startup and then let the user control the video until it ends. Could I perhaps just use sys.stdin.read over and over and send that into the pipe…?

          – obskyr
          Nov 14 '18 at 2:52





          Not very portable at all – this particular thing's just going to run on a Raspberry Pi. There's a program (omxplayer) that does keyboard shortcuts via stdin (e.g. space for play/pause), and I'd like to run a few keyboard commands on startup and then let the user control the video until it ends. Could I perhaps just use sys.stdin.read over and over and send that into the pipe…?

          – obskyr
          Nov 14 '18 at 2:52













          (As a side note, omxplayer supports DBUS commands too, which I might look into – but I'd rather not if I don't have to.)

          – obskyr
          Nov 14 '18 at 2:53





          (As a side note, omxplayer supports DBUS commands too, which I might look into – but I'd rather not if I don't have to.)

          – obskyr
          Nov 14 '18 at 2:53













          In that case (the thing runs Linux) you might want to borrow the input reading routines from the curses package: this will put the tty into character-at-a-time mode for you. But it might be much easier if whatever program you're running can do its own keyboard-mode-thing and take command-line setup, so that you don't have to relay characters like that.

          – torek
          Nov 14 '18 at 2:58





          In that case (the thing runs Linux) you might want to borrow the input reading routines from the curses package: this will put the tty into character-at-a-time mode for you. But it might be much easier if whatever program you're running can do its own keyboard-mode-thing and take command-line setup, so that you don't have to relay characters like that.

          – torek
          Nov 14 '18 at 2:58


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • 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%2fstackoverflow.com%2fquestions%2f53292056%2fhow-to-pass-subprocess-control-to-regular-stdin-after-using-a-pipe%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

          Xamarin.iOS Cant Deploy on Iphone

          Glorious Revolution

          Dulmage-Mendelsohn matrix decomposition in Python