0

I need to check if the value of a variable is a path that exists. This is being read from a text file.

Basically, the point I'm stuck at, the line variable is as follows: location_of_folder=~/Desktop/folder\ with\ spaces

I need to check if the path after location_of_folder= exists.

Here's what I've tried:

foo="${line#'location_of_folder='}"
if ! [[ -d "${foo}" ]]
then
  echo 'This path exists.'
else
  echo 'This path does not exist.'
fi

if ! [[ -d "${line#'location_of_folder='}" ]]
then
  echo 'This path exists.'
else
  echo 'This path does not exist.'
fi

However both say the path is nonexistant, which is indeed not true.

And yes, inside of the text file I'm reading from looks like:

location_of_folder=~/Desktop/folder\ with\ spaces

Using bash 3.2.57(1)-release under OSX El Capitan 10.11.6.

Thank you.

leetbacoon
  • 1,111
  • 2
  • 9
  • 32
  • 1
    Drop the single quotes; they are being treated literally. – chepner Jun 17 '19 at 18:39
  • chepner I..wait what? That works? How? I thought single quoting the `location_of_folder=` was necessary. – leetbacoon Jun 17 '19 at 18:42
  • Hm. Actually, there are at best unnecessary. – chepner Jun 17 '19 at 18:45
  • What are they being interpreted as? – leetbacoon Jun 17 '19 at 18:46
  • How exactly are you setting the value of `line`? – chepner Jun 17 '19 at 18:46
  • `line` is set from using `while read -r line; do .......; done < text_file.txt` – leetbacoon Jun 17 '19 at 18:47
  • You probably shouldn't have backslashes there. That said, we really need a [mcve]. – melpomene Jun 17 '19 at 18:47
  • How are you reading the path? If you are using `-r`, then you probably have literal backslashes in the name. Inspect the value in the variable. – William Pursell Jun 17 '19 at 18:47
  • 1
    Ah, just saw your comment. Stop using `-r`. – William Pursell Jun 17 '19 at 18:48
  • 1
    The name of the directory doesn't actually have backslashes in it; those are shell syntax to make sure the spaces are treated as part of the name in the assignment to `location_of_folder`. They are preserved in the value of `line` by `read -r`, which means `${line#...}` doesn't contain the actual name of your directory. – chepner Jun 17 '19 at 18:50
  • Yes, my `folder\ with\ spaces` has escaped spaces. – leetbacoon Jun 17 '19 at 18:52
  • You would probably be better off using `declare "$line"` to actually define a variable named `location_of_folder` in your script, then use `[ -d "$location_of_folder" ]`. (That's not without its risks, but it ensures that you look for the directory intended by whoever wrote `location_of_folder=~/Desktop/folder\ with\ spaces` in the first place. It will also continue to work if the line gets changed to `location_of_folder=~/Desktop/"folder with spaces"`.) – chepner Jun 17 '19 at 18:54
  • I thought on doing that, however since it is a config file I am reading from I wanted to make sure the user-defined/manually user-written value was not incorrectly written or harmful. – leetbacoon Jun 17 '19 at 18:55
  • 1
    At what point in this process do you expect `~` to be converted to a path to your home directory? That is probably (almost certainly) not getting expanded. – William Pursell Jun 17 '19 at 18:56
  • William Pursell the first instance, when it is checking it with `if` – leetbacoon Jun 17 '19 at 18:57
  • 1
    add `set -x` a line before your `if` statement and turn off debugging with `set +x` the line after `fi`. Now you can see exactly what values are being processed inside of the `if` (although it's not a straightforward read). Good luck. – shellter Jun 17 '19 at 19:06
  • `~` is basically never appropriate for use in shell scripts. Use `$HOME` instead, which -- unlike `~` -- is actually expanded in double quotes. – Charles Duffy Jun 17 '19 at 19:45
  • That said, your problem is more about `~` expansion than anything else, and we have lots of duplicates covering that space. – Charles Duffy Jun 17 '19 at 19:50

1 Answers1

0

This isn't really an answer, but comments are hard to format. There are several issues here, and the sequence below demonstrates some of them. Note that there are blatant bad practices here (do not use eval, but that's essentially what you need if you want to expand that ~ to a path).

$ cat input
location_of_folder=~/Desktop/directory\ with\ spaces
location_of_folder=$HOME/Desktop/directory\ with\ spaces
$ while IFS== read -r name path; do if eval "test -d $path"; then echo "$path" exists; else echo "$path" does not exist; fi;  done < input
~/Desktop/directory\ with\ spaces exists
$HOME/Desktop/directory\ with\ spaces exists
$ while IFS== read name path; do if test -d "$path"; then echo "$path" exists; else echo "$path" does not exist; fi;  done < input
~/Desktop/directory with spaces does not exist
$HOME/Desktop/directory with spaces does not exist
$ while IFS== read name path; do if eval test -d "$path"; then echo "$path" exists; else echo "$path" does not exist; fi;  done < input
bash: test: too many arguments
~/Desktop/directory with spaces does not exist
bash: test: too many arguments
$HOME/Desktop/directory with spaces does not exist
$ while IFS== read name path; do if eval "test -d \"$path\""; then echo "$path" exists; else echo "$path" does not exist; fi;  done < input
~/Desktop/directory with spaces does not exist
$HOME/Desktop/directory with spaces exists 

Well, this is sort of an answer I guess, since the first line appears to give you what you want. But using eval just to expand ~ is a terrible idea.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • See https://stackoverflow.com/questions/3963716/how-to-manually-expand-a-special-variable-ex-tilde-in-bash/29310477#29310477 – William Pursell Jun 17 '19 at 19:16
  • Would it be better to tell the user to only input `"${HOME}"` instead of `~`, and then craft a way to check to make sure it does not contain a literal `~` (in case the user does it anyway)? – leetbacoon Jun 17 '19 at 19:23
  • If you're going to check for a ~, you might as well just expand it yourself. – William Pursell Jun 17 '19 at 19:24
  • @leetbacoon, how is the user entering that input? If they're passing it, say, on your program's command line, `~` will be expanded before your program is ever started... *if* it's unquoted. If the user is quoting it, that's *their* problem, and will break lots of other programs too (you can't `ls "~"` successfully, f/e). – Charles Duffy Jun 17 '19 at 19:47
  • ...oh, a config file. If you `source` that config file, the `~` will be expanded, though of course that requires that you trust its contents to be safe to run as code. If you *don't* trust it, there are some tricks that can be played with rbash, but I don't much recommend them. – Charles Duffy Jun 17 '19 at 19:47
  • See https://github.com/charles-dyfis-net/bees/blob/uuid-independent-wrapper/scripts/beesd.in#L54-L60 for an example of the aforementioned style of hackery to semi-safely eval an arbitrary config file (more safely than `eval`ing or `source`ing it, anyhow). – Charles Duffy Jun 17 '19 at 19:49