Escaping

فصل 5. نقل‌قول

5.2- Escaping

escapingتوضیح مترجم ‎[1]‎ یک روش نقل‌قول کردن کاراکترهای منفرد است. escape(\) جلوی یک کاراکتر به پوسته می‌گوید که کاراکتر به طور لفظی تفسیر گردد.

Caution

با برخی فرمانها و برنامه‌های سودمند، از قبیل echo و sed، به کار بردن کاراکتر گریز ‎(\)‎مقدم بر یک کاراکتر ممکن است دارای نتیجه متضادی باشد - می‌تواند باعث تغییر وضعیت به یک معنای خاص برای آن کاراکتر بشود.

معنای ویژه برخی کاراکترهای پوشش یافته با کاراکتر گریز

به کار رفته با echo و sed

‎\n‎

به معنای سطر جدید(تعویض سطر)

‎\r‎

به معنای برگشت

‎\t‎

به معنای tab

‎\v‎

به معنای tab عمودی

‎\b‎

به معنای backspace

‎\a‎

به معنای هشدار (بیپ یا تابش نور)

‎\0xx‎

0nn اکتال را که در آن nn رشته‌ای از ارقام است، به معادل ASCII آن ترجمه می‌کند.

important

ساختار ‎$' ... '‎ بسط رشته نقل‌قولی شده، ساز و کاری است که مقادیر اکتال یا هگز پوشش یافته با کاراکتر گریز را برای تخصیص کاراکترهای ASCII به متغیرها به کار می‌برد، به طور نمونه، ‎quote=$'\042'‎.

مثال ‎5-2‎. کاراکترهای escape شده

#!/bin/bash
# 

#
#
#

# 
# 

echo ""

echo "This will print
as two lines."
# 
# 

echo "This will print \
as one line."
# 

echo; echo

echo "============="


echo "\v\v\v\v"                  #       
#  
echo "============="
echo "VERTICAL TABS"
echo -e "\v\v\v\v"               #               
echo "=============="

echo "QUOTATION MARK"
echo -e "\042"        # 
echo "=============="



#                         

echo; echo "NEWLINE and (maybe) BEEP"
echo $'\n'      #    
echo $'\a'      # 
                # 

#       

# 
# 
# 

echo "Introducing the \$\' ... \' string-expansion construct . . . "
echo ". . . featuring more quotation marks."

echo $'\t \042 \t'            # 
#                    

# 
echo $'\t \x22 \t'            # 
#            
#          

echo


#    
# 
quote=$'\042'                      #
echo "$quote Quoted string $quote and this lies outside the quotes."

echo

# 
  
triple_underline=$'\137\137\137'   #       
echo "$triple_underline UNDERLINE $triple_underline"

echo

ABC=$'\101\102\103\010'            #  
echo $ABC

echo

escape=$'\033'                     #                  
echo "\"escape\" echoes as $escape"
                                   #               

echo

exit 0

مثالی با جزییات بیشتر:

مثال ‎5-3‎. تشخیص کلیدهای فشرده شده

#!/bin/bash
#    
# 
#           

key="no value yet"
while true; do
  clear
  echo "Bash Extra Keys Demo. Keys to try:"
  echo
  echo "* Insert, Delete, Home, End, Page_Up and Page_Down"
  echo "* The four arrow keys"
  echo "* Tab, enter, escape, and space key"
  echo "* The letter and number keys, etc."
  echo
  echo "    d = show date/time"
  echo "    q = quit"
  echo "================================"
  echo

 # 

 if [ "$key" = $'\x1b\x4f\x48' ]; then
  key=$'\x1b\x5b\x31\x7e'   #  
 fi

 #   

 if [ "$key" = $'\x1b\x4f\x46' ]; then
  key=$'\x1b\x5b\x34\x7e'
 fi

 case "$key" in
  $'\x1b\x5b\x32\x7e')  #         
   echo Insert Key
  ;;
  $'\x1b\x5b\x33\x7e')  #         
   echo Delete Key
  ;;
  $'\x1b\x5b\x31\x7e')  # 
   echo Home Key
  ;;
  $'\x1b\x5b\x34\x7e')  #  
   echo End Key
  ;;
  $'\x1b\x5b\x35\x7e')  #        
   echo Page_Up
  ;;
  $'\x1b\x5b\x36\x7e')  #      
   echo Page_Down
  ;;
  $'\x1b\x5b\x41')      #       
   echo Up arrow
  ;;
  $'\x1b\x5b\x42')      #     
   echo Down arrow
  ;;
  $'\x1b\x5b\x43')      #    
   echo Right arrow
  ;;
  $'\x1b\x5b\x44')      #     
   echo Left arrow
  ;;
  $'\x09')              #            
   echo Tab Key
  ;;
  $'\x0a')              #          
   echo Enter Key
  ;;
  $'\x1b')              #         
   echo Escape Key
  ;;
  $'\x20')              #          
   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 $?

همچنین مثال ‎37-1‎ را ببینید.

‎\"‎

یعنی نقل‌قول لفظی

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

‎\$‎

به معنی علامت دلار لفظی است (به نام متغیر پس از ‎\$‎ رجوع نخواهد شد)

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

\\

به معنی کاراکتر backslash لفظی

echo "\\"  #              

           #                     

echo "\"   #
           # 

           #                     

echo '\'   #              

note

رفتار \ به جاییکه معاف می‌شود بستگی دارد، نقل‌قولی شده قدرتمند، نقل‌قولی شده ضعیف، یا ظاهر شدن در داخل جایگزینی فرمان یا یک here document.

# 

echo \z               #   
echo \\z              #  
echo '\z'             #  
echo '\\z'            # 
echo "\z"             #  
echo "\\z"            #  

#      

echo `echo \z`        #   
echo `echo \\z`       #   
echo `echo \\\z`      #  
echo `echo \\\\z`     #  
echo `echo \\\\\\z`   #  
echo `echo \\\\\\\z`  # 
echo `echo "\z"`      #  
echo `echo "\\z"`     #  

                      # 
cat <<EOF              
\z                      
EOF                   # 

cat <<EOF              
\\z                     
EOF                   # 

# 

عناصر یک رشته تخصیص یافته به یک متغیر می‌توانند escape بشوند، اما کاراکتر escape به تنهایی نمی‌تواند به یک متغیر تخصیص بیابد.

variable=\
echo "$variable"
# 
#              
#       
#
#  
#+ 

variable=\
23skidoo
echo "$variable"     # 
#                


variable=\ 
#  
echo "$variable"     #         

variable=\\
echo "$variable"     # 

variable=\\\
echo "$variable"
# 
#             
#
# 
#+ 

variable=\\\\
echo "$variable"     # 
                     # 
                     #                        

معاف کردن یک فاصله می‌تواند مانع از تفکیک کلمه در فهرست شناسه‌های فرمان بشود.

file_list="/bin/cat /bin/gzip /bin/more /usr/bin/less /usr/bin/emacs-20.7"
# 

# 
ls -l /usr/X11R6/bin/xsetroot /sbin/dump $file_list

echo "-------------------------------------------------------------------------"

# ‎
ls -l /usr/X11R6/bin/xsetroot\ /sbin/dump\ $file_list
# 
# 

escape همچنین توانایی نوشتن یک فرمان چندسطری را فراهم می‌کند. به طور عادی هر سطر جداگانه، یک فرمان متمایز را تشکیل می‌دهد، اما یک escape در انتهای یک سطر، کاراکتر سطر جدید را (از معنای غیر لفظی) معاف می‌کند، و دنباله فرمان در سطر بعد ادامه می‌یابد.

(cd /source/directory && tar cf - . ) | \
(cd /dest/directory && tar xpvf -)
#   
# 

# 
tar cf - -C /source/directory . |
tar xpvf - -C /dest/directory
# 
# 
note اگر یک سطر اسکریپت به |، یا کاراکتر لوله‌کشی ختم شود، آنوقت کاراکتر گریز \ به طور صریح، ضروری نیست. اگر چه، همواره escape کردن انتهای سطری از کد که به سطر بعدی امتداد می‌یابد، عادت برنامه‌نویسی خوبی است.

echo "foo
bar" 
# 
# 

echo

echo 'foo
bar'    # 
# 
# 

echo

echo foo\
bar     # 
# 

echo

echo "foo\
bar"     # 
# 

echo

echo 'foo\
bar'     # 
# 
# 

#