7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【bash】if (testコマンド) の`-a`, `-e`オプションの違い

Posted at

はじめに

help testコマンドによると、「ファイルが存在するか」を判定するオプションは、以下の 2 種類がありました。
今回は、この 2 つのオプションの挙動の違いを調べてみました。

-a FILE True if file exists.
-e FILE True if file exists.

`help test` 出力結果全文
help test
# test: test [expr]
#     Evaluate conditional expression.

#     Exits with a status of 0 (true) or 1 (false) depending on
#     the evaluation of EXPR.  Expressions may be unary or binary.  Unary
#     expressions are often used to examine the status of a file.  There
#     are string operators and numeric comparison operators as well.

#     The behavior of test depends on the number of arguments.  Read the
#     bash manual page for the complete specification.

#     File operators:

#       -a FILE        True if file exists.
#       -b FILE        True if file is block special.
#       -c FILE        True if file is character special.
#       -d FILE        True if file is a directory.
#       -e FILE        True if file exists.
#       -f FILE        True if file exists and is a regular file.
#       -g FILE        True if file is set-group-id.
#       -h FILE        True if file is a symbolic link.
#       -L FILE        True if file is a symbolic link.
#       -k FILE        True if file has its `sticky' bit set.
#       -p FILE        True if file is a named pipe.
#       -r FILE        True if file is readable by you.
#       -s FILE        True if file exists and is not empty.
#       -S FILE        True if file is a socket.
#       -t FD          True if FD is opened on a terminal.
#       -u FILE        True if the file is set-user-id.
#       -w FILE        True if the file is writable by you.
#       -x FILE        True if the file is executable by you.
#       -O FILE        True if the file is effectively owned by you.
#       -G FILE        True if the file is effectively owned by your group.
#       -N FILE        True if the file has been modified since it was last read.

#       FILE1 -nt FILE2  True if file1 is newer than file2 (according to
#                        modification date).

#       FILE1 -ot FILE2  True if file1 is older than file2.

#       FILE1 -ef FILE2  True if file1 is a hard link to file2.

#     All file operators except -h and -L are acting on the target of a symbolic
#     link, not on the symlink itself, if FILE is a symbolic link.

#     String operators:

#       -z STRING      True if string is empty.

#       -n STRING
#          STRING      True if string is not empty.

#       STRING1 = STRING2
#                      True if the strings are equal.
#       STRING1 != STRING2
#                      True if the strings are not equal.
#       STRING1 < STRING2
#                      True if STRING1 sorts before STRING2 lexicographically.
#       STRING1 > STRING2
#                      True if STRING1 sorts after STRING2 lexicographically.

#     Other operators:

#       -o OPTION      True if the shell option OPTION is enabled.
#       -v VAR     True if the shell variable VAR is set
#       -R VAR     True if the shell variable VAR is set and is a name reference.
#       ! EXPR         True if expr is false.
#       EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
#       EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.

#       arg1 OP arg2   Arithmetic tests.  OP is one of -eq, -ne,
#                      -lt, -le, -gt, or -ge.

#     Arithmetic binary operators return true if ARG1 is equal, not-equal,
#     less-than, less-than-or-equal, greater-than, or greater-than-or-equal
#     than ARG2.

#     See the bash manual page bash(1) for the handling of parameters (i.e.
#     missing parameters).

#     Exit Status:
#     Returns success if EXPR evaluates to true; fails if EXPR evaluates to
#     false or an invalid argument is given.

結論

File test operatorsによると、ファイル演算子の-aは非推奨(deprecated)なため、-eを使った方が良さそうです。
(man test, info testの結果にはファイル演算子として-aはありませんでした)

実際、-aオプションは二項演算子としても使われるため、混同すると非常にややこしくなります。

挙動の違い

# 準備
touch foo.txt

通常

これには違い無し。

[ -a foo.txt ] && echo 'True' || echo 'False'
# True
[ -e foo.txt ] && echo 'True' || echo 'False'
# True

反転

!で反転させると、違いが分かります。

[ ! -a foo.txt ] && echo 'True' || echo 'False'
# True
[ ! -e foo.txt ] && echo 'True' || echo 'False'
# False

-aの場合、Falseにならず、Trueになります。
[ ! -a foo.txt ]-aが、ファイル演算子ではなく二項演算子として使われているためです。
! AND foo.txt という意味。
※test コマンドはexit 0を返せばTrueなので、!foo.txtTrue扱い。

参考

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?