In this lesson, you will learn why Linux exit statuses are restricted to a specific numerical range and how that limitation forces us to treat them as bitmasks.
The 0-255 Constraint
When a process finishes in Linux, it returns an exit status to its parent process. You might expect this to be a large integer, but due to historical design constraints in the Unix kernel, the exit status is stored in a single byte. This means the exit status can only be an integer from 0 to 255.
Because we only have 8 bits of information to report a process's outcome, we cannot pass complex objects or error strings. Instead, we use bitmask logic. We treat each of the 8 bits as a toggle for a specific condition.
Bitmasking in Action
Imagine you are writing a backup script. You want to report if the network failed (bit 0), the disk is full (bit 1), or a permission error occurred (bit 2). Instead of choosing one error, you can return a combination:
- Bit 0 (value 1): Network failed.
- Bit 1 (value 2): Disk full.
- Bit 2 (value 4): Permissions error.
If the network failed and the disk is full, you would return 1 + 2 = 3. In binary, this is 00000011.
# Example logic in your script
exit_code=0
(( network_fail )) && exit_code=$(( exit_code | 1 ))
(( disk_full )) && exit_code=$(( exit_code | 2 ))
exit $exit_code
Checking the Bits
When the parent script receives that 3, it doesn't just check if [ $? -eq 3 ]. It uses the bitwise & (AND) operator to inspect individual flags:
# In the parent script
if (( ($? & 2) != 0 )); then
echo "Alert: Disk is full!"
fi
By using bitwise operators, the parent can independently verify multiple error conditions bundled into one byte. If you try to exit with a number like 256, the shell will perform a modulo operation (256 % 256), resulting in 0—essentially lying to the parent process that everything went perfectly!
Key Takeaway: Since exit statuses are limited to 8 bits (0-255), we use bitwise arithmetic to pack multiple status flags into a single integer return value.