1

[Update]

1) I have a file (a.cfg) that contains lines like this:

FILE;'/tmp/testfile';;;+;'Add this line';$;Y

2) In my script, I read this file line by line :

while read line
do
...
done < a.cfg

3) When a line has been read, and it is not empty, I split up the line using IFS :

IFS=';' read a b c d e f g h <<< $line

4) To be sure, I echo the contents of $b. It returns :

'/tmp/testfile'

including the single quotes.

5) Next, I want to see if the location stored in $b exists :

if ! [ -e "$b" ]
then
  echo "not found"
else
  echo "found"
fi

This returns not found....

6) When I do an ls -l '/tmp/testfile' from the prompt (again, including single quotes), I get :

-rw-r--r-- 1 root root 0 Jul 10 22:22 /tmp/testfile

(Did I mention I'm doing all of this as root ?)

7) I tried the above if statement in several ways, but the result remains the same :

if [ ! -e $b ]
if ! [ -e "$b" ]
if [[ ! -e $b ]]
if ! [[ -e $b ]]

So, please tell me where I'm thinking not right....

[End update]

I'm trying to test if a file exists by passing the contents of a variable to the test -e of bash. The variable looks like this :

FILE1='/etc/wherever/whatever'

When i do :

[[ -e "$FILE1" ]]

$? equals to 1, and it says it can't find the file (above path is an example....)

Tried several options: double quotes around the filepath instead of single quotes (variable is obtained from a line in a file)

Found out it only works if I put the filepath in the file I read without any quotes. But that would be a problem when using filenames withe spaces in it.

So, to clarify: 1) file contains lines that are read one by one 2) columns in line are split using IFS into separate variables 3) one variable is a filename, that is enclosed in single quotes 4) a [[ -e $variable ]] can't find the file.

What would be the correct syntax, please ?

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • 1
    I suggest reviewing the tag 'testing' as this might cause confusion with automated software testing, which is what that tag stands for. – Felype Jul 10 '17 at 16:01
  • 1
    Can you show your actual bash code around this and not just the fragments? The mechanism works fine for me in `bash`. What happens if you use double quotes: `FILE1="/etc/wherever/whatever"`? – lurker Jul 10 '17 at 16:04
  • 1
    The problem seems to be in the way you read/parse the initial file. I'm suspecting that in reality you have `FILE1="'/etc/wherever/whatever'"`. In which case, just strip the outer single quotes and quote `$FILE` as you already do. Anyway, that part (reading/parsing) is missing in your question. – randomir Jul 10 '17 at 16:06
  • 1
    seems to work fine. check your actual filename. bash-4.3$ f='a/b/c/d' bash-4.3$ if [[ -e $f ]]; then echo true; fi true – Kaushik Nayak Jul 10 '17 at 16:09
  • Setting IFS won't make `read` recognise quoted strings. – choroba Jul 10 '17 at 16:13
  • If the `#!/bin/bash` interpreter line isn't included, you may be attempting to execute the test in a shell that doesn't support `[[...]]`. Try `bash -c '[[ -e "$FILE1" ]] && echo Found || echo Not Found'` and see what it does. – David C. Rankin Jul 10 '17 at 17:09
  • 1
    By request, question has been updated – notaverygoodprogrammer Jul 10 '17 at 23:11

2 Answers2

1

This happens because you have literal quotes in your string, and they are not being interpreted as shell script code.

Consider this PHP code:

$x="1+1";
echo 1+1;   # Writes 2
echo $x;    # Writes 1+1, not 2

It works the same way in Bash:

var="'myfile'"
[[ -e 'myfile' ]]  # Checks for a file called  myfile 
[[ -e $var ]]      # Checks for a filename with apostrophes in it, not  myfile

You have to extract the exact filename you want. Since your filename doesn't contain apostrophes, you should strip them:

var="'myfile'"
var=${var//\'/}  # Replace all apostrophes with nothing
if [[ -e $var ]]
then
  echo "Exists"
fi
that other guy
  • 116,971
  • 11
  • 170
  • 194
-1

You can try this:

[ $(ls "$file") == "$file" ]

Also use an other flag likes -r or -x.

raah
  • 71
  • 2
  • 6
  • That involves invoking a subshell, which is not overly efficient. I would stick with the original approach, but fix the quotes (I suspect @randomir is onto something). – blackghost Jul 10 '17 at 17:03
  • It also uses an extremely bad practice of using the output of `ls` for anything programmatic. – chepner Jul 10 '17 at 17:32