Reputation: 45
I'm doing some homework for a shell scripting class and had a question asking me to write a script that tests whether or not the argument entered is a valid shell variable name. The below script seems to work fine.
if echo "$1" | grep -v ".*[^A-Za-z_]" > /dev/null
then
echo yes
else
echo no
fi
I understand brackets are short hand for the test function in the BASH shell. My problem is that, when I attempted the above script using brackets I got an error.
if [ echo "$1" | grep -v ".*[^A-Za-z_]" > /dev/null ]
The problem with this (I believe) is that grep is trying to use the ] as its argument, thus resulting in an error when the script is run.
In what situations do I not need brackets?
Upvotes: 2
Views: 151
Reputation: 41456
You may also use double square brackets [[
instead of single [
Read more about it here: http://mywiki.wooledge.org/BashFAQ/031:
[ ("test" command) and [[ ("new test" command) are used to
evaluate expressions. [[ works only in Bash, Zsh and the Korn shell,
and is more powerful; [ and test are available in POSIX shells
Upvotes: 1
Reputation: 80931
[
/test
is a command (also a built-in), as you said. It is a command that accepts arguments of a specific sort and behaves in a specific way given those arguments.
It accepts flags and comparison operators and operates on those to obtain a true
or false
result. It then translates that result into a return code. 0
for true
and 1
for false
.
The if
construct in the shell is defined
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
The if list is executed. If its exit status is zero, the then list is executed. Otherwise, each elif list is executed in turn, and if its exit status is zero, the corresponding then list is executed and the command completes. Otherwise, the else list is executed, if present. The exit status is the exit status of the last command executed, or zero if no condition tested true.
So when [
/test
returns an exit code that is what if
evaluates.
The reason you don't need (and can't use) [
around the echo
command/pipeline is because that isn't a valid set of [
arguments. Instead that is a command list
itself and, as such, does not need to be evaluated by [
. You can simply use it directly and have the return code of the pipeline handed to if
for evalution.
Upvotes: 2
Reputation: 263267
[
is actually a command (it happens to be built into most shells), not just part of the syntax of an if
statement.
The if
statement executes the command that is its argument. If that command succeeds (sets $?
to zero), then the condition is true; if it fails (sets $?
to some non-zero value), the condition is false.
The built-in [
command is almost exactly equivalent to the test
command; the difference is that [
requires ]
as its last argument.
See also https://unix.stackexchange.com/a/22728/10454
Upvotes: 4