How to pass subprocess control to regular stdin after using a pipe?
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
add a comment |
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
add a comment |
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
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
python subprocess pipe stdin
asked Nov 14 '18 at 1:49
obskyrobskyr
658520
658520
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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.
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 usesys.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 thecurses
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
|
show 1 more comment
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 usesys.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 thecurses
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
|
show 1 more comment
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.
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 usesys.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 thecurses
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
|
show 1 more comment
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.
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.
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 usesys.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 thecurses
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
|
show 1 more comment
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 usesys.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 thecurses
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
|
show 1 more comment
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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