Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
    
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? –  Michael Kjörling Jul 11 '13 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 '13 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 '13 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 '13 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 '13 at 17:40
show 11 more comments

1 Answer

up vote 2 down vote accepted

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!

share|improve this answer
    
Awesome! I was thinking about writing something like that in C, but this is so much better :) –  Rogach Jul 12 '13 at 3:18
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.