[
and test
are synonyms (except [
requires ]
), so you don't want to use [ test
:
[ -x /bin/cat ] && echo 'cat is executable'
test -x /bin/cat && echo 'cat is executable'
test
returns a zero exit status if the condition is true, otherwise nonzero. This can actually be replaced by any program to check its exit status, where 0 indicates success and non-zero indicates failure:
# echoes "command succeeded" because echo rarely fails
if /bin/echo hi; then echo 'command succeeded'; else echo 'command failed'; fi
# echoes "command failed" because rmdir requires an argument
if /bin/rmdir; then echo 'command succeeded'; else echo 'command failed'; fi
However, all of the above examples only test against the program's exit status, and ignore the program's output.
For find
, you will need to test if any output was generated. -n
tests for a non-empty string:
if [[ -n $(find /var/log/crashes -name "app-*.log" -mmin -5) ]]
then
service myapp restart
fi
A full list of test arguments is available by invoking help test
at the bash
commandline.
If you are using bash
(and not sh
), you can use [[ condition ]]
, which behaves more predictably when there are spaces or other special cases in your condition. Otherwise it is generally the same as using [ condition ]
. I've used [[ condition ]]
in this example, as I do whenever possible.
I also changed `command`
to $(command)
, which also generally behaves similarly, but is nicer with nested commands.
pushd
, popd
, and dirs
are shell builtins which allow you manipulate the directory stack. This can be used to change directories but return to the directory from which you came.
For example
start up with the following directories:
$ pwd
/home/saml/somedir
$ ls
dir1 dir2 dir3
pushd to dir1
$ pushd dir1
~/somedir/dir1 ~/somedir
$ dirs
~/somedir/dir1 ~/somedir
dirs
command confirms that we have 2 directories on the stack now. dir1
and the original dir, somedir
. NOTE: Our "current" directory is ~/somedir/dir1
.
pushd to ../dir3 (because we're inside dir1
now)
$ pushd ../dir3
~/somedir/dir3 ~/somedir/dir1 ~/somedir
$ dirs
~/somedir/dir3 ~/somedir/dir1 ~/somedir
$ pwd
/home/saml/somedir/dir3
dirs
shows we have 3 directories in the stack now. dir3
, dir1
, and somedir
. Notice the direction. Every new directory is getting added to the left. When we start popping directories off, they'll come from the left as well.
manually change directories to ../dir2
$ cd ../dir2
$ pwd
/home/saml/somedir/dir2
$ dirs
~/somedir/dir2 ~/somedir/dir1 ~/somedir
Now start popping directories
$ popd
~/somedir/dir1 ~/somedir
$ pwd
/home/saml/somedir/dir1
Notice we popped back to dir1
.
Pop again...
$ popd
~/somedir
$ pwd
/home/saml/somedir
And we're back where we started, somedir
.
Might get a little confusing, but the head of the stack is the directory that you're currently in. Hence when we get back to somedir
, even though dirs
shows this:
$ dirs
~/somedir
Our stack is in fact empty.
$ popd
bash: popd: directory stack empty
Best Answer
Because that's the definition for those operands. From POSIX test documentation, OPERANDS section:
==
is not defined by POSIX, it's an extension ofbash
, derived fromksh
. You shouldn't use==
when you want portability. From bash documentation - Bash Conditional Expressions: