How can I see the verbatim contents of a shell variable?

How can I see the verbatim contents of a shell variable?

I want to view the verbatim contents of a shell variable on Debian containing terminal escape codes. If I try to echo its contents, then all of the terminal escape gets interpreted by the terminal to e.g. display colours.

➜  sds git:(master) echo $PS1
%(?:%{%}➜ :%{%}➜ ) %{$fg[cyan]%}%c%{$reset_color%} $(git_prompt_info)

Is it possible to print the verbatim contents of a shell variable, or do I need to find the exact script that sets it in order to view its verbatim contents?

答案1

As terdon says, you can’t get back the original construction of the variable if it was constructed using the values of other variables.

However you can see its contents, uninterpreted by the terminal or even by the shell itself, in at least Bash and Zsh:

printf '%q\n' "$PS1"

This will escape all the characters which would otherwise have a different effect; you can use this to reconstruct the verbatim contents.

Another approach is to output the variable’s contents to somewhere other than the terminal (directly); for example

printf %s "$PS1" | od -vtc

will show the variable’s contents, character by character, replacing control characters with a mnemonic (nl, esc, sp...).

Do not use echo here which expands \x sequences and adds an extra newline character.

In your case,

%(?:%{%}➜ :%{%}➜ ) %{$fg[cyan]%}%c%{$reset_color%} $(git_prompt_info)

looks like it could be exactly the verbatim contents of your PS1 variable: there are no terminal-interpreted escapes there, those are indirectly obtained through the fg array and reset_color variable. Assuming the promptsubst option is set, those would be expanded when PS1 is used to display the prompt, but not when echo $PS1 is expanded.

答案2

The contents of the variable include the expanded values of any variables you are using. You cannot get back to the original because the original is only used to expand the values.

For example, consider this:

fooVar="foo"
barVar="$fooVar : bar"

By the time the shell sets barVar, it has already expanded $foovar. It isn't setting barVar to $fooVar : bar, it is setting it to foo : bar. There is no way of getting back to "$fooVar : bar", the $vooVar variable was expanded before being assigned as a value to the new barVar variable. That's the whole point of using variables, after all: that they can be treated as their value.

So no, there is no way of getting the genie back in the bottle and "unexpanding" variables you have already expanded and used. The only way to see what variables were used to form your PS1 is to track down the various files where it is being set.

相关内容