test
test evaluates a single condition and reports whether it is true or false. It prints nothing — the answer is its exit status: 0 for true, 1 for false. That makes it the command a shell's if, while, &&, and || are built on.
test expression
[ expression ]
The two forms are the same command. [ is test under another name; when invoked as [, it requires a closing ] as its last argument. [ -f notes.txt ] and test -f notes.txt are identical.
$ test -f notes.txt && echo "the file exists"
File tests #
Existence and type #
| Test | True when the file… |
|---|---|
-e FILE | exists. |
-f FILE | exists and is a regular file. |
-d FILE | exists and is a directory. |
-L FILE, -h FILE | exists and is a symbolic link. |
-p FILE | exists and is a named pipe (FIFO). |
-S FILE | exists and is a socket. |
-b FILE | exists and is a block device. |
-c FILE | exists and is a character device. |
-s FILE | exists and is not empty. |
Access #
These three tests ask whether you may actually use the file:
| Test | True when… |
|---|---|
-r FILE | you may read the file. |
-w FILE | you may write the file. |
-x FILE | you may execute the file, or search the directory. |
On Peios these are real access checks. test asks the kernel whether your token is granted the right in question — a live check against the file's security descriptor, the same decision any actual read, write, or execute would face. The answer is therefore honest: test -w FILE is true exactly when a write would be permitted.
-x on a regular file means "you are permitted to execute it" — which is a different question from whether the file is an executable. A file can be runnable code and still fail -x for you, and the two are decided separately; see Access decisions.
Comparing two files #
| Test | True when… |
|---|---|
FILE1 -nt FILE2 | FILE1 is newer than FILE2. |
FILE1 -ot FILE2 | FILE1 is older than FILE2. |
FILE1 -ef FILE2 | both name the same file (same device and inode). |
Other file tests #
| Test | True when the file… |
|---|---|
-t FD | file descriptor FD is open on a terminal. |
-N FILE | has been modified since it was last read. |
-O FILE, -G FILE | carries an owner-id / group-id field matching the caller's. |
-g FILE, -u FILE, -k FILE | has its set-group-id, set-user-id, or sticky inode bit set. |
The last two rows probe decorative inode fields. The Peios access model does not consult them — they are stored on the inode and reported for completeness, but they carry no authority. For a true picture of what may be done to a file, use the access tests -r, -w, -x above, not -O, -g, or -u.
String tests #
| Test | True when… |
|---|---|
-n STRING | STRING is not empty. A bare STRING means the same. |
-z STRING | STRING is empty. |
STRING1 = STRING2 | the strings are equal. |
STRING1 != STRING2 | the strings are unequal. |
STRING1 < STRING2 | STRING1 sorts before STRING2. |
STRING1 > STRING2 | STRING1 sorts after STRING2. |
Integer comparisons #
| Test | True when… |
|---|---|
A -eq B | A equals B. |
A -ne B | A does not equal B. |
A -lt B | A is less than B. |
A -le B | A is less than or equal to B. |
A -gt B | A is greater than B. |
A -ge B | A is greater than or equal to B. |
Combining conditions #
| Form | Result |
|---|---|
! EXPRESSION | The negation. |
( EXPRESSION ) | Grouping — escape the parentheses so the shell does not take them. |
EXPR1 -a EXPR2 | True when both are true. |
EXPR1 -o EXPR2 | True when either is true. |
-a and -o are genuinely ambiguous to parse and are best avoided. Combine separate test calls with the shell's own && and || instead:
test -f notes.txt && test -r notes.txt
A note on shells #
Many command shells provide their own built-in test and [, and the shell's version is what runs when you type test at a prompt or in a script. A built-in may not behave as described here — in particular, the access tests -r, -w, and -x are the real access checks described above only when this command runs. To be certain you are running this command rather than the shell built-in, invoke it by its full path.
Exit status #
| Code | Meaning |
|---|---|
0 | The expression was true. |
1 | The expression was false. |
2 | The expression was malformed. |