user8378799
user8378799

Reputation:

Error while checking existence of a file in shell script

I wrote a script to check if a given file exists or not ( i am considering only regular files ) It displays opposite, that is, if file exists then "not found" and "file found" if file doesn't exists. Have i messed up the if else ? Please tell me how to rectify it.

#! /bin/bash
is_file_exists(){
 local file="$1"
 if  [[ -f "$file" ]]
 then
  return 1
 else
 return 0
 fi
}

if [[ "$#" -eq 0 ]]
then
 echo "enter a file name" 
 exit
fi

if ( is_file_exists "$1" )
then
  echo "file found"
else
  echo "not found"
fi

Upvotes: 0

Views: 555

Answers (3)

cdarke
cdarke

Reputation: 44444

As my comment said, you have the return 0 and return 1 around the wrong way in your is_file_exists function, and you should use: if is_file_exists "$1", i.e. no parentheses.

Shell if statements test success or failure of the given command. Success is defined as a returned value of zero. So maybe you had the returns around that way because you might have come from C, Java, or a similar language where zero is false. Think in terms of success or failure rather than true or false.

I have suggested a few other tweaks, including consistent indentation:

#! /bin/bash
is_file_exists(){

    local file="$1"

    # [ (test) could have been used here
    # Is the name given a regular file?        
    if  [[ -f $file ]]     # quotes not required with [[ (but are with [ )
    then
        return 0
    else
        return 1
    fi
}

# Use (( )) for arithmetic comparisons
if (( $# == 0 ))
then
    echo "enter a file name" >&2       # error messages should go to stderr
    exit
fi

# Delimit filenames on display, shows unintended whitespace
if is_file_exists "$1"
then
    echo "'$1' file found"
else
    echo "'$1' not found"
fi

Upvotes: 1

Toby Speight
Toby Speight

Reputation: 30992

Well, firstly, you're not checking for existence (-e); you're checking that it exists and that it's a regular file.

Secondly, you're returning 0 (success) if it doesn't exist.

But since the return value of a function is that of the last command, there's no need for the if/else at all:

is_file_exists() {
   test -f "$1"
}

Re-written program (as portable shell, since it doesn't need anything Bash-specific):

#!/bin/sh

regular_file_exists() {
   test -f "$1"
}

# Is it used correctly?
if [ $# -ne 1 ]
then
  echo "enter a file name" >&2
  exit 1
fi

if regular_file_exists "$1"
then
  echo "file found"
else
  echo "not found"
fi

Upvotes: 0

Lino
Lino

Reputation: 6160

If you still want to keep the "inverse" logic of your is_file_exists() function then you can do the following:

#! /bin/bash
is_file_exists(){
 local file="$1"
 if  [[ -f "$file" ]]
 then
  return 1
 else
  return 0
 fi
}

if [[ "$#" -eq 0 ]]
then
 echo "enter a file name" 
 exit
fi

is_file_exists "$1"
retVal=$?

if [ $retVal -ne 0 ]; then
  echo "file found"
else
  echo "not found"
fi

This stores the return value of the function into the retVal variable and checks its value to provide the desired output.

Also, as suggested by @Toby, another solution would be (skipping the fuction):

if [[ "$#" -eq 0 ]]
then
 echo "enter a file name" 
 exit
fi

if ! is_file_exists "$1"; then
  echo "file found"
else
  echo "not found"
fi

Upvotes: 0

Related Questions