Been unsuccessful figuring out why the OR operator is ignored and both commands are executed.
find / -ipath /usr/bin 2>/dev/null -print -quit || echo "Not a valid directory"
/usr/bin
Not a valid directory
Been experimenting with command substitution and grouping but the result is the same or find is ignored.
{find / -ipath /usr/bin 2>/dev/null -print -quit || echo "Not a valid directory"}
Not a valid directory}
$(find / -ipath /usr/bin 2>/dev/null -print -quit) || echo "Not a valid directory"
-bash: /usr/bin: Is a directory
Not a valid directory
If we remove 2>/dev/null
:
For the first find
command we may see something like:
$ find / -ipath /usr/bin -print -quit
find: ‘/lost+found’: Permission denied
find: ‘/root’: Permission denied
/usr/bin
$ echo $?
1
$
So we see that find
continues running after errors, but returns a non-zero exit code at the end. So the "OR" would trigger and your echo
would run.
For the second case:
$ {find / -ipath /usr/bin -print -quit
sh: {find: not found
$ echo $?
127
$
This has attempted to run a comand called literally {find
, which does not exist. This also returns a non-zero result. So the "OR" would trigger and your echo
would run.
Note that {
is only special to the shell when it appears as a separate word at the start of a command; and }
is only special after ;
, a newline, or in a few other situations. Consider:
{true || echo ok}
{ false || echo ok;}
{ false || echo ok
}
{ false || echo ok}
(Note that the fourth of these is still waiting for a terminating }
.
Finally, using $(
... )
causes the shell to execute the command inside the parentheses and then carry on as if its output were part of the original commandline. Consider:
$ echo hello
hello
$ $(printf 'ec%co h%c' h e)llo
hello
$
When you applied it to find
, the shell attempted to use find
's output as the command to run. /usr/bin
is, as the error stated, a directory and not a program.
It is more normal to use $(
...)
to produce arguments to a command rather than to generate the command itself.