help-bash
[Top][All Lists]
Advanced

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

Re: `printf %q` but more human readable


From: Alex fxmbsw7 Ratchev
Subject: Re: `printf %q` but more human readable
Date: Sun, 14 Mar 2021 10:06:23 +0100

try ${var@Q}

On Sun, Mar 14, 2021 at 6:52 AM Peng Yu <pengyu.ut@gmail.com> wrote:

> Hi,
>
> I want to have something similar to `printf %q` but the result should
> be more human-readable. I come up with the following code. Here is one
> example to show that the result of printfbq is more human-readable
> than `printf %q`. The idea is to reduce the use of backslashes
> whenever possible. But human-readablilty may be a subjective matter.
> So different people might have slightly different definitions.
>
> $ printfbq "$x"
> "while true; do echo 'bash -i >& /dev/tcp/127.0.0.1/4444 0>&1' | bash;
> sleep 5; done &"
> $ printf '%q\n' "$x"
> while\ true\;\ do\ echo\ \'bash\ -i\ \>\&\ /dev/tcp/127.0.0.1/4444\
> <http://127.0.0.1/4444%5C>
> 0\>\&1\'\ \|\ bash\;\ sleep\ 5\;\ done\ \&
>
> The code is listed below.
>
> I think that there may be corner cases in which my code may not do
> well. But I am not sure what those corner cases are.
>
> Does anybody have a better way to make something equivalent to `printf
> %q` but more human-readable against all possible cases?
>
> function printfbq/dqoute_esc_dquote_dollar_bslash {
>     __printfbq__dqoute_esc_dquote_dollar_bslash__r=${1//z/z0}
>
> __printfbq__dqoute_esc_dquote_dollar_bslash__r=${__printfbq__dqoute_esc_dquote_dollar_bslash__r//'\'/z1}
>
> __printfbq__dqoute_esc_dquote_dollar_bslash__r=${__printfbq__dqoute_esc_dquote_dollar_bslash__r//'"'/'\"'}
>
> __printfbq__dqoute_esc_dquote_dollar_bslash__r=${__printfbq__dqoute_esc_dquote_dollar_bslash__r//$/'\$'}
>
> __printfbq__dqoute_esc_dquote_dollar_bslash__r=${__printfbq__dqoute_esc_dquote_dollar_bslash__r//z1/'\\'}
>
> __printfbq__dqoute_esc_dquote_dollar_bslash__r="\"${__printfbq__dqoute_esc_dquote_dollar_bslash__r//z0/z}\""
> }
>
> function printfbq/esc_char {
>     __printfbq__esc_char__r=${1//z/z0}
>     __printfbq__esc_char__r=${__printfbq__esc_char__r//$'\a'/z1}
>     __printfbq__esc_char__r=${__printfbq__esc_char__r//$'\E'/$'\a'}
>     builtin printf -v __printfbq__esc_char__r %q "$__printfbq__esc_char__r"
>     __printfbq__esc_char__r=${__printfbq__esc_char__r//'\a'/'\e'}
>     __printfbq__esc_char__r=${__printfbq__esc_char__r//z1/'\a'}
>     __printfbq__esc_char__r=${__printfbq__esc_char__r//z0/z}
> }
>
> function printfbq/squote_esc_squote {
>     builtin printf -v __printfbq__squote_esc_squote__r "'%s'"
> "${1//"'"/"'\"'\"'"}"
>
> __printfbq__squote_esc_squote__r=${__printfbq__squote_esc_squote__r#\'\'}
>
> __printfbq__squote_esc_squote__r=${__printfbq__squote_esc_squote__r%\'\'}
> }
>
>     function printfbq {
>         declare __printfbq__r
>         if [[ -z $1 ]]; then # empty string
>             builtin printf -v __printfbq__r %q "$1"
>         elif [[ $1 = *$'\E'* ]]; then # contains the escape character
>             declare __printfbq__esc_char__r
>             "$FUNCNAME"/esc_char "$1"
>             __printfbq__r=$__printfbq__esc_char__r
>         elif [[ $1 =~ [^[:print:]] ]]; then # contains any other
> non-print characters
>             builtin printf -v __printfbq__r %q "$1"
>         elif [[ $1 = *\'* ]]; then
>             if [[ $1 =~ [$\"\\] ]]; then
>                 declare __printfbq__squote_esc_squote__r
> __printfbq__dqoute_esc_dquote_dollar_bslash__r
>                 "$FUNCNAME"/squote_esc_squote "$1"
>                 "$FUNCNAME"/dqoute_esc_dquote_dollar_bslash "$1"
>                 if
>
> ((${#__printfbq__squote_esc_squote__r}<${#__printfbq__dqoute_esc_dquote_dollar_bslash__r}));
> then
>                     __printfbq__r=$__printfbq__squote_esc_squote__r
>                 else
>
> __printfbq__r=$__printfbq__dqoute_esc_dquote_dollar_bslash__r
>                 fi
>             else
>                 builtin printf -v __printfbq__r '"%s"' "$1"
>             fi
>         elif [[ $1 =~ [][\ !\"#$\&()*,\;\<\>?\\^\`{|}~] ]]; then
>             builtin printf -v __printfbq__r "'%s'" "$1"
>         else
>             __printfbq__r=$1
>         fi
>
>         builtin printf '%s\n' "$__printfbq__r"
>     }
>
> The testing code covering all branches is listed below.
>
> $   # empty
> $   printfbq ''
> ''
>
> $   # escchar
> $   printfbq $'a\e\'$'
> $'a\e\'$'
> $
> $   # nonprint
> $   printfbq $'\001\a"'\'$'\001\a'
> $'\001\a"\'\001\a'
>
> $   # squote/escape_in_dquote
> $   printfbq "'\"\"\"\"'"
> "'\"\"\"\"'"
> $   printfbq "'\"\"\"\"\"'"
> "'"'"""""'"'"
>
> $   # squote/nonescape_in_dquote
> $   printfbq "|'"
> "|'"
>
> $ # nosquote/need_squote
> $   printfbq '#'
> '#'
>
> $   # nosquote/noneed_squote
> $   printfbq a
> a
>
> --
> Regards,
> Peng
>
>


reply via email to

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