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: Mon, 24 May 2021 11:48:49 +0900

2021年5月24日(月) 10:42 Christoph Anton Mitterer <calestyo@scientia.net>:
> > - Oh, this example is interesting. I guess [\$\`\'\"\] is treated as
> > [<quoted $`'"]> and "escaped" as [$`'"], but it's just a naive guess.
>
> Hmm then I'd have expected a syntax error, as the bracket expression
> isn't closed.

$ [[ 'a' =~ ['abc[]' ]]; echo $?
0
$ [[ ']' =~ ['abc[]'] ]]; echo $?
1

Hmm, these examples are counter-intuitive though I can guess what is
happening internally.

> > But actually, in this case, we can actually simply use the glob
> > pattern (operator ==) instead of regular expressions.
> >
> > if [[ $str == *[\$\`\'\"\\]* ]]; then
> > [...]
>
> As far as I understand, this is *not* affected by compat31, right?!

Right.

> It would be nice if something like the local keyword could be used for
> dot sourced files or things like when the shell loads .profile/.bashrc
> and friends.

Yeah. To use local variables, I think currently we need to define a
function inside the sourced files

funcion main {
  local xxxx

  [...]

}
main

Or we source the file in a function:

function local_source { source "$@"; }
local_source file.sh

A related discussion:
https://lists.gnu.org/archive/html/bug-bash/2014-05/msg00032.html

> I guess the following would be equivalent (while avoiding the "bashism"
> - which however doesn't really matter in my case, as I only target
> .bashrc, which is anyway just bash):
>
> [ -n "${str##*[\$\`\'\"\\]*}"  -o  -z "${str}" ] && echo "NO evil char" || 
> echo "evil char"
> or
> [ -n "${str##*["$`'\"\\"]*}"  -o  -z "${str}" ] && echo "NO evil char" || 
> echo "evil char"

$ case $str in *[\$\`\'\"\\]*) echo "NO evil char" ;; *) echo "evil
char" ;; esac

is the POSIX way. Also, "-o" is obsoleted in POSIX.

> Hmm I was thinking about including ' and " because the manpage says:
> > After the string is decoded, it is  expanded  via  parameter
> > expansion, command substitution, arithmetic expansion,
> > and quote removal
>
> But I guess this applies only to the outer quotes of e.g.
> PS1="...${str}..."
> and not to the content of str, right?

Right.

> So - correct me if I'm wrong - ultimately it would boil down to your:
>    if [[ $str == *['$`\']* ]]; then
> respectively
>    if [ -n "${str##*['$`\']*}"  -o  -z "${str}" ]; then

I think this is fine.

--
Koichi



reply via email to

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