Shell script to create a file if it doesn't exist?

145,564

Solution 1

Possibly simpler solution, no need to do explicit tests, just use:

mkdir -p /Scripts
touch /Scripts/file.txt

If you don't want the "modification" time of an existing file.txt to be changed by touch, you can use touch -a /Scripts/file.txt to make touch only change the "access" and "change" times.

Solution 2

You are getting the error because there is no space between [ and ! however there are also some flaws in your code. First you are checking if the file does not exist, and if not you are doing nothing. If the file DOES exist you are making a directory (but not doing anything to create the file).

You also don't need the null operation, you should be able to simply do:

#! /bin/bash -
if [[ ! -e /Scripts/file.txt ]]; then
    mkdir -p /Scripts
    touch /Scripts/file.txt
fi

[command2]

This is checking if /Scripts/file.txt does not exist it will create the /Scripts directory and then the file.txt file. You could also check for the existence of the directory separately if you wanted. Additionally notice I am using -e instead of -f as you asked simply to check for the existence of a file which is what -e will do where -f checks that it is a "regular file" http://tldp.org/LDP/abs/html/fto.html

Solution 3

To start with, shell script is not bash script, so let's make your code more general:

#!/bin/sh

Every Posix system must have that file; bash is strictly optional.

No need to test if the directory exists, just

dir=/Scripts
mkdir -p $dir

To create the file if it doesn't exist,

filename=$dir/file.txt
test -f $filename || touch $filename

Or if you prefer,

filename=$dir/file.txt
if [ ! -f $filename ]
then
    touch $filename
fi

Solution 4

You have a syntactical error. You require spaces before and after the [ and ].

Solution 5

#!/bin/bash

# Check for the file that gets created when the script successfully finishes.
CHECKFILE="/Scripts/file.txt"

CHECKDIR=$( dirname "$CHECKFILE" )

# The directory with the file must exist
mkdir -p "$CHECKDIR"
if [ ! -f "$CHECKFILE" ]; then
    # What to do if the file is not there
fi
touch "$CHECKFILE"

The above assumes that there are no "tricks" such as creating a directory called /Scripts/file.txt (which could be a way of forcing the script to always enter the if branch). If the "file" is a directory, the -f test will fail and the touch command will not change anything.

Share:
145,564
jrw
Author by

jrw

Updated on September 18, 2022

Comments

  • jrw
    jrw almost 2 years

    I need to create a shell script that checks for the presence of a file and if it doesn't exist, creates it and moves on to the next command, or just moves on to the next command. What I have doesn't do that.

    #!/bin/bash
    
    # Check for the file that gets created when the script successfully finishes.
    if [! -f /Scripts/file.txt]
    then
    : # Do nothing. Go to the next step?
    else
    mkdir /Scripts # file.txt will come at the end of the script
    fi
    
    # Next command (macOS preference setting)
    defaults write ...
    

    Return is

    line 5: [!: command not found
    mkdir: /Scripts: File exists
    

    No idea what to do. Every place a Google search brings me indicates something different.

    • kirkpatt
      kirkpatt over 6 years
      Any reason you can't just touch the file and skip the conditional?
    • TheDudeAbides
      TheDudeAbides over 5 years
      Other answers below address the syntax error (missing the space between [ and !), but it's probably helpful to point out here that [ is an actual command on Unix. A Unix command requires some whitespace between the command name and its arguments. Yes, it's a Bash builtin, too, but there's also a binary at /usr/bin/[ on most systems.
  • PiedPiper
    PiedPiper over 6 years
    You're not checking if the file exists
  • Ant
    Ant over 6 years
    what is the file does not exists but the directory does?
  • Olivier Dulac
    Olivier Dulac over 6 years
    @Ant: mkdir -p : create all the necessary directories, without complaining if one already exists. ex: mkdir /home/user1/tmp : will create this hierarchy , independant from the fact the /home , or /home/user1, directories existed beforehand . touch will also just update the time of an existing file, or create a new one if no file existed. One could even get rid of the if ... then part, as it is quite ok to just launch those 2 commands, if you want to ensure those directories exist and that file exist within it.
  • ssola
    ssola over 6 years
    If you don’t care about the mtime, you could use >>/Scripts/file.txt. This will open the file for appending and create it if it doesn’t exist.
  • jmullee
    jmullee over 6 years
    same ides with more checking looks like: D=/boot/bork ; F=fnord ; mkdir -p "$D" && { touch "$D/$F" && echo "created $D/$F OK" ; } || { echo "couldn't create dir '$D'" ; }
  • user1593842
    user1593842 over 3 years
    @kojiro awesome suggestion. No need to modify the file time (any of them) if you are just trying to ensure it exists.
  • sgfw
    sgfw over 3 years
    this should not be a correct answer: touch create/update the file even IF ALREADY EXISTS. The question is about if does not exist.