Search code examples
bashshellargv

Unexpected strings escape in process argv


Got kinda surprised with:

$ node -p 'process.argv' $SHELL '$SHELL' \t '\t' '\\t'
[ 'node', '/bin/bash', '$SHELL', 't', '\\t', '\\\\t' ]

$ python -c 'import sys; print sys.argv' $SHELL '$SHELL' \t '\t' '\\t'
['-c', '/bin/bash', '$SHELL', 't', '\\t', '\\\\t']

Expected the same behavior as with:

$ echo $SHELL '$SHELL' \t '\t' '\\t'
/bin/bash $SHELL t \t \\t

Which is how I need the stuff to be passed in.

Why the extra escape with '\t', '\\t' in process argv? Why handled differently than '$SHELL'? Where's this actually coming from? Why different from the echo behavior?

First I thought this to be some extras on the minimist part, but then got the same with both bare Node.js and Python. Might be missing something obvious here.


Solution

  • Use $'...' form to pass escape sequences like \t, \n, \r, \0 etc in BASH:

    python -c 'import sys; print sys.argv' $SHELL '$SHELL' \t $'\t' $'\\t'
    ['-c', '/bin/bash', '$SHELL', 't', '\t', '\\t']
    

    As per man bash:

    Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows:

    \a     alert (bell)
    \b     backspace
    \e
    \E     an escape character
    \f     form feed
    \n     new line
    \r     carriage return
    \t     horizontal tab
    \v     vertical tab
    \\     backslash
    \'     single quote
    \"     double quote
    \nnn   the eight-bit character whose value is the octal value nnn (one to three digits)
    \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
    \uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
    \UHHHHHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH  (one  to  eight  hex digits)
    \cx    a control-x character