I am simply trying to get a bash script
to return the content of a text file.

cat $1

the problem is.. when the path to a file is not fed to this bash script... how will it even close itself.

because via regular command line... if there is no file path being fed to the cat command.. it does not hang up.

almost as if it is waiting for something..

  • 6
    cat is waiting for input from stdin which is how it's designed. If this is a concern for you, then you should be validating your inputs (which you should be doing anyways) by doing a -z test or something. – Bratchley Jun 20 '14 at 17:29
  • Just noticed @Creek posted this answer below. That's what you need to do. The cat command is doing what it needs to do. – Bratchley Jun 20 '14 at 17:30
  • 6
    Tip: always do set -u at the start of each script, at least you'll have an indication that there's a problem in the script arguments instead of calling potentially destructive commands with the wrong parameters. – Matteo Italia Jun 20 '14 at 23:18
  • 1
    Default $1 to /dev/null if it does not exist. – smci Jun 21 '14 at 4:40

Your command also has another problem, what if the filename has spaces?

cat "$1"

Always quote unless you have a compelling reason not to. And cat "" does not hang. Instead it would produce an error message like "No such file or directory".

  • 4
    cat "" doesn't hang, but it does print an error message: cat: : No such file or directory (referring to the empty string). It's better to test whether $1 exists, probably by checking the value of $#. – Keith Thompson Jun 20 '14 at 20:10
  • The main problem I see here is that if one is running a file system which allows an empty file name this could actually work and not error. However, as a quick hack this is fine. – Vality Jun 20 '14 at 21:06
  • @Darkhogg: If there is such a file the test would succeed also. I assume the OP's script is in reality more complicated and this was just an example regarding cat invocation. Other answers went more to the error handling route. Someone even deleted his answer; oh well. something for everyone here. – frostschutz Jun 20 '14 at 21:58
  • Not cat "$@"? – Cascabel Jun 20 '14 at 22:55
  • @vality, empty filename are likely to be illegal on all (POSIX) operating systems: how would you differentiate a filename /path/to/$FILENAME and the parent directory /path/to/ ? – Franklin Piat Sep 19 '16 at 11:10
if [[ "$#" -ne 1 ]]; then
    echo "Usage: $0 [INPUT FILE]" 1>&2
    exit 1
cat "$1"
  • Above and beyond is generally best. – mikeserv Jun 20 '14 at 17:30
  • @mikeserv who? where? – Creek Jun 20 '14 at 17:47
  • 4
    this is the better solution in my opinion, since it exits with error – polym Jun 20 '14 at 17:49
  • 1
    @Creek - you, here. – mikeserv Jun 20 '14 at 18:18
  • 1
    There are lots of votes for this answer but perhaps because this is an english only web site .. people from other parts of the world are not really voting.. it is not balanced. simplicity saves the day with the chosen answer. – user72685 Jun 20 '14 at 18:19

cat will ignore STDIN if you supply it with a filename. Connecting STDIN to /dev/null would be a valid solution in this context.

$ cat test.sh
cat $1 < /dev/null
$ ./test.sh test.sh
cat $1 < /dev/null
$ ./test.sh

The shortcoming of this approach is that it will return 0 if no file name is supplied. No way around that. Failure to open the specified file will still return failure.


I would say that cat is an unsuitable tool here and this is why you are getting this undesired behaviour, cat is designed to concatenate a set of files and write the output to another file, it is a quirk of the implementation that the default input is stdin and the default output is stdout.

I would say a far more suitable command here would be:

cp ${1} /dev/stdout

The dev stdout directory is originally Linux only, however before I am yelled at for using a platform specific construct bash (the shell the op explicitly stated they are using) implements /dev/stdout as a builtin so is therefore usable on any platform with bash or ksh.

cp is a utility more suitable here as it is designed to copy the contents from one file to another and that is exactly what we are doing here, copying $1 to stdout

This command will also usefully fail given no input and works on any system with bash, note it does assume that the user has properly escaped any file names with odd chars like space or \n.

  • 3
    Honestly, this seems to me like an overcomplication; cat was born to concatenate files, but everybody uses it just to show files contents probably since the first version of UNIX, and I see nothing wrong with that - cat "filename" is way shorter, more portable and more idiomatic than cp filename /dev/stdout. – Matteo Italia Jun 20 '14 at 23:16
  • @MatteoItalia I give you that it is shorter, and potentially more idiomatic but it is not significantly more portable, every shell I have seen in over a decade (with the possible exception of csh) had implemented the cp version, I will note that there is a performance impact if your chosen shell makes one a builtin and the other an external command. However if neither are builtin cp will be faster. Regarding the expressiveness I suppose it depends what you are used to. – Vality Jun 21 '14 at 10:20
  • @Vality Why should cp be faster if both aren't builtin? – heinrich5991 Jun 22 '14 at 15:58
  • @heinrich5991 I have benchmarked this for a 512MB text file in a variety of machines, on average with these machines cat takes 1.79 seconds and cp takes 1.42 seconds. It seems from running a performance analyzer that cat is copying in small chunks and running a loop for every char printed, cp just splices the files together at high speed. – Vality Jun 22 '14 at 18:08
  • I came across this and just thought I'd mention that even in bash, on Linux, a script might not have write permission for files/descriptors like /dev/stdout. I've encountered this in Nix build scripts, for example having to use 1>&2 rather than 1> /dev/stderr since there's no write permission for /dev/stderr. – Warbo Aug 14 '17 at 22:18

To display file contents only if the file exists:

[ -f "$1" ] && cat "$1"

This script assumes that the first argument is the file you want to cat


Default $1 to /dev/null if it does not exist.

(You can easily figure out the bash syntax for that)

: | cat $1

This would be the shortest piece of code that would work. It should ignore the absence of a file silently.

Howeverm, is this really what you need? I agree with @Vality that you probably should not use cat in this context.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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