فصل 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
# ‎escaped.sh:‎ شده ‎escape‎ کاراکترهای‎

##########################################################################
###.شده اصلی را ارایه کنم ‎escape‎  نخست ، اجازه دهید کاربرد چند کاراکتر ###
##########################################################################

# معاف کردن یک کاراکتر تعویض سطر
# ------------------

echo ""

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

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

echo; echo

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


echo "\v\v\v\v"                  #      .را به طور لفظی چاپ می‌کند ‎\v\v\v\v‎ 
#  .استفاده کنید ‎'echo'‎ را همراه با‎ -e‎ ‎شده گزینهescape‎ برای چاپ کاراکترهای‎
echo "============="
echo "VERTICAL TABS"
echo -e "\v\v\v\v"               #               .عمودی چاپ می‌کند ‎tab‎ چهار
echo "=============="

echo "QUOTATION MARK"
echo -e "\042"        # را چاپ می‌کند ‎42‎ اکتال ‎ASCII‎ نقل‌قول، یعنی کاراکتر ‎"‎
echo "=============="



#                         .را غیر ضروری می‌کند ‎-e‎ کاربرد گزینه ‎$'\X'‎ ساختار‎

echo; echo "NEWLINE and (maybe) BEEP"
echo $'\n'      #    سطر جدید
echo $'\a'      # هشدار (بیپ)‏
                # .ممکن است فقط نور بتاباند، نه بیپ، به ترمینال بستگی دارد‎

#       ... را دیده‌ایم، و اکنون ‎$"\nnn"‎ ما بسط رشته ‎

# =================================================================== #
#      .را معرفی کرده است ‎$'\nnn'‎ ساختار بسط رشته ‎Bash‎ پوسته ‎2‎ نگارش 
# =================================================================== #

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

echo $'\t \042 \t'            # .ها‎tab‎ قاب شده توسط ‎(")‎ نقل‌قول
#                    .یک مقدار اکتال است ‎'\nnn'‎ توجه نمایید که‎

# با مقادیر هگزا دسیمال هم کار می‌کند ‎$'\xhhh'‎ همچنین در ساختار
echo $'\t \x22 \t'            # .ها‎tab‎ قاب شده توسط ‎(")‎ نقل‌قول
#            .برای نشان دادن این مورد ‎Greg Keraunen‎ با تشکر از‎
#          .را اجازه می‌دادند ‎'\x022'‎ شکل ‎Bash‎ نگارشهای قدیمی‌تر 

echo


#    .به متغیرها ‎ASCII‎ تخصیص کاراکترهای‎
# ----------------------------------------
quote=$'\042'                      # .تخصیص داده شده به یک متغیر ‎"‎ کاراکتر
echo "$quote Quoted string $quote and this lies outside the quotes."

echo

# در یک متغیر ‎ASCII‎ بهم زنجیر کردن کاراکترهای‎
  
triple_underline=$'\137\137\137'   #       .است ‎'_'‎ اکتال کد اسکی برای ‎137‎
echo "$triple_underline UNDERLINE $triple_underline"

echo

ABC=$'\101\102\103\010'            #  .هستند ‎A, B, C‎  اکتال ‎101, 102, 103‎ 
echo $ABC

echo

escape=$'\033'                     #                  است ‎escape‎ اکتال ‎033‎
echo "\"escape\" echoes as $escape"
                                   #               .خروجی قابل مشاهده نیست‎

echo

exit 0

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

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

#!/bin/bash
#    ‎Sigurd Solaas, 20 Apr 2011   :‎ مؤلف
# با مجوز در این راهنما استفاده شده است ‎
#           .است ‎4.2+‎ نگارش ‎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

 # بخش کلیدهای عددی ‎(7)home‎ جداگانه به کلید ‎home‎ تبدیل کلید‎

 if [ "$key" = $'\x1b\x4f\x48' ]; then
  key=$'\x1b\x5b\x31\x7e'   #  .ساختار بسط رشته نقل‌قولی شده‎ 
 fi

 #   بخش کلیدهای عددی ‎(1)end‎ جداگانه به کلید ‎end‎ تبدیل کلید

 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 $?

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

‎\"‎

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

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

‎\$‎

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

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

\\

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

echo "\\"  #              می‌شود ‎\‎ منجر به نمایش

           #                     . . .در حالیکه

echo "\"   #.دومین اعلان خط فرمان را احضار می‌کند‎
           # .در یک اسکریپت، یک پیغام خطا می‌دهد‎

           #                     . . .هر چند که

echo '\'   #              می‌شود ‎\‎ منجر به نمایش

note

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

# نقل‌قول و معاف کردن ساده‎

echo \z               #   z
echo \\z              #  \z
echo '\z'             #  \z
echo '\\z'            # \\z
echo "\z"             #  \z
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
echo `echo "\\z"`     #  \z

                      # Here document
cat <<EOF              
\z                      
EOF                   # \z

cat <<EOF              
\\z                     
EOF                   # \z

# .ارسال شده‌اند ‎Stéphane Chazelas‎ این مثالها توسط

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

variable=\
echo "$variable"
# :کار نخواهد کرد، یک پیغام خطا ارایه می‌کند‎
#              test.sh: : command not found
#       .برهنه نمی‌تواند به سلامت به یک متغیر اختصاص داده شود ‎escape‎‎ یک‎
#
#   سطر جدید را معاف می‌کند و ‎"\"‎ آنچه اینجا در عمل رخ می‌دهد آن است که‎
#+ یعنی یک تخصیص متغیر نامعتبر است ‎variable=echo "$variable"‎ نتیجه آن‎

variable=\
23skidoo
echo "$variable"     # 23skidoo
#                این کار می‌کند، چون سطر دوم، یک تخصیص متغیر معتبر است


variable=\ 
#        \^    دنبال شده با فاصله ‎escape‎
echo "$variable"     #         یک فاصله‎

variable=\\
echo "$variable"     # \

variable=\\\
echo "$variable"
# :کار نخواهد کرد، یک پیغام خطا ارایه می‌کند
#             test.sh: \: command not found
#
#  دومی را معاف می‌کند، اما سومی بدون پوشش ‎escape‎ اولی ‎escapes‎‎
#+    .  باقی می‌ماند، با همان نتیجه مانند نخستین نمونه در بالا

variable=\\\\
echo "$variable"     # \\
                     # .های دوم و چهارم معاف می‌شوند‎escape‎ 
                     #                        این صحیح است

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

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
# به هم پیوسته می‌شوند ‎'ls -l' سه فایل نخست در یک شناسه برای‎ :خطا‎
#        .زیرا فاصله‌های معاف شده مانع تفکیک شناسه (کلمه) می‌گردند

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

(cd /source/directory && tar cf - . ) | \
(cd /dest/directory && tar xpvf -)
#   اما ‎Alan Cox‎ فرمان کپی تکرار کننده درخت دایرکتوری‎
# .به منظور افزایش خوانایی به دو سطر تقسیم گردیده است‎

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

echo "foo
bar" 
# foo
# bar

echo

echo 'foo
bar'    # .باز هم تفاوت ندارد‎
# foo
# bar

echo

echo foo\
bar     # .سطر جدید معاف شده است‎
# foobar

echo

echo "foo\
bar"     # تفسیر گردیده ‎escape‎ در داخل نقل‌قول ضعیف باز هم به عنوان ‎\‎ اینجا هم همانطور، چون ‎
# foobar

echo

echo 'foo\
bar'     # .به علت نقل‌قول قدرتمند حالت لفظی گرفته است ‎\‎ کاراکتر‎
# foo\
# bar

# .پیشنهاد گردیده‌اند ‎Stéphane Chazelas‎ مثال‌ها به وسیله