Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In bash, is there a way to know if a given script has been invoked with:

$ myscript.sh myfile


$ myscript.sh < myfile

Inside some scripts I always have accessed the contents of myfile with $1, but now I'd like to change the behavior as different cases.

EDIT: I also would like a third case when invoked without any redirection:

$ myscript.sh
share|improve this question
up vote 12 down vote accepted

EDIT: changed -t to -t 0, which does correctly detect input from terminal or file.

I think the key here is knowing whether your input is coming from a terminal or from a file. There is a test for this (man test, see -t).

Assuming you're running a bash script:

if [ -t 0 ]; then
    echo "Input from terminal"
    if [ $# -eq 0 ]; then
        echo "No input files specified on command line.  Error." >&2
        echo "Input file given on command line.  It is $1"
    echo "Input coming from stdin"

You can handle the different scenarios by substituting actual code in for the echo statements above.

Update, quickie test script:

[ -t 0 ] && echo "t is true" || echo "t is false"


$ test.sh testfile
t is true
$ test.sh < testfile
t is false
share|improve this answer
-t always evaluates to true running the script from the command line with < myfile :( – mschonaker Jun 27 '11 at 7:28
@mschonaker - Using -t 0 gives the correct results. Updated answer. – Mark Mann Jun 27 '11 at 7:39
Thanks! That worked for me! – mschonaker Jun 27 '11 at 7:48
@MarkMann What does the 0 do? What is the difference? It's not in the documentation. – Ivan V. Feb 5 at 21:47
@IvanV. - The zero is the file descriptor to test. Standard input is associated with 0, standard output with 1 and standard error with 2. If I wanted to check if my output was going to a terminal I would use [ -t 1 ] – Mark Mann Feb 5 at 22:16

In general, the expressions $1, $2, etc. expand to the 1st, 2nd, etc. argument given on the script command line.

So, when you invoke a script as:

myscript.sh myfile

then $1 within the script expands to myfile (and $2, $3, etc. all are the empty string).

When you invoke a script as:

myscript < myfile

the redirection of STDIN from myfile is done by the parent shell, so the script is actually called with no arguments and $1 expands to the empty string.

share|improve this answer
How do I detect if called with no arguments in the command line (the third case)? Sorry if you answered before my edit. Thanks. – mschonaker Jun 27 '11 at 7:18

Your Answer


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.