XXX 5.2. Escapament¶
En diem escapament al mecanisme de remarcar un caràcter prefixant-lo amb el
caràcter \
per a indicar a la shell que interpreti el caràcter com el seu
significat literal i no com un caràcter especial.
En alguns contextos (ex. amb les comandes echo i i sed), escapar un caràcter pot tenir l’efecte contrari. Podria indicar que es consideri un significat especial pel caràcter escapat.
Significats especials d’alguns caràcters¶
Quan escapem els següents caràcters amb les comandes echo
i sed
, són
interpretats de la següent manera:
\n
: nova línia\r
: retorn de línia\t
: tabulador\v
: tabulador vertical\b
: espai en rere\a
: alerta (en forma de so o parpadeig)\0nn
: tradueix a l’equivalent ASCII en octal. Equival a0nn
onnn
és una cadena de dígits.Nota
Es poden assignar caràcters ASCII a variables fent servir valors octals o hexadecimals escapats dins de
$' ... '
. Per exemple:cometadoble=$'\\042'
.\"
: Indica que les cometes s’interpretin com el caràcter i no com inici o final de text entre cometes.echo "Hola" # Sortida: Hola echo "\"Hola\" ... va dir." # Sortida: "Hola" ... va dir.
\$
: Indica que$
sigui interpretat com el caràcter. Així, les variables precedides per\$
no fan referència al seu valor.echo \$variable01 # Sortida: $variable01 echo "El llibre val \$7.98." # Sortida: El llibre val $7.98.
\\
: Indica que la contrabarra sigui interpretada com el caràcter i no com escapament del següent caràcter.echo "\\" # Sortida: \ # Mentre que ... echo "\" # Escapa la segona cometa doble. # Des de la línia de comandes invoca el *prompt* secundari # per continuar introduint una comanda multi-linia en # posteriors línies fins acabar amb ``"`` en aquest cas, o amb # ``ctrl-d`` en general. # Dins d'un guió, generaria un missatge d'error. # En canvi ... echo '\' # Sortida: \
Exemple 1. Caràcters escapats¶
#!/bin/bash
# Demostració de caràcters escapats
### Comencem veient uns exemples bàsics d'escapament de caràcters
# Escapem un salt de línia
echo ""
echo "Aquest text es mostrarà
en dues línies."
# Sortida: Aquest text es mostrarà
# en dues línies.
echo "Aquest text es mostrarà \
en una única línia."
# Sortida: Aquest text es mostrarà en una única línia.
echo; echo
echo "============="
echo "a\ve\vi\vo\vu" # Sortida: a\ve\vi\vo\vu
# Amb l'opció -e, la comanda echo mostrarà els caràcters escapats.
echo "Tabulació vertical"
echo -e "a\ve\vi\vo\vu" # Sortida: a
# e
# i
# o
# u
echo "Cometes dobles"
echo -e "\042aeiou\042" # Sortida: "aeiou"
# Amb $'\X' no cal l'opció -e
echo; echo "Salt de línia i (potser) PIIIP"
echo $'\n' # Nova línia
echo $'\a' # Alerta (PIIP).
# Depenent del terminal, pot no fer soroll sinó un parpadeig.
# Hem vist l'expansió $'\xxx'. Ara...
# La versió 2 de Bash va introduir l'expansió de cadenes de text $'\nnn'.
echo "Introducció de l'expansió de cadenes amb \$\' ... \' ..."
echo "... que inclou més marques de cometes."
echo $'a\t \042 \tz' # Sortida: a " z
# Atenció: '\xxx' és un valor octal
# També funciona amb valors hexadecimals amb $'\xhhh'.
echo $'a\t \x22 \tz' # Sortida: a " z
echo
# Assignació d'un caràcter ASCII a una variable.
cometes=$'\042' # " ara $cometes val "
echo $cometes text entre cometes $cometes i fora de les cometes.
echo
# Concatenació de caràcters ASCII en una variable.
triple_subratllat=$'\137\137\137' # 137 és el valor octal del caràcter ASCII _
echo "$triple_subratllat SUBRATLLAT $triple_subratllat"
echo
ABC=$'\101\102\103\010' # 101, 102, 103 són els valors en octal dels caràcters A, B i C.
echo $ABC
echo
escape=$'\033' # 033 és el valor octal pel caràcter d'escape (tecla ESC)
echo "\"escape\" mostrat com $escape"
# Sortida: "escape" mostrat com
# ^ en el teu terminal segurament es mostra amb un
# símbol "raro"
echo
exit 0
Exemple 2. Detecció de tecles¶
A continuació un exemple més elaborat:
#!/bin/bash
# Demostració de captura de tecles
# Autor original: Sigurd Solaas, 20 abril 2011
# Per versió de Bash 4.2+.
key="De moment no has pres cap tecla"
while true; do
clear
echo "Demostració de tecles extra. Prova amb les tecles:"
echo
echo "* Insert, Delete, Home, End, Page_Up i Page_Down"
echo "* Les quatre tecles del cursor"
echo "* Tab, enter, esc i barra d'espai"
echo "* Les tecles de lletres, nombres, etc."
echo
echo " d = mostra la data i hora"
echo " q = surt"
echo "================================"
echo
# Converteix la tecla separada home-key a home-key_num_7:
if [ "$key" = $'\x1b\x4f\x48' ]; then
key=$'\x1b\x5b\x31\x7e' # expansió de text entre cometes
fi
# Converteix la tecla separada end-key a end-key_num_1.
if [ "$key" = $'\x1b\x4f\x46' ]; then
key=$'\x1b\x5b\x34\x7e'
fi
case "$key" in
$'\x1b\x5b\x32\x7e') # Insert
echo Insert
;;
$'\x1b\x5b\x33\x7e') # Delete
echo Delete
;;
$'\x1b\x5b\x31\x7e') # Home_key_num_7
echo Inici
;;
$'\x1b\x5b\x34\x7e') # End_key_num_1
echo Fi
;;
$'\x1b\x5b\x35\x7e') # Page_Up
echo Pàgina amunt
;;
$'\x1b\x5b\x36\x7e') # Page_Down
echo Pàgina abaix
;;
$'\x1b\x5b\x41') # Up_arrow
echo Cursor amunt
;;
$'\x1b\x5b\x42') # Down_arrow
echo Cursor abaix
;;
$'\x1b\x5b\x43') # Right_arrow
echo Cursor dreta
;;
$'\x1b\x5b\x44') # Left_arrow
echo Cursor esquerra
;;
$'\x09') # Tab
echo Tab
;;
$'\x0a') # Enter
echo Enter
;;
$'\x1b') # Escape
echo Escape
;;
$'\x20') # Space
echo Space
;;
d)
date
;;
q)
echo "Això s'acaba..."
echo
exit 0
;;
*)
echo Has pres: \'"$key"\'
;;
esac
echo
echo "================================"
unset K1 K2 K3
read -s -N1 -p "Prem una tecla: "
K1="$REPLY"
read -s -N2 -t 0.001
K2="$REPLY"
read -s -N1 -t 0.001
K3="$REPLY"
key="$K1$K2$K3"
done
exit $?
Exemple 3. Expansió de cadenes de text¶
Considera també el següent exemple que també apareix a XXX 37.1. Bash, version 2.
#!/bin/bash
# XXX Demostració d'expansió de cadenes de text
# Introduced with version 2 of Bash.
# Strings of the form $'xxx'
#+ have the standard escaped characters interpreted.
echo $'Ringing bell 3 times \a \a \a'
# May only ring once with certain terminals.
# Or ...
# May not ring at all, depending on terminal settings.
echo $'Three form feeds \f \f \f'
echo $'10 newlines \n\n\n\n\n\n\n\n\n\n'
echo $'\102\141\163\150'
# B a s h
# Octal equivalent of characters.
exit
Exemple 4. Comportament de \
¶
El comportament de \
depén de si apareix:
- entre cometes dobles o simples (mira 4.1. Substitució de variables),
- dins d’una substitució de comandes (mira XXX Chapter 12. Substitució de comanda), o
- en un document immediat (mira XXX Chapter 19. Document immediat)
# XXX Demostració del comportament de \
# Simple escaping and quoting
echo \z # z
echo \\z # \z
echo '\z' # \z
echo '\\z' # \\z
echo "\z" # \z
echo "\\z" # \z
# Command substitution
echo `echo \z` # z
echo `echo \\z` # z
echo `echo \\\z` # \z
echo `echo \\\\z` # \z
echo `echo \\\\\\z` # \z
echo `echo \\\\\\\z` # \\z
echo `echo "\z"` # \z
echo `echo "\\z"` # \z
# Here document
cat <<EOF
\z
EOF # \z
cat <<EOF
\\z
EOF # \z
# These examples supplied by Stéphane Chazelas.
Exemple 5. Contrabarra com a valor d’una variable¶
Els elements d’una cadena de caràcters assignada a una variable poden ser escapats, però el caràcter d’escapament en si (la contrabarra) no pot ser assignada com a únic valor a una variable.
# XXX Demostració de \ com a valor de variable
variable=\
echo "$variable"
# Will not work - gives an error message:
# test.sh: : command not found
# A "naked" escape cannot safely be assigned to a variable.
#
# What actually happens here is that the "\" escapes the newline and
#+ the effect is variable=echo "$variable"
#+ invalid variable assignment
variable=\
23skidoo
echo "$variable" # 23skidoo
# This works, since the second line
#+ is a valid variable assignment.
variable=\
# \^ escape followed by space
echo "$variable" # space
variable=\\
echo "$variable" # \
variable=\\\
echo "$variable"
# Will not work - gives an error message:
# test.sh: \: command not found
#
# First escape escapes second one, but the third one is left "naked",
#+ with same result as first instance, above.
variable=\\\\
echo "$variable" # \\
# Second and fourth escapes escaped.
# This is o.k.
Exemple 6. Escapament d’espai¶
Quan escapem espais, hem de tenir present que té implicacions a l’hora de separar paraules en una llista d’arguments.
# XXX Demostració d'escapament d'espais en blanc
file_list="/bin/cat /bin/gzip /bin/more /usr/bin/less /usr/bin/emacs-20.7"
# List of files as argument(s) to a command.
# Add two files to the list, and list all.
ls -l /usr/X11R6/bin/xsetroot /sbin/dump $file_list
echo "-------------------------------------------------------------------------"
# What happens if we escape a couple of spaces?
ls -l /usr/X11R6/bin/xsetroot\ /sbin/dump\ $file_list
# Error: the first three files concatenated into a single argument to 'ls -l'
# because the two escaped spaces prevent argument (word) splitting.
Exemple 7. Escapament i comandes multi-línia¶
Amb \
també disposem d’un mecanisme per escriure comandes multi-línia. Ja ho
hem vist per sobre, a un exemple previ. Considera aquest exemple més complet:
# XXX Demostració d'ús de \ per construir comandes en més d'una línia
(cd /source/directory && tar cf - . )\
(cd /dest/directory && tar xpvf -)
# Repeating Alan Cox's directory tree copy command,
# but split into two lines for increased legibility.
# As an alternative:
tar cf - -C /source/directory .
tar xpvf - -C /dest/directory
# See note below.
# (Thanks, Stéphane Chazelas.)
Nota
En cas que la línia acabi amb el caràcter |
(pipe), no és extrictament
necessari escapar el salt de línia. Amb tot, es considera una bona pràctica
escapar sempre el final de cada línia que continua amb la següent.
Exemple 8. Comandes multi-línia i text¶
# XXX Demostració de text en més d'una línia
echo "foo
bar"
#foo
#bar
echo
echo 'foo
bar' # No difference yet.
#foo
#bar
echo
echo foo\
bar # Newline escaped.
#foobar
echo
echo "foo\
bar" # Same here, as \ still interpreted as escape within weak quotes.
#foobar
echo
echo 'foo\
bar' # Escape character \ taken literally because of strong quoting.
#foo\
#bar
# Examples suggested by Stéphane Chazelas.