Bash. Quoting

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.




Media Free Software Foundation, FAL, via Wikimedia Commons

H2
H3
H4
3 columns
2 columns
1 column
Join the conversation now
Logo
Center