2

Example:

  • When I run

    echo -e "\[\033[;33m\][\t \u (\#th) | \w]$\[\033[0m\]"
    

    the printed response is

    \[\][    \u (\#th) | \w]$\[\]
    

    where everything after the first \[ and before the last \] is an orangey-brown.

  • However when I set the command prompt to

    \[\033[;33m\][\t \u (\#th) | \w]$\[\033[0m\]
    

    the command prompt is printed as

    [21:55:17 {username} (89th) | {current directory path}]$
    

    were the whole command prompt is the orangy-brown.

In conclusion, my question is: Can I have a command prompt design printed (with echo, cat, less, etc.) as if it were the command prompt?

3
  • 1
    No, but you can replace \u with ${USER}, \w with ${PWD} etc. The escape sequences for changing colours work in any ANSI terminal. Jul 27 at 13:40
  • 1
    Escape codes will work, because they're processed by the terminal emulator Other things, like \t, \u, \w won't because they have different meanings outside of the PS1 variable. (e.g. \t usually means a tab, or just a backslash-escaped literal t. It's only in a prompt variable like PS1 that it means the current time in HH:MM:SS format)
    – cas
    Jul 27 at 14:06
  • OP asked the same question on superuser.com/questions/1664971/…. Jul 27 at 19:37
6

In Bash 4.4+, you can use ${var@P}, similarly to how ${var@Q} produces the contents of var quoted, see 3.5.3 Shell Parameter Expansion in the manual, bottom of page.

$ printf "%s\n" "${var}" 
\[\033[00;32m\]\w\[\033[00m\]\$
$ printf "%s\n" "${var@P}"  |od -tx1z
0000000 01 1b 5b 30 30 3b 33 32 6d 02 2f 74 6d 70 01 1b  >..[00;32m./tmp..<
0000020 5b 30 30 6d 02 24 0a                             >[00m.$.<
0000027

or if you run the latter without od, you should see the current path in green.

Note that it prints \001 and \002 for \[ and \]. Those probably aren't too useful for you. We could use a temporary variable and the string replace expansion to get rid of them:

$ printf -v pst "%s\n" "${var@P}" 
$ pst=${pst//[$'\001\002']}
$ printf "%s\n" "$pst" |od -tx1z
0000000 1b 5b 30 30 3b 33 32 6d 2f 74 6d 70 1b 5b 30 30  >.[00;32m/tmp.[00<
0000020 6d 24 0a 0a                                      >m$..<
0000024

In Zsh, there's print -P:

$ print -P "%F{green}%d%F{normal}%#" |od -tx1z
0000000 1b 5b 33 32 6d 2f 74 6d 70 2f 61 61 61 1b 5b 33  >.[32m/tmp/aaa.[3<
0000020 39 6d 25 0a                                      >9m%.<

and the parameter expansion flag %, so ${(%)var} would be similar to Bash's ${var@P} above, and you could use either print -v othervar -P "..." or othervar=${(%)var} to put the resulting string in othervar.


Note that for things like Bash's \u and \w, you could just use $USER and $PWD instead, but for something like \# or \j that might not be so easy.

3
  • 2
    In zsh, there's also the % parameter expansion flag (closer to bash's @P, though precedes it by decades). Jul 27 at 14:04
  • @StéphaneChazelas, I figured it had to be there, but for some reason just couldn't find it, thanks.
    – ilkkachu
    Jul 27 at 14:21
  • See also %% for full prompt expansion. You'd need print -rPv othervar -- $var for a closer equivalent. Jul 27 at 14:24

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.