Bash. Quoting

in voilk •  3 months ago


    image.svg
    Free Software Foundation, FAL, via Wikimedia Commons




    Para el intérprete de la shell existen una serie de caracteres que, en determinado contexto, poseen un significado especial.

    $ echo $25
    5
    Es deseable un mecanismo que permita despojar a los caracteres especiales de su representación específica, este mecanismo es el quoting.

    Bash facilita tres formatos de quoting,

    – Comillas simples ('...')
    – Comillas dobles (“...”)
    – Contrabarra (\)

    Contrabarra


    Protege el siguiente carácter de toda interpretación, excepto si se trata
    del carácter de control 'nueva línea'(\n), en este caso el carácter de
    control desaparece por completo.

    $ echo \$25
    $25

    La contrabarra puede utilizarse, en el interior de un script, para hacer más
    sencillo de leer un comando que se extiende a lo largo de más de una línea,
    ya que los caracteres 'nueva línea' protegidos por la contrabarra no son
    visibles para el intérprete de la shell.

    Comillas simples


    Protegen todos los caracteres incluidos entre las mismas excepto el
    carácter de comilla simple (').

    $ echo '$45 $35 $25 $15'
    $45 $35 $25 $15
    $ echo \$45 \$35 \$25 \$15
    $45 $35 $25 $15
    Funcionan igual que la contrabarra, en realidad son un atajo conveniente que nos evita tener que escribir varias contrabarras, exceptuando que el carácter de 'nueva línea' no se trata de forma especial.
    $ echo '$45 $35^V^J
    $25 $15'
    $45 $35
    $25 $15
    Para insertar una nueva línea es necesario introducir la secuencia ^V^J.

    Comillas dobles


    Protegen todos los caracteres incluidos entre las mismas excepto el
    carácter de comilla doble (“), con la salvedad de que las expansiones que
    realiza la shell tienen lugar de la forma habitual.

    $ echo “$25”
    5

    Mezclando formatos


    Dado que disponemos de tres formatos para aplicar el quoting, vamos a ver
    que ocurre si usamos varios a la vez.

    En el interior de las comillas simples la contrabarra es un carácter más.

    En el interior de las comillas dobles se puede utilizar la contrabarra,

    $ echo “$45 $35 \
    $25 $15”
     5 5 5 5
    Entre comillas simples la comilla doble no tiene significado especial.

    Entre comillas dobles la comilla simple no tiene significado especial.

    Cuándo usar cada formato


    Si necesitamos que los caracteres no sean procesados en absoluto por la
    shell y se presenten 'tal cual', debemos utilizar la contrabarra o las
    comillas simples.

    Si deseamos hacer uso de las conversiones de la shell no queda otro remedio
    que utilizar comillas dobles, este formato de quoting es el más utilizado.

    En el improbable caso de que deseemos que el contenido se interprete como
    valores independientes separados por los caracteres definidos en la variable
    interna de la shell IFS, debemos omitir todo quoting.

    Casos comunes


    Whitespace : los caracteres definidos en IFS son interpretados como
    separadores de campo, de forma que son eliminados durante el proceso de
    interpretación, el uso más frecuente del quoting es preservar el whitespace.

    $ echo 1        2
    1 2
    $ echo “1        2”
    1        2
    $ echo '1        2'
    1        2

    Acceso a variables : las variables se entrecomillan con comillas dobles cuando
    se accede a su valor.
    La culpa, de la variable IFS. Dado que una variable puede contener
    whitespace, la única forma de protegerlo de la interpretación por parte de la
    shell es haciendo uso de alguna forma de quoting, ya que se trata del acceso
    al valor de una variable la única opción es utilizar las comillas dobles.

    $ CADENA='a b c'
    $ [ $CADENA = 'a b c' ]
    bash: [: demasiados argumentos
    $ [ “$CADENA” = 'a b c' ]
    $ echo $?
    0
    Hay que tener en cuenta que una variable puede estar definida pero no tener asignado valor alguno, o incluso puede no estar definida, un script robusto ha de ser capaz de manejar estas situaciones sin generar un error fatal o finalizar su ejecución.
    $ CADENA=
    $ [ $CADENA = 'a b c' ]
    bash: [: =: se esperaba un operador unario
    $ [ “$CADENA” = 'a b c' ]
    $ echo $?
    1
    Una notable excepción, a esta regla de uso general, es el caso en el que la variable contiene una expresión de tipo fichero, sobre la que la shell realizará globbing; en este caso todo quoting es totalmente innecesario,
    $ FOTOS=*.png
    $ echo “$FOTOS”
    *.png
    $ echo $FOTOS
    wallpaper.png image.png
    Asignación de variables : Al asignar una variable no es necesario proteger el valor asignado, salvo que contenga whitespace de forma explícita,
    $ FOTOS=*.png
    $ echo “$FOTOS”
    *.png
    $ UNO=1
    $ echo $UNO
    1
    $ ONCE=$UNO$UNO
    $ echo $ONCE
    11
    $ UNOS=”$1 $1”
    $ echo “$UNOS”
    1 1
    $ UNOS='1 1'
    $ echo “$UNOS”
    1 1
    for..in : Este bucle permite iterar sobre los múltiples valores de una variable, por lo tanto no tiene sentido proteger estos valores, ya que entonces los despojamos de su multiplicidad,
    $ FOTOS=*.png; FOTOS=$(echo $FOTOS)
    $ for FICHERO in “$FOTOS”; do echo “$FICHERO” ; done
    wallpaper.png image.png
    $ for FICHERO in $FOTOS; do echo “$FICHERO” ; done
    wallpaper.png
    image.png
    En el caso de que se acceda a los elementos de un array, es recomendable utilizar comillas dobles para de esta forma proteger el posible whitespace que éstos puedan contener.
    $ BEBIDAS=(café leche 'café con leche')
    $ for BEBIDA in ${BEBIDAS[@]}; do echo “$BEBIDA” ; done
    café
    leche
    café
    con
    leche
    $ for BEBIDA in "${BEBIDAS[@]}"; do echo “$BEBIDA” ; done
    café
    leche
    café con leche
    case : Bash espera un único valor sobre el que realizar la comparación, así que no es necesario el quoting, ya que no tiene efecto,
    $ FOTOS=*.jpg
    $ FOTOS=$(echo $FOTOS)
    $ case $FOTOS in \*.jpg) echo Ningún archivo de \
    tipo JPG. ;; esac
    Ningún archivo de tipo JPG.
    here document : Por defecto se efectúan expansiones de variable, para evitarlo hay que aplicar cualquiera de los formatos de quoting a la cadena que hace las veces de delimitador, no hay gobbling,
    $ FOTOS=
    $ cat > mis_fotos << EOF
    > FOTOS=*.png
    > echo $FOTOS
    > EOF
    $ cat mis_fotos
    FOTOS=*.png
    echo
    $ cat > mis_fotos << \EOF
    > FOTOS=*.png
    > echo $FOTOS
    > EOF
    $ cat mis_fotos
    FOTOS=*.png
    echo $FOTOS

    Este listado de casos de uso más o menos comunes no es ni mucho menos exhaustivo.

    Como se puede apreciar el quoting en Bash es un tema bastante complejo.

      Authors get paid when people like you upvote their post.
      If you enjoyed what you read here, create your account today and start earning FREE VOILK!