3527

I've used the following script to see if a file exists:

#!/bin/bash

FILE=$1     
if [ -f $FILE ]; then
   echo "File $FILE exists."
else
   echo "File $FILE does not exist."
fi

What's the correct syntax to use if I only want to check if the file does not exist?

#!/bin/bash

FILE=$1     
if [ $FILE does not exist ]; then
   echo "File $FILE does not exist."
fi
codeforester
  • 28,846
  • 11
  • 78
  • 104
Bill the Lizard
  • 369,957
  • 201
  • 546
  • 842
  • 11
    Being the very lazy person that I am, I would typically have used the following silly workaround construct: `if [ -f $FILE ]; then; else; echo "File $FILE does not exist."; fi;` Probably good that I found this question instead and learned to do it in a more proper way. :) – Alderath Jan 15 '13 at 13:35
  • 204
    I've found this [list of bash conditional statements](http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html) very useful. – Saulius Žemaitaitis Mar 12 '09 at 14:52
  • 5
    To be pendantic, you should say "regular file", as most UNIX/POSIX docs refer generically to all types of file system entries a simply "files", e.g., a symbolic link is a type of a file, as is a named pipe, regular file, directory, block special, character special, socket, etc. – kevinarpe Nov 09 '13 at 08:51
  • 11
    @kevinarpe if you want to test whether _something_ exists, use `-e`. -f won't pick up directories, symlinks, etc. – Benubird Mar 24 '15 at 09:38
  • 15
    To be safe, always use double quotes to correctly handle file names with whitespace, e.g., `FILE=$1` -> `FILE="$1"` and `if [ -f $FILE ];` -> `if [ -f "$FILE" ];` – kevinarpe Mar 24 '15 at 11:37
  • Unfortunately this is prone for race conditions and not useful in most use cases, except of trivial hello world examples. – hek2mgl Jun 19 '15 at 15:38
  • 1
    As a side note and regarding your "$FILE" variable: By convention, environment variables (PATH, EDITOR, SHELL, ...) and internal shell variables (BASH_VERSION, RANDOM, ...) are fully capitalized. All other variable names should be lowercase. Since variable names are case-sensitive, this convention avoids accidentally overriding environmental and internal variables. – Rany Albeg Wein Jan 16 '16 at 14:09
  • Possible duplicate of [Bash: How do I check if certain files exist?](https://stackoverflow.com/questions/572206/bash-how-do-i-check-if-certain-files-exist) – jww Mar 31 '18 at 22:03
  • 3
    @jww This is the opposite of that question. This is asking for specific syntax. – Bill the Lizard Apr 01 '18 at 01:37

20 Answers20

4868

The test command ([ here) has a "not" logical operator which is the exclamation point (similar to many other languages). Try this:

if [ ! -f /tmp/foo.txt ]; then
    echo "File not found!"
fi
John Feminella
  • 281,997
  • 42
  • 326
  • 347
  • 236
    More succinctly: [ ! -f /tmp/foo.txt ] && echo "File not found!" – DavidWinterbottom Sep 29 '10 at 12:09
  • 40
    I struggled a bit to find the right syntax for "if any of 2 files does not exist". The following both work: `if [ ! \( -f "f1" -a -f "f2" \) ] ; then echo MISSING; fi` `if [ ! -f "f1" ] || [ ! -f "f2" ] ; then echo MISSING; fi` – mivk Feb 02 '12 at 15:41
  • 164
    @DavidWinterbottom Even more succulently: `[ -f /tmp/foo.txt ] || echo "File not found!"` – David W. Jun 26 '13 at 21:08
  • 28
    Parameter can be any one of the following: `-e: Returns true value, if file exists` `-f: Return true value, if file exists and regular file` `-r: Return true value, if file exists and is readable` `-w: Return true value, if file exists and is writable` `-x: Return true value, if file exists and is executable` `-d: Return true value, if exists and is a directory` – SD. Dec 19 '13 at 13:41
  • 2
    If you want to use 2 conditions in an if-operation, use the -a operator, this means AND. I think this is also possible with & if you use the [[ ]] operator – BlueCacti Jan 25 '14 at 20:44
  • 10
    There is an asymmetry in using `! -f` with `&&` versus using `-f` with `||`. This has to do with the exit code returned by the non/existence check. If you need your line to always exit cleanly with exit code 0 (and sometimes you don't want this constraint), the two approaches are not interchangeable. Alternatively, just use an `if` statement and you no longer have to worry about the exit code of your non/existence check. – Acumenus Aug 01 '15 at 02:16
  • if the file name is dynamic, test it with `if [ ! -f "$filename" ]; then...` because it might contain spaces – MariusP Aug 27 '15 at 14:25
  • Used this to only run a cron job if the script exists, since our cron tasks deploy out before our app code base `* * * * * [ -f foo.php] && php foo.php` – David Mann Oct 23 '15 at 20:41
  • 1
    [[ is a bash keyword similar to (but more powerful than) the [ command. See and . Unless you're writing for POSIX sh, it is recommend to use [[. – Rany Albeg Wein Jan 16 '16 at 14:08
  • 1
    Keep a `space` between `[` and `!`, it will not work otherwise – Ghilas BELHADJ Jun 02 '16 at 14:25
  • 1
    I propose `[[ ! -f ... ]]; then`. Why you are not using double brackets? - - I cannot get your proposal work. – Léo Léopold Hertz 준영 Oct 29 '16 at 10:47
  • In the text `echo "File not found!"` just replace double quotes for single quotes, otherwise you may get `bash: !": event not found` – Edenshaw Dec 02 '20 at 13:04
754

Bash File Testing

-b filename - Block special file
-c filename - Special character file
-d directoryname - Check for directory Existence
-e filename - Check for file existence, regardless of type (node, directory, socket, etc.)
-f filename - Check for regular file existence not a directory
-G filename - Check if file exists and is owned by effective group ID
-G filename set-group-id - True if file exists and is set-group-id
-k filename - Sticky bit
-L filename - Symbolic link
-O filename - True if file exists and is owned by the effective user id
-r filename - Check if file is a readable
-S filename - Check if file is socket
-s filename - Check if file is nonzero size
-u filename - Check if file set-user-id bit is set
-w filename - Check if file is writable
-x filename - Check if file is executable

How to use:

#!/bin/bash
file=./file
if [ -e "$file" ]; then
    echo "File exists"
else 
    echo "File does not exist"
fi 

A test expression can be negated by using the ! operator

#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
    echo "File does not exist"
else 
    echo "File exists"
fi 
BlueCacti
  • 8,169
  • 3
  • 18
  • 24
  • 1
    @0x90 If you want, you are free to edit my post and add it to the list. I guess you mean: `-n String` - Check if the length of the string isn't zero. Or do you mean `file1 -nt file2` - Check if file1 is newer then file 2 (you can also use -ot for older then) – BlueCacti May 05 '14 at 10:59
  • 1
    About -n: `The unary operator -z tests for a null string, while -n or no operator at all returns True if a string is not empty.` ~ http://www.ibm.com/developerworks/library/l-bash-test/index.html – BlueCacti May 05 '14 at 11:06
  • 1
    why didn't some add a function like function exists() { ⏎ if [ -e "$1" ]; then echo "$1 exists" else echo "$1 does not exist" fi } – Mz A Apr 12 '19 at 08:30
  • @MzA because we need to make the code readable, nobody knows what is $1. So assign $1 as `file` and then use that `file` variable to do something else looks more readable than using an unknown argument `$1` – MaXi32 Nov 11 '20 at 03:39
  • 1
    This should be top and accepted answer. – Gostega Mar 10 '21 at 06:03
302

You can negate an expression with "!":

#!/bin/bash
FILE=$1

if [ ! -f "$FILE" ]
then
    echo "File $FILE does not exist"
fi

The relevant man page is man test or, equivalently, man [ -- or help test or help [ for the built-in bash command.

starbeamrainbowlabs
  • 4,842
  • 6
  • 38
  • 68
  • 4
    In [tag:bash], `[` is a builtin. So the relevant information is rather obtained by `help [`... but this shows that `[` is a synonym for the `test` builtin, hence the relevant information is rather obtained by `help test`. See also the [Bash Conditional Expression section in the manual](http://www.gnu.org/software/bash/manual/bashref.html#Bash-Conditional-Expressions). – gniourf_gniourf Jun 29 '13 at 10:05
  • @gniourf_gniourf: Yes, but the bash built-in `[` command behaves very similarly to the external `[` command, so either `man test` or `man [` will give you a good idea of how it works. – Keith Thompson Sep 21 '13 at 19:04
  • 9
    @KeithThompson except that the _bash_ builtin `[` has more switches than the external command `[` found on my system... Generally speaking I believe it's better to read the documentation specific to a given tool, and not the documentation specific to another vaguely related one. I might be wrong, though `;)` – gniourf_gniourf Sep 21 '13 at 21:54
143
[[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"

Also, it's possible that the file is a broken symbolic link, or a non-regular file, like e.g. a socket, device or fifo. For example, to add a check for broken symlinks:

if [[ ! -f $FILE ]]; then
    if [[ -L $FILE ]]; then
        printf '%s is a broken symlink!\n' "$FILE"
    else
        printf '%s does not exist!\n' "$FILE"
    fi
fi
ormaaj
  • 5,551
  • 25
  • 34
guns
  • 9,800
  • 3
  • 36
  • 36
  • 10
    May I ask why the two "["s in the test? (eg [[ ! -a $FILE ]]). I tried all the options mentioned on a solaris box and only that one worked, so grateful, but why? – Dimitrios Mistriotis Apr 20 '11 at 08:35
  • 31
    Double brackets are a "modern" extension; eg they won't do word splitting (such as for filenames with spaces) and still work for empty strings: http://mywiki.wooledge.org/BashFAQ/031 – bw1024 Feb 14 '12 at 23:40
  • 7
    according to http://tldp.org/LDP/abs/html/fto.html -a is identical in effect to -e. It has been "deprecated," and its use is discouraged. Anyhow +1 for mentioning to check on broken symlink too – Luca Borrione Sep 01 '12 at 20:55
  • 4
    @dimitrismistriotis two "[" is a non-portable extension implemented (differently) by zsh & bash; generally you should avoid it if at all possible. – Good Person Oct 26 '12 at 15:41
  • 1
    See [SO 321348](http://stackoverflow.com/questions/321348/bash-if-a-vs-e-option) for a good reason why `-a` can't be negated in single bracket conditional expressions. Avoid `-a` altogether, I suggest. – Steve Powell Jan 17 '14 at 16:04
  • Changed this around a bit to eliminate `-a`, but also because `-a` is equivalent to `-e`, which returns true for an existing file regardless of type, you'd run into trouble if adding checks for fifos or sockets in the second example. – ormaaj Sep 14 '14 at 01:58
108

It's worth mentioning that if you need to execute a single command you can abbreviate

if [ ! -f "$file" ]; then
    echo "$file"
fi

to

test -f "$file" || echo "$file"

or

[ -f "$file" ] || echo "$file"
ormaaj
  • 5,551
  • 25
  • 34
Elazar Leibovich
  • 30,136
  • 27
  • 116
  • 161
73

I prefer to do the following one-liner, in POSIX shell compatible format:

$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"

$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"

For a couple of commands, like I would do in a script:

$  [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}

Once I started doing this, I rarely use the fully typed syntax anymore!!

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
J. M. Becker
  • 2,561
  • 27
  • 31
  • 1
    First of all, unquoted variable references are error-prone. That said, where does it say in *any* bash manpage that the `[` or `test` built-in would test for *file existence* of the argument by default (as opposed to `-e`)? Would that not be ambiguous? AFAIK (and AIUI the section "CONDITIONAL EXPRESSIONS") the only thing that is tested with your approach is that the argument is not empty (or undefined), which is, in this case, a tautology (let `$DIR = ''` and `$FILE = ''`, then the argument is still `'//'`). – PointedEars Nov 09 '12 at 02:59
  • 1
    Proof: `ls /foo`, result `ls: cannot access /foo: No such file or directory`. `[ /foo ] && echo 42`, result `42`. GNU bash, version 4.2.37(1)-release (i486-pc-linux-gnu). – PointedEars Nov 09 '12 at 03:05
  • 1
    @PointedEars: I failed to specify the `-f` option, at the moment I wrote this answer. Obviously you could always use `-e`, if your not sure it will be a regular file. Additionally In all my scripts I quote these constructs, I must have just submitted this without adequate proofing. – J. M. Becker Nov 17 '12 at 23:42
  • ACK. But you probably know that a one-liner cannot solve the if-else problem: `[ $condition ] && if_true || if_false` is error-prone. In any event, I find `[ ! -f "$file" ] && if_not_exists` easier to read and understand than `[ -f "$file" ] || if_not_exists`. – PointedEars Nov 18 '12 at 01:33
58

To test file existence, the parameter can be any one of the following:

-e: Returns true if file exists (regular file, directory, or symlink)
-f: Returns true if file exists and is a regular file
-d: Returns true if file exists and is a directory
-h: Returns true if file exists and is a symlink

All the tests below apply to regular files, directories, and symlinks:

-r: Returns true if file exists and is readable
-w: Returns true if file exists and is writable
-x: Returns true if file exists and is executable
-s: Returns true if file exists and has a size > 0

Example script:

#!/bin/bash
FILE=$1

if [ -f "$FILE" ]; then
   echo "File $FILE exists"
else
   echo "File $FILE does not exist"
fi
codeforester
  • 28,846
  • 11
  • 78
  • 104
SD.
  • 1,212
  • 15
  • 32
43

You can do this:

[[ ! -f "$FILE" ]] && echo "File doesn't exist"

or

if [[ ! -f "$FILE" ]]; then
    echo "File doesn't exist"
fi

If you want to check for file and folder both, then use -e option instead of -f. -e returns true for regular files, directories, socket, character special files, block special files etc.

Jahid
  • 18,228
  • 8
  • 79
  • 95
  • 2
    That is not bash-specific. The syntax comes from the Korn shell and is also available in zsh and bash. It has limited advantage over the standard `[` utility here though. – Stephane Chazelas Jan 03 '18 at 10:38
  • _regular_ files (as checked by `-f`) and _directories_ are just two of many different types of _files_. There are also sockets, symlinks, devices, fifos, doors... `[ -e` will test for file existence (of any type including regular, fifo, directory...) _after symlink resolution_. – Stephane Chazelas Jan 03 '18 at 10:42
  • @StephaneChazelas : I don't see any ksh or zsh tag anywhere. We are talking about bash or something that is standardized on most unix systems. So, within the context, it's bash specific. OP doesn't need to know of every whatever shells are out there :D – Jahid Jan 03 '18 at 15:59
  • That was a comment on the _"Bash specific"_ part of your answer. – Stephane Chazelas Jan 03 '18 at 16:03
  • @StephaneChazelas : Yes, and within context (bash and the standard sh), it's bash specific. I don't see the point in your second comment, it's totally out of context. OP doesn't need `-e`, he needs `-f`. – Jahid Jan 03 '18 at 16:37
  • @Jahid, to call a general construct specific to only a certain utility is just wrong- because it's not Bash specific. If one can use it in ksh, then it's simply not contrained to this utility. The fact that it's being discussed under this topic is not license to say, "By the way, now that we're talking about Bash, let me introduce you to something that's specific to Bash." No- it's just not. -1 for being misleading in a technical forum. If you were writing about Python, would you say, "Now let me introduce you to this amazing Python-specific concept: The `if` statement." ? I don't think so. – Mike S May 09 '18 at 18:13
  • ...You also miss the mark with your comment about `-e`. As Stephane says, `-e` returns true for almost any entity in the filesystem: fifos, directories, regular files, block special files, character special files, etc. Your answer appears to suggest that you're simply expanding a little bit on `-f` and adding directories to its match against regular files. You're not; it's much more broad than that. – Mike S May 09 '18 at 18:18
38

You should be careful about running test for an unquoted variable, because it might produce unexpected results:

$ [ -f ]
$ echo $?
0
$ [ -f "" ]
$ echo $?
1

The recommendation is usually to have the tested variable surrounded by double quotation marks:

#!/bin/sh
FILE=$1

if [ ! -f "$FILE" ]
then
   echo "File $FILE does not exist."
fi
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
artdanil
  • 4,304
  • 2
  • 30
  • 47
  • 8
    The recommendation is to have **every** variable surrounded by double quotation marks, unless you know exactly that you have one of the rare cases where it's unnecessary, or one of the even rarer cases where it's harmful. (And no, this is not one of them.) – Uwe May 28 '13 at 11:43
  • Would you care to elaborate why this is not the case to use double quotation mark? Otherwise I don't see the usefulness in the comment. – artdanil May 28 '13 at 23:29
  • 4
    I meant: This is not one of the rare cases where it's unnecessary or harmful. A shell programmer should get used to enclose (almost) every variable in double quotes; this rule is not limited to `[ ... ]`. – Uwe May 29 '13 at 09:03
  • See also http://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-variable – tripleee May 27 '16 at 16:37
26

In

[ -f "$file" ]

the [ command does a stat() (not lstat()) system call on the path stored in $file and returns true if that system call succeeds and the type of the file as returned by stat() is "regular".

So if [ -f "$file" ] returns true, you can tell the file does exist and is a regular file or a symlink eventually resolving to a regular file (or at least it was at the time of the stat()).

However if it returns false (or if [ ! -f "$file" ] or ! [ -f "$file" ] return true), there are many different possibilities:

  • the file doesn't exist
  • the file exists but is not a regular file (could be a device, fifo, directory, socket...)
  • the file exists but you don't have search permission to the parent directory
  • the file exists but that path to access it is too long
  • the file is a symlink to a regular file, but you don't have search permission to some of the directories involved in the resolution of the symlink.
  • ... any other reason why the stat() system call may fail.

In short, it should be:

if [ -f "$file" ]; then
  printf '"%s" is a path to a regular file or symlink to regular file\n' "$file"
elif [ -e "$file" ]; then
  printf '"%s" exists but is not a regular file\n' "$file"
elif [ -L "$file" ]; then
  printf '"%s" exists, is a symlink but I cannot tell if it eventually resolves to an actual file, regular or not\n' "$file"
else
  printf 'I cannot tell if "%s" exists, let alone whether it is a regular file or not\n' "$file"
fi

To know for sure that the file doesn't exist, we'd need the stat() system call to return with an error code of ENOENT (ENOTDIR tells us one of the path components is not a directory is another case where we can tell the file doesn't exist by that path). Unfortunately the [ command doesn't let us know that. It will return false whether the error code is ENOENT, EACCESS (permission denied), ENAMETOOLONG or anything else.

The [ -e "$file" ] test can also be done with ls -Ld -- "$file" > /dev/null. In that case, ls will tell you why the stat() failed, though the information can't easily be used programmatically:

$ file=/var/spool/cron/crontabs/root
$ if [ ! -e "$file" ]; then echo does not exist; fi
does not exist
$ if ! ls -Ld -- "$file" > /dev/null; then echo stat failed; fi
ls: cannot access '/var/spool/cron/crontabs/root': Permission denied
stat failed

At least ls tells me it's not because the file doesn't exist that it fails. It's because it can't tell whether the file exists or not. The [ command just ignored the problem.

With the zsh shell, you can query the error code with the $ERRNO special variable after the failing [ command, and decode that number using the $errnos special array in the zsh/system module:

zmodload zsh/system
ERRNO=0
if [ ! -f "$file" ]; then
  err=$ERRNO
  case $errnos[err] in
    ("") echo exists, not a regular file;;
    (ENOENT|ENOTDIR)
       if [ -L "$file" ]; then
         echo broken link
       else
         echo does not exist
       fi;;
    (*) syserror -p "can't tell: " "$err"
  esac
fi

(beware the $errnos support was broken with some versions of zsh when built with recent versions of gcc).

Stephane Chazelas
  • 5,014
  • 2
  • 27
  • 29
24

There are three distinct ways to do this:

  1. Negate the exit status with bash (no other answer has said this):

    if ! [ -e "$file" ]; then
        echo "file does not exist"
    fi
    

    Or:

    ! [ -e "$file" ] && echo "file does not exist"
    
  2. Negate the test inside the test command [ (that is the way most answers before have presented):

    if [ ! -e "$file" ]; then
        echo "file does not exist"
    fi
    

    Or:

    [ ! -e "$file" ] && echo "file does not exist"
    
  3. Act on the result of the test being negative (|| instead of &&):

    Only:

    [ -e "$file" ] || echo "file does not exist"
    

    This looks silly (IMO), don't use it unless your code has to be portable to the Bourne shell (like the /bin/sh of Solaris 10 or earlier) that lacked the pipeline negation operator (!):

    if [ -e "$file" ]; then
        :
    else
        echo "file does not exist"
    fi
    
Stephane Chazelas
  • 5,014
  • 2
  • 27
  • 29
  • Any portability difference between `! [` and `[ !`? – Frozen Flame Aug 18 '15 at 03:42
  • 3
    The `! [` [is POSIX for shell pipelines 2.9.2 (any command)](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_02) `Otherwise, the exit status shall be the logical NOT of the exit status of the last command` and `[ ! ` [is POSIX for test](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html#tag_20_128) `! expression True if expression is false. False if expression is true.` So, both are POSIX, and in my experience, both are extensively supported. –  Aug 18 '15 at 04:16
  • 1
    @FrozenFlame, the Bourne shell didn't have the `!` keyword which was introduced by the Korn shell. Except maybe for Solaris 10 and older, you're unlikely to come across a Bourne shell these days though. – Stephane Chazelas Jan 03 '18 at 10:39
11

To reverse a test, use "!". That is equivalent to the "not" logical operator in other languages. Try this:

if [ ! -f /tmp/foo.txt ];
then
    echo "File not found!"
fi

Or written in a slightly different way:

if [ ! -f /tmp/foo.txt ]
    then echo "File not found!"
fi

Or you could use:

if ! [ -f /tmp/foo.txt ]
    then echo "File not found!"
fi

Or, presing all together:

if ! [ -f /tmp/foo.txt ]; then echo "File not found!"; fi

Which may be written (using then "and" operator: &&) as:

[ ! -f /tmp/foo.txt ] && echo "File not found!"

Which looks shorter like this:

[ -f /tmp/foo.txt ] || echo "File not found!"
10

The test thing may count too. It worked for me (based on Bash Shell: Check File Exists or Not):

test -e FILENAME && echo "File exists" || echo "File doesn't exist"
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
android developer
  • 106,412
  • 122
  • 641
  • 1,128
10

This code also working .

#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
 echo "File '$FILE' Exists"
else
 echo "The File '$FILE' Does Not Exist"
fi
Lemon Kazi
  • 3,148
  • 2
  • 31
  • 53
7

The simplest way

FILE=$1
[ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
Acumenus
  • 41,481
  • 14
  • 116
  • 107
lancerex
  • 1,132
  • 13
  • 12
6

This shell script also works for finding a file in a directory:

echo "enter file"

read -r a

if [ -s /home/trainee02/"$a" ]
then
    echo "yes. file is there."
else
    echo "sorry. file is not there."
fi
Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
Simmant
  • 1,360
  • 22
  • 39
  • 3
    It isn't clear that this adds anything that other answers have not already given. It hard-codes a pathname. Since the question is tagged [tag:bash], it could use `read -p "Enter file name: " -r a` to prompt as well as read. It does use quotes around the variable; that's good, but should be explained. It might be better if it echoed the file name. And this checks that the file exists and is not empty (that's the meaning of `-s`) whereas the question asks about any file, empty or not (for which `-f` is more appropriate). – Jonathan Leffler Aug 05 '15 at 21:01
6

sometimes it may be handy to use && and || operators.

Like in (if you have command "test"):

test -b $FILE && echo File not there!

or

test -b $FILE || echo File there!
André
  • 1,065
  • 8
  • 20
3

If you want to use test instead of [], then you can use ! to get the negation:

if ! test "$FILE"; then
  echo "does not exist"
fi
Bill the Lizard
  • 369,957
  • 201
  • 546
  • 842
Mauro Zallocco
  • 176
  • 1
  • 3
1

You can also group multiple commands in the one liner

[ -f "filename" ] || ( echo test1 && echo test2 && echo test3 )

or

[ -f "filename" ] || { echo test1 && echo test2 && echo test3 ;}

If filename doesn't exit, the output will be

test1
test2
test3

Note: ( ... ) runs in a subshell, { ... ;} runs in the same shell. The curly bracket notation works in bash only.

upteryx
  • 99
  • 3
  • 4
  • 2
    No, the curly bracket notation is *not* bash-only; it works in any POSIX-compliant shell. – Charles Duffy Nov 04 '19 at 13:27
  • 1
    The most interesting part of your answer is explaining the difference between `(...)` and `{...}`! I had no idea about that! I'm learning every day... thanks! – Gwyneth Llewelyn Jan 17 '21 at 20:42
0
envfile=.env

if [ ! -f "$envfile" ]
then
    echo "$envfile does not exist"
    exit 1
fi
kta
  • 17,024
  • 7
  • 58
  • 43
  • 1
    While this code may resolve the OP's issue, it is best to include an explanation as to how your code addresses the OP's issue. In this way, future visitors can learn from your post, and apply it to their own code. SO is not a coding service, but a resource for knowledge. Also, high quality, complete answers are more likely to be upvoted. These features, along with the requirement that all posts are self-contained, are some of the strengths of SO as a platform, that differentiates it from forums. You can edit to add additional info &/or to supplement your explanations with source documentation. – ysf Jun 04 '20 at 20:12