1. Overview
Understanding the exit status codes of commands executed in the Zsh terminal is important for assessing the success or failure of each operation. These codes serve as indicators of whether a command ran successfully, with exit status 0, or encountered an error, represented by a non-zero exit status.
Knowing the exit status code is useful for troubleshooting, scripting, and ensuring our commands function as intended. However, Zsh doesn’t display the exit code of every command by default. This poses a challenge for users seeking real-time feedback on command execution outcomes.
In this tutorial, we’ll talk about different methods to address this challenge and print the exit status code of every command in the Zsh terminal. Through customizable prompts, error-trapping mechanisms, and function hooks, we can gain insights into command execution outcomes and streamline our workflow effectively.
2. Challenges of Printing Every Exit Code
Zsh doesn’t provide a built-in feature to automatically display the exit code after each command execution. Manually printing the exit code after every single command can clutter our terminal output. As a result, it could be cumbersome to track and interpret exit status codes, especially when dealing with a large number of commands or complex scripts.
Additionally, some methods might only display the exit code of the most recently executed command. While helpful, this doesn’t provide a complete picture if we need to track the exit codes of multiple commands in a sequence.
This lack of native functionality can hinder our ability to quickly identify errors, troubleshoot issues, and ensure the smooth execution of commands within our workflow. Without immediate feedback on command outcomes, we may encounter delays and inefficiencies in diagnosing problems.
This means we need to explore alternative methods to achieve this goal. Zsh offers several customizable solutions that enable us to overcome the limitations of its default behavior and gain better visibility into command execution outcomes.
3. Customizing the Zsh Prompt With %?
One of the most straightforward approaches to address the absence of automatic exit code printing in Zsh is by customizing the prompt using prompt expansion sequences. Zsh offers a versatile prompt customization feature, allowing us to dynamically modify command prompts.
By using the %? prompt expansion sequence in the prompt configuration of the PS1 variable, we can display the exit code of the last executed command directly in the terminal prompt. This sequence expands to the exit status of the previous command, providing immediate feedback on command execution outcomes.
Let’s see it in action:
% PS1='%n@%m:%~ [%?] %# '
user@hostname:~ [0] %
This sets up the Zsh prompt to display the exit code of the previous command, enclosed in brackets. We already get a 0 exit status because the customization was successful.
Let’s run a command that we know will fail:
user@hostname:~ [0] % ls fail_sure
ls: cannot access 'fail_sure.': No such file or directory
user@hostname:~ [2] %
Running ls on a non-existent file or directory results in an error, as expected. On the next line, we get the exit status code 2 confirming this.
Furthermore, the command can be tweaked to display different font weights or colors on the exit status for a more striking visual effect.
4. Capturing Failed Command Exit Codes With TRAPERR
An alternative approach is to use a TRAPERR() function to capture and handle errors occurring during command execution. It’s important to note that the TRAPERR() function behaves the same as TRAPZERR() on systems where there’s no SIGERR. This function is triggered whenever a command returns a non-zero exit status, indicating failure.
Let’s run the code:
% TRAPERR() print -u2 Exit status: $?
Whenever a command fails, the TRAPERR() function is called automatically. $? is a special variable in Zsh that holds the exit status of the last command executed.
Let’s invoke an error to test it:
% ls test
ls: cannot access 'test': No such file or directory
Exit status: 2
% lstest
zsh: command not found: lstest
Exit status: 127
In these two instances, we get the exact exit status code after each error message.
In summary, the TRAPERR() function in Zsh allows us to capture and handle errors gracefully. Using this function, we can print the exit status of failed commands. While useful for pinpointing errors during testing or debugging, it may not be ideal for use cases with numerous commands.
5. Print the Exit Status for Every Command
Alternatively, to print the exit status of every command executed in the Zsh terminal, we can utilize a custom precmd() function.
First, let’s assign a command to a PROMPT_COMMAND variable:
% PROMPT_COMMAND='printf "Exit code: %s\n" $?'
In this case, the PROMPT_COMMAND variable holds a command to be executed just before displaying each primary prompt. We’ve included a printf command that formats and prints text. It displays the string Exit code: followed by a placeholder for a string (%s) and then a newline (\n). Here, the printf command prints the exit status code, represented by the $? variable.
Afterwards, we can define the function:
% precmd() { eval "$PROMPT_COMMAND" }
Exit code: 0
Here, precmd()* is a special hook function that’s executed before displaying each primary prompt, *PS1.
So, when we execute this line, the precmd() hook evaluates the command stored in PROMPT_COMMAND just before displaying each primary prompt. This effectively prints the exit code of the previous command before each prompt.
Let’s run another command:
% cd Desktop
Exit code: 0
Next, let’s run an incorrect command:
% lstest
zsh: command not found: lstest
Exit code: 127
In both instances, the exit status code is displayed.
By integrating this information into the prompt, we get immediate feedback on command execution outcomes, allowing for faster error detection and troubleshooting.
6. Conclusion
In this article, we’ve explored various techniques to print the exit status code of every command in the Zsh terminal. Initially, we discussed the basics of customizing the Zsh prompt using the PS1 variable. We experimented with the %? escape sequence to display the exit status of the previous command in the prompt.
Additionally, we learned how to display the exit status codes of failed commands by defining custom functions like TRAPERR(). Finally, we explored how to print the exit status of every command before each prompt. In that instance, we made use of the precmd() hook function.
By combining these techniques, we can tailor Zsh prompts to provide insights into command execution, error handling, and system state. Subsequently, we can improve productivity and facilitate a more efficient command-line workflow.