Always gives false even though file exists and is not empty

Bash

Bash Problem Overview


I have a bash script:

echo " enter file name "
read $file
if [ -f "$file" ] && [ -s "$file" ]
then 
   echo " file does not exist, or is empty "
else
   echo " file exists and is not empty "
fi

No matter what I enter as a $file, it gives me the false value. I can even enter a file that does not even exist; it still will give me the false value. Why is that?

Bash Solutions


Solution 1 - Bash

It is enough to check for -s, because it says:

> FILE exists and has a size greater than zero

http://unixhelp.ed.ac.uk/CGI/man-cgi?test

also your output is switched, so it outputs does not exists when a file exists, because -s will give TRUE if file exists AND has a size > 0.

So correctly you should use:

echo " enter file name "
read file
if [ -s "$file" ]
then 
   echo " file exists and is not empty "
else
   echo " file does not exist, or is empty "
fi

This will give you the expected output.

Also it should be

read file

instead of

read $file

If you want further informations, I recommand reading man test and man read

Solution 2 - Bash

Please note, that [ -f "$file" ] && [ -s "$file" ] will return true if file exists and is not empty.

Other option:

if [[ -f "/path/to/file" && -s "/path/to/file" ]]; then 
    echo "exist and not empty"
else 
    echo "not exist or empty"; 
fi

Solution 3 - Bash

This is the true solution:

if [[ -f $file && -s $file ]]

With [[ the quotes are unnecessary because [[ handles empty strings and strings with whitespace more intuitively.

The solution that was proposed to you:

if [ -s "$file" ]

is wrong because it is instead equivalent to:

if [[ -e $file && -s $file ]]

which, in addition to the regular files dictated by the word -f, also looks for:

  1. Directory
  2. Symbolic Link
  3. Block Special Device
  4. Character Device
  5. Unix Socket (local domain socket)
  6. Named Pipe

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiondemboz11View Question on Stackoverflow
Solution 1 - BashNidhoeggerView Answer on Stackoverflow
Solution 2 - BashSamuelView Answer on Stackoverflow
Solution 3 - BashMario PalumboView Answer on Stackoverflow