I have a piece of code to find the first file in a directory:
bash~> $( echo eval "ls | head -1" )
arguprog.sh
This snippet was then added to an if statement, to run a different set of commands if that file was arguprog.sh:
bash~> if [[ $( echo eval "ls | head -1" ) == "arguprog.sh" ]]; then echo "TRUE"; else echo "FALSE"; fi;
FALSE
However this is not doing what I want. It returns FALSE even though the first file is arguprog.sh!
Is there a way to resolve this while still doing the string comparison entirely within the test block?
First, eval
is evil, especially when it's not needed. In your case, eval
is not needed!
Replace the coding horror you showed with just:
ls | head -1
and to include it in your test statement:
if [[ $(ls | head -1) = "arguprog.sh" ]]; then echo "TRUE"; else echo "FALSE"; fi
But this is wrong and broken (see below).
Now something more general: do not parse the output of ls
. If you want to find the first file (or directory or...) in your current dir, use globs and this method:
shopt -s nullglob
files=( * )
# The array files contains the names of all the files (and directories...)
# in the current directory, sorted by name.
# The first one is given by the expansion of "${files[0]}". So:
if [[ "${files[0]}" = "arguprog.sh" ]]; then echo "TRUE"; else echo "FALSE"; fi
Notice that your method, parsing ls
is wrong. Look:
$ # Create a new scratch dir
$ mkdir myscratchdir
$ # Go in there
$ cd myscratchdir
$ # touch a few files:
$ touch $'arguprog.sh\nwith a newline' "some other file"
$ # I created 2 files, none of them is exactly arguprog.sh. Now look:
$ if [[ $(ls | head -1) = "arguprog.sh" ]]; then echo "TRUE"; else echo "FALSE"; fi
TRUE
$ # HORROR!
There are twisted work-arounds for this, but really, the best method is the one I just gave you.
Done!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With