help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: how to (safely) escape an arbitrary string for use in PS1


From: Koichi Murase
Subject: Re: how to (safely) escape an arbitrary string for use in PS1
Date: Fri, 21 May 2021 07:44:21 +0900

2021年5月21日(金) 6:41 Christoph Anton Mitterer <calestyo@scientia.net>:
> starting with PS1='$ '
> $ PS1='\ '   ===> clear, "\ " has no special meaning to bash
> \ PS1='\\ '  ===> clear, too, \\ yields \
> \ PS1='\\\ '
>              ===> don't understand I'd have expected that e.g. '\\\ ' gives 
> '\\ '
>                   i.e. the first '\\' give one '\' and then a sole '\ ' 
> remains
> \ PS1='\\\\ '
> \ PS1='\\\\\ ' => why does it take 5 \ to get double \\
> \\

As I have mentioned, there are two unescaping. The first processing is
\u to usernames, \$ to # or $, \\ to \, etc. The second processing
(promptvars) includes \\ to \, \$ to $, \` to `, and \" to " as well
as expansions of ${}, $(), $(()). You can understand it step-by-step.

PS1='\ ' -> '\ ' -> '\ '
PS1='\\ ' -> '\ ' -> '\ '
PS1='\\\ ' -> '\\ ' → '\ '
PS1='\\\\ ' → '\\ ' → '\ '
PS1='\\\\\ ' → '\\\ ' → '\\ '

> Similarly with '$' (as root here):
> PS1='$ '
> $ PS1='\$ '
> # PS1='\\$ '
> $ PS1='\\\$ '
> \# PS1='\\\\$ '
> \$ PS1='\\\\\$ '
> \# PS1='\\\\\\$ '
> \$ PS1='\\\\\\\$ '

This is also the same:

PS1='$ ' -> '$ ' -> '$ '
PS1='\$ ' -> '# ' -> '# '
PS1='\\$ ' -> '\$ ' -> '$ '
PS1='\\\$ ' -> '\# ' -> '# '
PS1='\\\\$ ' -> '\\$ ' -> '\$ '
PS1='\\\\\$ ' -> '\\# ' -> '\# '
PS1='\\\\\\$ ' -> '\\\$ ' -> '\$ '
PS1='\\\\\\\$ ' -> '\\\# ' -> '\# '

> btw:
> The following lets bash go into an endless loop (Ctrl-C doesn't help):
> export bar='\h $(echo \$(date))' ; qbar="$(printf '%s' "$bar" | sed 
> 's/\\/\\\\/g; s/\$/\\\\\\\\$/g')"; printf '%s\n%s\n' "$bar" "$qbar" ; 
> PS1="$qbar \$ "

Oh, I think this is a bug of Bash 5.1. I could reproduce it with bash
5.1, but not with bash 5.0. It seems it is already fixed in the devel
branch. The minimal reproducer is:

PS1='$(\\$()) '

2021年5月21日(金) 7:04 Christoph Anton Mitterer <calestyo@scientia.net>:
> On Fri, 2021-05-21 at 06:08 +0900, Koichi Murase wrote:
> > At least in my environments, \\$ is always $ with `promptvar' turned
> > on, and \$ with `promptvar' turned off.
> That's strange btw,... cause promptvars shouldn't affect \$, AFAIU.

It does affect \$ because we want a way to represent literal '$' when
we process ${}, $(), etc.

> (And I don't see this behaviour in my bash.)

Hmm, how did you check that? For example, what is the result of the
following commands?

$ PS1='\\$ '
$ shopt -u promptvars
\$

--
Koichi



reply via email to

[Prev in Thread] Current Thread [Next in Thread]