Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
October 09, 2013 std.process spawnShell/pipeShell dont capture output of the shell | ||||
---|---|---|---|---|
| ||||
Hi folks, Is there anyway to make std.process.spawnShell or std.process.pipeShell capture the output of the shell interface? For example, the code: import std.stdio; import std.process; void main(string[] args){ writefln("Executing: %s", args[1]); auto processPipes = pipeShell(args[1], Redirect.all); foreach(str; processPipes.stdout.byLine){ writefln("STDOUT: %s",str); } foreach(str; processPipes.stderr.byLine){ writefln("STDERR: %s",str); } } is compiled to an executable called "mess". When executed with the following produces: " ~/test$ ./mess ls Executing: ls STDOUT: mess STDOUT: text.txt " Thats all fine, however, I'd expect it to print another "~/test$" at the end, as if its an interactive shell waiting for input. Is that an incorrect assumption to make or am I doing something wrong that is stopping that from happening? Also, If I run /bin/bash through program, it hangs. " ~/test$ ./mess /bin/bash Executing: /bin/bash " Thanks, Colin |
October 09, 2013 Re: std.process spawnShell/pipeShell dont capture output of the shell | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin Grogan | On Wednesday, 9 October 2013 at 11:22:26 UTC, Colin Grogan wrote:
> "
> ~/test$ ./mess ls
> Executing: ls
> STDOUT: mess
> STDOUT: text.txt
>
> "
> Thats all fine, however, I'd expect it to print another "~/test$" at the end, as if its an interactive shell waiting for input.
It is extracting the output of the program, 99.9% of the time this is what everyone wants and including the shells behavior would be terrible.
If you run bash, then it is going to be waiting for stdin so you'd need to pass it "ls" and "exit" to get the output and quit. I'm not sure this would get you want you wanted.
|
October 09, 2013 Re: std.process spawnShell/pipeShell dont capture output of the shell | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On Wednesday, 9 October 2013 at 14:27:30 UTC, Jesse Phillips wrote: > On Wednesday, 9 October 2013 at 11:22:26 UTC, Colin Grogan wrote: >> " >> ~/test$ ./mess ls >> Executing: ls >> STDOUT: mess >> STDOUT: text.txt >> >> " >> Thats all fine, however, I'd expect it to print another "~/test$" at the end, as if its an interactive shell waiting for input. > > It is extracting the output of the program, 99.9% of the time this is what everyone wants and including the shells behavior would be terrible. But its exactly what I want ;) > If you run bash, then it is going to be waiting for stdin so you'd need to pass it "ls" and "exit" to get the output and quit. I'm not sure this would get you want you wanted. That would imply that the call to pipeShell("/bin/bash", Redirect.all); is blocking. However, its not meant to be blocking is it not? That new /bin/bash process is meant to run in parallel to the main process? If I use the program to execute the following script: #!/bin/bash for i in {1..100} do for j in {1..100} do echo "$i, $j" done sleep 15 done and monitor the output that is printed, I can see that it is indeed sleeping for 15 seconds, so the pipeShell call is definitely non-blocking. I assumed it should behave the same way for /bin/bash. It is just another process after all, surely pipeShell knows nothing more about /bin/bash that it does about my silly script above? |
October 10, 2013 Re: std.process spawnShell/pipeShell dont capture output of the shell | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin Grogan | On Wednesday, 9 October 2013 at 14:54:32 UTC, Colin Grogan wrote:
> is blocking. However, its not meant to be blocking is it not? That new /bin/bash process is meant to run in parallel to the main process?
I'm not sure exactly the implementation. But if you're asking to run bash and then print its output, wouldn't it have to block because the output won't be complete until the program has finished running? And since bash will run until you exit the program will block for ever.
|
October 11, 2013 Re: std.process spawnShell/pipeShell dont capture output of the shell | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On Thursday, 10 October 2013 at 01:24:03 UTC, Jesse Phillips wrote:
> On Wednesday, 9 October 2013 at 14:54:32 UTC, Colin Grogan wrote:
>> is blocking. However, its not meant to be blocking is it not? That new /bin/bash process is meant to run in parallel to the main process?
>
> I'm not sure exactly the implementation. But if you're asking to run bash and then print its output, wouldn't it have to block because the output won't be complete until the program has finished running? And since bash will run until you exit the program will block for ever.
From what I understood in the documentation, I didnt think it should block. I understood it's meant to run the child process in the background and you communicate with it via the stdin/stdout/stderr pipes. But, from experimentation I can see that running /bin/bash does appear to block.
Ill have to do some more digging when I have the time...
|
September 11, 2016 Re: std.process spawnShell/pipeShell dont capture output of the shell | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin Grogan | I'm sorry for the "necro-bumping", but I've not found the solution for this yet, and i'm getting a different error message at the execution moment: "std.stdio.StdioException@/build/ldc/src/ldc/runtime/phobos/std/stdio.d(4066): Bad file descriptor" This is my testing code: module dd_test; import std.stdio, core.stdc.stdlib; import std.process, std.string; int main(string[] args) { string command_find = "(find /usr/share/icons/ -name a*) "; //string command_dd = "(dd if=/dev/urandom | pv -ptrbef -i 2 -s 2339876653 | dd of=/dev/null) 2>&1"; auto p = pipeShell(command_find, Redirect.all); foreach(str; p.stdin.byLine){ writefln("IN: %s", str); } foreach(str; p.stdout.byLine){ writefln("OUT: %s", str); } foreach(str; p.stderr.byLine){ writefln("Error: %s", str); } return 0; } |
Copyright © 1999-2021 by the D Language Foundation