0

I'm trying to understand a sed command shown on ETA Lab's Rich’s sh (POSIX shell) tricks page, specifically in the trick Shell-quoting arbitrary strings:

quote () { printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/" ; }

In the third sed command (\$s/\$/'/), I understand the first $ is escaped to prevent the shell to interpret it as a hypothetical $s variable, so it can be passed to sed and be rightfully interpreted as the last line address for the s command, but why escape the second $ ? Shouldn't it correctly match the end of the line as-is ?

7
  • 2
    probably because the dollar is special in double quotes, and escaping it is good hygiene. Then you don't need to think which ones of !#%&/?_- etc. require you to escape the preceding dollar, and if e.g. $/ was only an existing special variable in Perl, or in the shell too... What if some future shell decided to add that as a non-standard special parameter?
    – ilkkachu
    Mar 2 at 21:38
  • That sed command is unnecessarily complicated by escapes due to using double quotes instead of single quotes around the whole script instead of just using '\'' or \047 or \27 or similar for the single quotes inside the script. Similarly for the printf formatting string - instead of having it unqupoted and requiring doubling uyp on escapes, printf %s\\n "$1" just quote it - printf '%s\n' "$1"
    – Ed Morton
    Mar 3 at 16:40
  • 1
    That whole script is also redundant given printf '%q\n' "$1" or printf '%s\n' "${1@Q}" if your shell supports those constructs.
    – Ed Morton
    Mar 3 at 16:59
  • 1
    @EdMorton "If your shell supports those constructs"... I think you didn't understand that the whole point of this page is to use only POSIX shell. printf '%q\n' or ${1@Q} are not POSIX.
    – MoonSweep
    Mar 4 at 0:09
  • @MoonSweep I did understand that this questions was asking about a web site that is about POSIX sh, but that doesn't mean everyone reading this NEEDS to only know about POSIX constructs and can't learn about better alternatives which is why I said If your shell supports those constructs.
    – Ed Morton
    Mar 4 at 0:10

1 Answer 1

1

You only need to escape the $ at the end of a regular expressions in an sed command to make it literal instead of being the end of the line.

Your sed command does not have any escaped $, because the backslashes are eaten by the shell. The command as it is seen by sed is just $s/$/'/ (in the last line, add a single quote to the end of the line).

So in the end, the title of your question is wrong: It's about shell escaping, not sed escaping.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.