2

For example, the following works fine:

/usr/bin/program

It produces some output, and gets to result.

But if I invoke it like this:

echo -n | /usr/bin/program

or this

echo -n | bash -c "/usr/bin/program"

or even this:

echo -n | bash -c "wc -c; /usr/bin/program"

It produces some lines of output, then fails. I have no access to source of the program, so I can't even look what could cause this behavior.

And when I try to invoke it from the python script, I get the same stuff:

echo | python -c 'from subprocess import call; call("/usr/bin/program", shell=True)'

(version without "echo" prepended works fine)

I don't even have the faintest idea why that could be happening. Stdin is going to be open even if I don't explicitly specify where the program should read from, so that shouldn't be the cause.

Is there any way to work around this issue?

EDIT:

The last four lines from strace output - the only ones that differ:

# without echo
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
...

# with echo
select(1, [0], NULL, NULL, {0, 0})      = 1 (in [0], left {0, 0})
write(4, "\0\0\0j\0\0\0\3\0\0\0\4\0\0\0\0\377\377\377\377", 20) = 20
write(3, "\0\0\0j\0\0\0\3\0\0\0\4\0\0\0\0\377\377\377\377", 20) = 20
exit_group(1)                           = ?

PARTIAL SOLUTION:

sleep 20 | /usr/bin/program

Seems that program waits for something to happen at stdin, and exits if it encounters a newline or EOF (we can see it from select call in strace output - it timeouts if input comes from "real" user). So we needed a program that doesn't write anything to stdin, while still keeping it open - sleep does the job.

15
  • A process always has a standard input by default. The program might be getting confused by seeing an unexpected EOF on its input. What are you trying to do, anyway; why pipe nothing into a process? For what kind of software would this be useful?
    – user
    Jul 11, 2013 at 17:33
  • Have you tried running strace on your program to see how it's messing with its stdin? That may give you clues on what's going on.
    – lgeorget
    Jul 11, 2013 at 17:33
  • @MichaelKjörling - for example, that python script is doing something different, and it gets input from stdin. And I try to execute this external process from script.
    – Rogach
    Jul 11, 2013 at 17:35
  • @lgeorget - I'm trying right now. I'm not familiar with strace, yet, so the only useful thing I currently see is "exit_group(1)" at the end of the output.
    – Rogach
    Jul 11, 2013 at 17:37
  • @lgeorget - I'm not even sure it's the stdin thing. If I type something at keyboard while it executes, it works fine, and echo -n shouldn't provide any input anyway.
    – Rogach
    Jul 11, 2013 at 17:40

1 Answer 1

2

Here's a Perl one-liner that will do what you want:

perl -e '$SIG{CHLD} = sub{exit 0}; open $fh, "|-", @ARGV or die; sleep 20 while 1;' /usr/bin/program

It's essentially the same as a mythical* sleep forever | /usr/bin/program, except it also watches for the program to finish, and will quit immediately when it does. If /usr/bin/program needs any args, you can tack them onto the end of the line.

*sleep forever doesn't work, but GNU sleep will sleep forever if you sleep inf!

1
  • Awesome! I was thinking about writing something like that in C, but this is so much better :)
    – Rogach
    Jul 12, 2013 at 3:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .