Bash citando-citando introducción detallada

Bash citando-citando introducción detallada

descripción general

  • Citar literalmente significa encerrar una cadena entre comillas. Esto protege los caracteres especiales en las cadenas para que no sean reinterpretados o expandidos por el shell o los scripts de shell. (Una palabra es "especial" si tiene una interpretación diferente a su significado literal. Por ejemplo: el asterisco * representa comodines en archivos y expresiones regulares además de representar *).
[root@centos8 ~]$ ls -l P*
Pictures:
total 0
Public:
total 0
[root@centos8 ~]$ ls -l 'P*'
ls: cannot access 'P*': No such file or directory
  • En la vida diaria o en la escritura, cuando usamos comillas dobles para "citar" una oración, tratamos la oración de manera diferente y le damos un significado especial; en Bash script, cuando usamos comillas dobles "cadena" para citar una cadena, también tratarlo de manera diferente y proteger su significado literal (significado general).

  • Cuando se trata de la sustitución de comandos, las comillas permiten que echo emita resultados de comandos formateados, conservando los símbolos de espacio en blanco adjuntos a las variables.

bash$ echo $(ls -l)                 # 无引号命令替换
total 8 -rw-rw-r-- 1 bo bo 13 Aug 21 12:57 t.sh -rw-rw-r-- 1 bo bo 78 Aug 21 12:57 u.sh
bash$ echo "$(ls -l)"               # 被引用的命令替换
total 8
 -rw-rw-r--  1 bo bo  13 Aug 21 12:57 t.sh
 -rw-rw-r--  1 bo bo  78 Aug 21 12:57 u.sh

5.1 Cotización de variables¶

  • Cuando citamos una variable, se recomienda utilizar comillas dobles para citarla. Hacer esto evita que bash vuelva a analizar los caracteres especiales entre comillas dobles (excepto: $, backtick ` y backslash \ seguirán siendo analizados por bash). El símbolo $ entre comillas dobles todavía se considera un carácter especial, la ventaja de esto es que se puede realizar la sustitución de variables (“$variable”), es decir, el valor de la variable se usa para reemplazar el nombre de la variable.

  • Otro uso de las comillas dobles es evitar la división de palabras. Los argumentos encerrados entre comillas dobles aparecen como palabras simples (incluso si contienen caracteres de espacio en blanco).

List="one two three"
for a in $List     # 使用空格符作为分隔符分割变量的值(字符串).
do
  echo "$a"
done
# 输出
# one
# two
# three
echo "---"
for a in "$List"   # Preserves whitespace in a single variable.
do #     ^     ^
  echo "$a"
done
# 输出
# one two three
  • Aquí hay un ejemplo más elaborado.
variable1="a variable containing five words"
COMMAND This is $variable1    # 执行COMMAND命令时会被认为带了7个参数如下:
# "This" "is" "a" "variable" "containing" "five" "words"
COMMAND "This is $variable1"  # # 执行COMMAND命令时会被认为带了1个参数如下:
# "This is a variable containing five words"
variable2=""    # 空变量.
COMMAND $variable2 $variable2 $variable2
                # COMMAND命令没带参数执行. 
COMMAND "$variable2" "$variable2" "$variable2"
                # 带了三个空参数执行COMMAND命令. 
COMMAND "$variable2 $variable2 $variable2"
                # COMMAND命令带一个参数执行(该参数为2个空格). 
# 谢谢这个大佬指出:Stéphane Chazelas.
  • Use echo para imprimir caracteres extraños en la salida estándar

Ejemplo 5-1 echo genera variables extrañas

#!/bin/bash
# weirdvars.sh: Echoing weird variables.
echo
var="'(]\\{}\$\""
echo $var        # '(]\{}$"
echo "$var"      # '(]\{}$"     结果相同.
echo
IFS='\'
echo $var        # '(] {}$"     \ 变为了空格,为什么?(IFS为内部域分割符,临时使用'\'作为分隔符)
echo "$var"      # '(]\{}$"
# 以上例子来自Stephane Chazelas.
echo
var2="\\\\\""
echo $var2       #   "
echo "$var2"     # \\"
echo
# 但是 ... var2="\\\\"" 是非法的?(此处四个\,位置2,4的两个刚好被转义,而剩余3个"符,所以不行)
var3='\\\\'
echo "$var3"     # \\\\
# 但是强引用可以.
# ************************************************************ #
# 变量嵌套替换也可以
echo "$(echo '"')"           # "
#    ^           ^
# 某些情况下嵌套很有用
var1="Two bits"
echo "\$var1 = "$var1""      # $var1 = Two bits
#    ^                ^
# Or, as Chris Hiestand points out ...
if [[ "$(du "$My_File1")" -gt "$(du "$My_File2")" ]]
#     ^     ^         ^ ^     ^     ^         ^ ^
then
  ...
fi
# ************************************************************ #
  • Las comillas simples (' ') funcionan como comillas dobles, pero no se permite la sustitución de variables dentro de las comillas simples porque el significado especial del signo $ está desactivado. Cualquier símbolo especial dentro de comillas simples se interpreta literalmente (excepto la comilla simple en sí).

  • Dado que el carácter de escape (carácter de escape) pierde el significado de escape entre comillas simples, no es aceptable intentar encerrar comillas simples entre comillas simples. El siguiente ejemplo puede realizar la salida de comillas simples.

echo "Why can't I write 's between single quotes"
echo
# The roundabout method.
echo 'Why can'\''t I write '"'"'s between single quotes'
#    |-------|  |----------|   |-----------------------|
# 上面使用了三个单引号组;一个转义的单引号和一个双引号引起的单引号.

5.2 Escapar/Escapar

  • El escape es un método utilizado para citar caracteres individuales. Una barra invertida \ antes de un carácter le dice al shell que interprete el carácter literalmente.

Nota: En los comandos del programa como echo o sed, escapar de un carácter puede tener el efecto contrario y desencadenar un significado especial.

Los caracteres de escape específicos tienen los siguientes significados:

used with echo and sed
\n 新行(means newline)
\r 回车(means return)
\t tab键
\v 垂直tab键(means vertical tab)
\b 退格(means backspace)
\a 报警(means alert (beep or flash))
\0xx 将反斜杠后的数字视为八进制的ASCII码值
  • $' … ' : El mecanismo de esta estructura de símbolo es asignar el código ASCII a la variable usando un valor octal o hexadecimal escapado, por ejemplo: quote=$'\042'.

Ejemplo 5-2 Caracteres escapados

#!/bin/bash
# escaped.sh: escaped characters
#############################################################
### First, let's show some basic escaped-character usage. ###
#############################################################
# Escaping a newline.
# ------------------
echo ""
echo "This will print
as two lines."
# 上面的写法将会打印两行
echo "This will print \
as one line."
# 上面的写法将会打印一行
echo; echo
echo "============="
echo "\v\v\v\v"      # 按照字面意思打印 \v\v\v\v .
# 使用 -e 选项 打印转义字符所代表的字符
echo "============="
echo "VERTICAL TABS" # 垂直tab键
echo -e "\v\v\v\v"   # 此时将会打印四个垂直tab
echo "=============="
echo "QUOTATION MARK"
echo -e "\042"       # 打印一个双引号 " (quote, 八进制的 ASCII 值:42;代表一个双引号).
echo "=============="
# 使用该结构 $'\X' 使得-e选项不在需要
echo; echo "NEWLINE and (maybe) BEEP"
echo $'\n'           # 新行.
echo $'\a'           # 警告音(beep).
                     # May only flash, not beep, depending on terminal.
# We have seen $'\nnn" string expansion, and now . . .
# =================================================================== #
# $'\nnn' 该种字符串展开的机制在bash2.0中引进
# =================================================================== #
echo "Introducing the \$\' ... \' string-expansion construct . . . "
echo ". . . featuring more quotation marks."
echo $'\t \042 \t'   # 打印左右两边分别有个tab键的双引号(").
# '\nnn' 为八进制数.
echo
# 将一个ASCII字符赋值给一个变量
# ----------------------------------------
quote=$'\042'        # " 赋值给一个变量
echo "$quote Quoted string $quote and this lies outside the quotes."
echo
# Concatenating ASCII chars in a variable.
triple_underline=$'\137\137\137'  # 137 是八进制的ASCII值,代表'_'.
echo "$triple_underline UNDERLINE $triple_underline"
echo
ABC=$'\101\102\103\010'           # 101, 102, 103 分别代表 A, B, C.
echo $ABC
echo
escape=$'\033'                    # 033 是escape的八进制表示.
echo "\"escape\" echoes as $escape"
#                                   并无可视化的输出.
echo
exit 0
  • Un ejemplo más elaborado

Ejemplo 5-3 Detección de pulsaciones de teclas

#!/bin/bash
# Author: Sigurd Solaas, 20 Apr 2011
# Used in ABS Guide with permission.
# Requires version 4.2+ of Bash.
key="no value yet"
while true; do
  clear
  echo "Bash Extra Keys Demo. Keys to try:"
        #Bash 识别按键的demo.可以识别一下按键:
  echo
  echo "* Insert, Delete, Home, End, Page_Up and Page_Down"
  echo "* The four arrow keys"
        #四个方向键
  echo "* Tab, enter, escape, and space key"
        #tab,回车,返回,空格键
  echo "* The letter and number keys, etc."
        #标点按键
  echo
  echo "    d = show date/time"
  echo "    q = quit"
  echo "================================"
  echo
 # Convert the separate home-key to home-key_num_7:
 if [ "$key" = $'\x1b\x4f\x48' ]; then
  key=$'\x1b\x5b\x31\x7e'
  #   Quoted string-expansion construct. 
 fi
 # Convert the separate end-key to 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 Key
  ;;
  $'\x1b\x5b\x33\x7e')  # Delete
   echo Delete Key
  ;;
  $'\x1b\x5b\x31\x7e')  # Home_key_num_7
   echo Home Key
  ;;
  $'\x1b\x5b\x34\x7e')  # End_key_num_1
   echo End Key
  ;;
  $'\x1b\x5b\x35\x7e')  # Page_Up
   echo Page_Up
  ;;
  $'\x1b\x5b\x36\x7e')  # Page_Down
   echo Page_Down
  ;;
  $'\x1b\x5b\x41')  # Up_arrow
   echo Up arrow
  ;;
  $'\x1b\x5b\x42')  # Down_arrow
   echo Down arrow
  ;;
  $'\x1b\x5b\x43')  # Right_arrow
   echo Right arrow
  ;;
  $'\x1b\x5b\x44')  # Left_arrow
   echo Left arrow
  ;;
  $'\x09')  # Tab
   echo Tab Key
  ;;
  $'\x0a')  # Enter
   echo Enter Key
  ;;
  $'\x1b')  # Escape
   echo Escape Key
  ;;
  $'\x20')  # Space
   echo Space Key
  ;;
  d)
   date
  ;;
  q)
  echo Time to quit...
  echo
  exit 0
  ;;
  *)
   echo You pressed: \'"$key"\'
  ;;
 esac
 echo
 echo "================================"
 unset K1 K2 K3
 read -s -N1 -p "Press a key: "
 K1="$REPLY"
 read -s -N2 -t 0.001
 K2="$REPLY"
 read -s -N1 -t 0.001
 K3="$REPLY"
 key="$K1$K2$K3"
done
exit $?

\" Restaurar el significado literal de las comillas dobles (es decir, comillas dobles, no usadas para comillas)

echo "Hello"                     # Hello
echo "\"Hello\" ... he said."    # "Hello" ... he said.

$ Restaurar el significado literal del carácter $, lo que significa que la variable después de $ no será reemplazada

echo "\$variable01"           # $variable01
echo "The book cost \$7.98."  # The book cost $7.98.

\\ restaura el significado literal de \

echo "\\"  # Results in \
# Whereas . . .
echo "\"   # Invokes secondary prompt from the command-line.
           # In a script, gives an error message.
# However . . .
echo '\'   # Results in \
  • La barra invertida \ se comporta de manera diferente en diferentes situaciones (ya sea con escape, si está en una referencia fuerte, si está en una referencia débil, si está en una sustitución de comando, si está en un "documento aquí")
                      #  简单的转义和引用
echo \z               #  z
echo \\z              # \z
echo '\z'             # \z
echo '\\z'            # \\z
echo "\z"             # \z
echo "\\z"            # \z
                      #  命令替换
echo ècho \z`        #  z
echo ècho \\z`       #  z
echo ècho \\\z`      # \z
echo ècho \\\\z`     # \z
echo ècho \\\\\\z`   # \z
echo ècho \\\\\\\z`  # \\z
echo ècho "\z"`      # \z
echo ècho "\\z"`     # \z
                      # 此处文本(Here document)
cat <<EOF              
\z                      
EOF                   # \z
cat <<EOF              
\\z                     
EOF                   # \z
# These examples supplied by Stéphane Chazelas.
  • Ciertos elementos de una cadena asignada a una variable pueden ser (pueden ser) escapados, pero un solo carácter escapado no necesariamente puede ser asignado a una variable.
variable=\
echo "$variable"
# 不可行,打印一个错误提示:
# test.sh: : command not found
# 单独一个转义字符不可赋给变量
#
#  事实上此处转义字符 "\" 转义了新行(在编写比较长的命令时就可以使用一个转义符来将命令写成多行)
#+ 真正的行为是:        variable=echo "$variable"
#+                      把命令赋值给变量是不允许的
variable=\
23skidoo
echo "$variable"        #  23skidoo
                        #  可行,因为第二行是合法的变量,且实际上第二行被转义成了第一。
variable=\ 
#        \^    转义符后跟一个空格 
echo "$variable"        # 输出空格
variable=\\
echo "$variable"        # \
variable=\\\
echo "$variable"
# 行不通,出错:
# test.sh: \: command not found
#
#  上面三个转义符中,第一个转义可第二个,但是第三个转义符还在,类似于第一个例子。
variable=\\\\
echo "$variable"        # \\
                        # Second and fourth escapes escaped.
                        # This is o.k.

  • Los espacios de escape evitan la división de palabras de la lista de argumentos del comando.
  • Escapar un espacio puede evitar la división de palabras en la lista de argumentos de un comando.
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
输出:
################################
[root@centos8 ~]#ls -l /usr/X11R6/bin/xsetroot\ /sbin/dump\ $file_list
ls: cannot access '/usr/X11R6/bin/xsetroot /sbin/dump /bin/cat': No such file or directory
################################
# Error: the first three files concatenated into a single argument to 'ls -l'
#        because the two escaped spaces prevent argument (word) splitting.
  • Escapar también significa "esperar un comando de varias líneas". Generalmente, diferentes líneas tendrán diferentes comandos, pero el carácter de escape al final de la línea escapa al carácter de la nueva línea y el comando se puede escribir en la siguiente línea.
(cd /source/directory && tar cf - . ) | \
(cd /dest/directory && tar xpvf -)
# 该命令为Alan Cox写的拷贝命令,作两行写,增加了易读性。
# 下面的命令同样功能:
tar cf - -C /source/directory . |
tar xpvf - -C /dest/directory
# See note below.
# (Thanks, Stéphane Chazelas.)
  • Si la línea del script termina con un |, un símbolo de canalización, entonces el carácter de escape \ no es estrictamente necesario. Pero es un buen hábito mantenerse al día con los personajes de escape.
echo "foo
bar" 
##两行
#foo
#bar
echo
echo 'foo
bar'    # 仍然是两行
#foo
#bar
echo
echo foo\
bar     # 换行符被转义输出一行.
#foobar
echo
echo "foo\
bar"     # 同样是一行,转义字符在弱引用中("\")不会丢掉其转义字符的特殊意义。
#foobar
echo
echo 'foo\
bar'     # 两行,因为转义字符在强引用('\')中失去了转义字符的意义,被bash按照字面意义解释。
#foo\
#bar
# Examples suggested by Stéphane Chazelas.

Supongo que te gusta

Origin blog.csdn.net/wang11876/article/details/132075833
Recomendado
Clasificación