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 06:08:00 +0900

    text1=${text/'\'/'\\\\'}
2021年5月21日(金) 0:09 Christoph Anton Mitterer <calestyo@scientia.net>:
> I tried to first quote all \ with 's/\\/\\\\/g;'
> Next all $ with something like this 's/\$/\\\$/g'

If we use `sed', we need to further escape backslashes in the
replacement because there are another unescaping by `sed'.
s=${s//'\'/'\\\\'} is equivalent to 's/\\/\\\\\\\\/g'.
s=${s//'$'/'\\$'} is equivalent to 's/\$/\\\\$/g'.

> But the problem then always seems to be the special meaning of \$ in
> PS1:
> It doesn't seem to be possible to escape $.
> - $ alone might get used with promptvars.
> - \$ is $ or #
> - \\$ gives \$

At least in my environments, \\$ is always $ with `promptvar' turned
on, and \$ with `promptvar' turned off.

# shopt -p promptvars
shopt -s promptvars
# PS1='$(echo) '
 PS1='\$(echo) '
#(echo) PS1='\\$(echo) '
$(echo)

> So the only safe way seems to be to always put arbitrary strings in a
> tmp var.
>
> Which of course has the unpleasant drawbacks of
> a) needing such a var in the environment, which may be overrwritten by
> anything execute in the shell environment.

If you worry that the variable may be overwritten, you can use a long
variable name that will never be used by something other. Maybe
something like

_prompt_text1__never_overwrite_this_variable='text...'

> b) looking ugly if somone switches off promptvars
>
> Or does anyone else have an idea?

You can use PRMOPT_COMMAND (though it is still a variable which might
be overwritten by something other). For example,

PROMPT_COMMAND="set_up_prompt;$PROMPT_COMMAND"
set_up_prompt() {
  local text1='text...'
  if shopt -q promptvars; then
    text1=${text1//'\'/'\\\\'}
    text1=${text1//'$'/'\\$'}
    text1=${text1//'`'/'\\`'}
  else
    text1=${text1//'\'/'\\'}
  fi
  PS1=$text1'\$ '
}

--
Koichi



reply via email to

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