Ksh: how to explore stdin?

I want my ksh script to have a different behavior depending on whether there is something via stdin or not:

(1) cat file.txt | ./script.ksh (then do "cat <&0 >./tmp.dat" and process tmp.dat) vs. (2) ./script.ksh (then process $1 which must be a readable regular file) 

Checking for stdin to determine if it is a terminal [-t 0] does not help, because my script is being called from another script.

Running "cat <& 0> ./tmp.dat" to check the size of tmp.dat hangs, waiting for EOF from stdin if stdin is "empty" (2nd case).

How easy is it to check if stdin is "empty" or not ?!

+4
source share
3 answers

EDIT: you work on HP-UX

Tested [ -t 0 ] on HP-UX and seems to work for me. I used the following setting:

/tmp/x.ksh:

 #!/bin/ksh /tmp/y.ksh 

/tmp/y.ksh:

 #!/bin/ksh test -t 0 && echo "terminal!" 

Performing /tmp/x.ksh fingerprints: terminal!

Could you confirm this on your platform and / or provide an alternative test setup that more accurately reflects your situation? Is your script ultimately spawned by cron ?


EDIT 2

If desperate, and if Perl is available, define:

 stdin_ready() { TIMEOUT=$1; shift perl -e ' my $rin = ""; vec($rin,fileno(STDIN),1) = 1; select($rout=$rin, undef, undef, '$TIMEOUT') < 1 && exit 1; ' } stdin_ready 1 || 'stdin not ready in 1 second, assuming terminal' 

EDIT 3

Please note that latency can be significant if your input comes from sort , ssh , etc. (All these programs can appear and set the channel using the script seconds or minutes before any data is created.) In addition, using a powerful timeout can sharply fine your script when nothing happens at the initial stage (for example, a terminal).

If potentially long timeouts are a problem, and if you can influence the way the script is called, then you can force the callers to explicitly tell your program whether to use stdin using a custom option or the standard GNU or tar method (for example, script [options [-] ] FILE ..., where FILE can be a file name, a - to indicate standard input or a combination of them, and your script will only read from standard input, if - was passed as a parameter.)

+3
source

This strategy works for bash and most likely will work for ksh. Poll 'tty':

 #!/bin/bash set -a if [ "$( tty )" == 'not a tty' ] then STDIN_DATA_PRESENT=1 else STDIN_DATA_PRESENT=0 fi if [ ${STDIN_DATA_PRESENT} -eq 1 ] then echo "Input was found." else echo "Input was not found." fi 
+2
source

Why not solve it in a more traditional way and use the command line argument to indicate that the data will come from stdin?

As an example, consider the difference between:

echo foo | cat -

and

echo foo > /tmp/test.txt

cat /tmp/test.txt

0
source

All Articles