When I write multi-line statements in interactive mode in Zsh, it will prefix my statements with the block type I'm in like so:

% for i in $(seq 3); do
for> echo $i
for> done
% function foo() {
function> echo bar
function> }
% foo

I prefer not to see for> and function> and other code block prefixes. I'm not even sure what these prefixes are called to adequately search for how to suppress them. Bash does this too with just the > character, but I've not had luck figuring it out from that route. Is there a way to disable these in Zsh?


Turns out the default $PS2 value in Zsh is PS2=%_>, for anyone that comes across this via a search engine someday. From the docs:


The status of the parser, i.e. the shell constructs (like ‘if’ and ‘for’) that have been started on the command line. If given an integer number that many strings will be printed; zero or negative or no integer means print as many as there are. This is most useful in prompts PS2 for continuation lines and PS4 for debugging with the XTRACE option; in the latter case it will also work non-interactively.

Based on the accepted answer, I wound up with my PS2 set like this, which adds a 2 space indent to each block, and accounts for an initial 2 spaces to align with my PS1 length:

PS2='${${${(%):-%_}//[^ ]}// /  }    '

1 Answer 1


This is the secondary prompt, configured through the variable PS2, in all Bourne-style shells including zsh. In zsh, it defaults to showing which shell constructs (loops, quotes, etc.) are open, using the %_ prompt escape. In bash, it defaults to > and you can use escape sequences but they aren't very useful.

If you don't want any secondary prompt, make it empty:


With the prompt_subst option turned on, you can make it have one space per level of nesting, which gives some visual feedback but makes it possible to copy the code from the terminal.

setopt prompt_subst
PS2='${${(%):-%_}//[^ ]} '
  • %_ does indeed contain the status of the parser, which was in the docs, but just not something my searches turned up. This works perfectly, thank you.
    – mattmc3
    Jan 9 at 19:05
  • For copy-pastable code, you can also do things like set -o transientrprompt; PS2= RPS2='%F{blue}%^%f' Jan 10 at 6:42
  • The leading spaces in your approach would still cause problem with multiline quotes or here-docs. Jan 10 at 6:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.