Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you only need to know if it's a pipe <em>or</em> a redirection, it should be sufficient to determine if stdin is a <em>terminal</em> or not:</p> <pre><code>if [ -t 0 ]; then # stdin is a tty: process command line else # stdin is not a tty: process standard input fi </code></pre> <p><code>[</code> (aka <code>test</code>) with <code>-t</code> is equivalent to the libc <code>isatty()</code> function. The above will work with both <code>something | myscript</code> and <code>myscript &lt; infile</code>. This is the simplest solution, assuming your script is for interactive use.</p> <p>The <code>[</code> command is a builtin in bash and some other shells, and since <code>[</code>/<code>test</code> with <code>-t</code><a href="http://pubs.opengroup.org/onlinepubs/009696699/utilities/test.html" rel="nofollow">is in POSIX</a>, it's portable too (not relying on Linux, bash, or GNU utility features).</p> <p>There's one edge case, <code>test -t</code> also returns false if the file descriptor is invalid, but it would take some slight adversity to arrange that. <code>test -e</code> will detect this, though assuming you have a filename such as <code>/dev/stdin</code> to use.</p> <p>The POSIX <a href="http://pubs.opengroup.org/onlinepubs/009696699/utilities/tty.html" rel="nofollow"><code>tty</code></a> command can also be used, and handles the adversity above. It will print the tty device name and return 0 if stdin is a terminal, and will print "not a tty" and return 1 in any other case:</p> <pre><code>if tty &gt;/dev/null ; then # stdin is a tty: process command line else # stdin is not a tty: process standard input fi </code></pre> <p>(with GNU <code>tty</code>, you can use <code>tty -s</code> for silent operation)</p> <p>A less portable way, though certainly acceptable on a typical Linux, is to use GNU <code>stat</code> with its <code>%F</code> format specifier, this returns the text "character special file", "fifo" and "regular file" in the cases of terminal, pipe and redirection respectively. <code>stat</code> requires a filename, so you must provide a specially-named file of the form <code>/dev/stdin</code>, <code>/dev/fd/0</code>, or <code>/proc/self/fd/0</code>, and use <code>-L</code> to chase symlinks:</p> <pre><code>stat -L -c "%F" /dev/stdin </code></pre> <p>This is probably the best way to handle non-interactive use (since you can't make assumptions about terminals then), or to detect an actual pipe (FIFO) distinct from redirection.</p> <p>There is a slight gotcha with <code>%F</code> in that you cannot use it to tell the difference between a <em>terminal</em> and certain other device files, for example <code>/dev/zero</code> or <code>/dev/null</code> which are also "character special files" and might reasonably appear. An unpretty solution is to use <code>%t</code> to report the underlying device type (major, in hex), assuming you know what the underlying tty device number ranges are... and that depends on whether you're using BSD style ptys or Unix98 ptys, or whether you're on the actual console, among other things. In the simple case <code>%t</code> will be 0 though for a pipe or a redirection of a normal (non-special) file.</p> <p>More general solutions to this kind of problem are to use bash's <code>read</code> with a timeout (<code>read -t 0 ...</code>) or non-blocking I/O with GNU <code>dd</code> (<code>dd iflag=nonblock</code>).</p> <p>The latter will allow you to detect lack of input on stdin, <code>dd</code> will return an exit code of 1 if there is nothing ready to read. However, these are more suitable for non-blocking polling loops, rather than a once-off check: there is a race condition when you start two or more processes in a pipeline as one may be ready to read before another has written.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload