Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if stdin is from the terminal or a pipe in a shell script?

Tags:

posix

sh

I am writing a POSIX shell script that may or may not receive input from stdin as in foo.sh < test.txt, non-interactively.

How do I check whether there is anything on stdin, to avoid halting on while read -r line...?

like image 416
l0b0 Avatar asked Mar 16 '10 17:03

l0b0


People also ask

Is Stdin a pipe?

+1: stdin can be a pipe or redirected from a file.

What is Stdin in shell script?

In Linux, stdin is the standard input stream. This accepts text as its input. Text output from the command to the shell is delivered via the stdout (standard out) stream. Error messages from the command are sent through the stderr (standard error) stream.

What does $_ mean in terminal?

Use Case # 1: Using “$_” in Ubuntu 20.04 Terminal: This special variable can be used in the Ubuntu 20.04 terminal. The purpose of using it within the terminal is to print the last argument of the previous command executed within the terminal.


2 Answers

To answer the question literally (but not what you actually want): read -t 0

Timeout, zero seconds.

  1. this is a race-condition, depending on when the left-hand-side is ready to provide data. You can specify -t 5 but on a thrashing system even that is problematic.
  2. read -t is not standardised in SUSv3. It is in BSD sh, bash, zsh. It's not in ksh or dash.

So you can't just use #!/bin/sh and expect to have this.

The basic problem is that even if there's nothing on stdin now, that doesn't mean there won't be soon. Invoking a program normally leaves stdin connected to the terminal/whatever, so there's no way to tell what's needed.

So, to answer your question literally, you can do it, but in practice your options are:

  1. test if stdin is a tty: [ -t 0 ]
  2. use argv to control behaviour
like image 33
Phil P Avatar answered Sep 28 '22 20:09

Phil P


If I get the question right, you may try the following:

#!/bin/sh if [ -t 0 ]; then     echo running interactivelly else     while read -r line ; do         echo $line     done fi 
like image 65
dmedvinsky Avatar answered Sep 28 '22 19:09

dmedvinsky