These docs are under active development and cover the v0.20 Kobicha security model.
On this page
reference 4 min read

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

Exit status

Code Meaning
0 The expression was true.
1 The expression was false.
2 The expression was malformed.