Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting | ||
---|---|---|
Prev | Chapter 5. Quoting | Next |
Escaping is a method of quoting single characters. The escape (\) preceding a character tells the shell to interpret that character literally.
With certain commands and utilities, such as echo and sed, escaping a character may have the opposite effect - it can toggle on a special meaning for that character. |
Special meanings of certain escaped characters
means newline
means return
means tab
means vertical tab
means backspace
means alert (beep or flash)
translates to the octal ASCII equivalent of 0nn, where nn is a string of digits
The $' ... ' quoted string-expansion construct is a mechanism that uses escaped octal or hex values to assign ASCII characters to variables, e.g., quote=$'\042'. |
Example 5-2. Escaped Characters
1 #!/bin/bash 2 # escaped.sh: escaped characters 3 4 ############################################################# 5 ### First, let's show some basic escaped-character usage. ### 6 ############################################################# 7 8 # Escaping a newline. 9 # ------------------ 10 11 echo "" 12 13 echo "This will print 14 as two lines." 15 # This will print 16 # as two lines. 17 18 echo "This will print \ 19 as one line." 20 # This will print as one line. 21 22 echo; echo 23 24 echo "=============" 25 26 27 echo "\v\v\v\v" # Prints \v\v\v\v literally. 28 # Use the -e option with 'echo' to print escaped characters. 29 echo "=============" 30 echo "VERTICAL TABS" 31 echo -e "\v\v\v\v" # Prints 4 vertical tabs. 32 echo "==============" 33 34 echo "QUOTATION MARK" 35 echo -e "\042" # Prints " (quote, octal ASCII character 42). 36 echo "==============" 37 38 39 40 # The $'\X' construct makes the -e option unnecessary. 41 42 echo; echo "NEWLINE and (maybe) BEEP" 43 echo $'\n' # Newline. 44 echo $'\a' # Alert (beep). 45 # May only flash, not beep, depending on terminal. 46 47 # We have seen $'\nnn" string expansion, and now . . . 48 49 # =================================================================== # 50 # Version 2 of Bash introduced the $'\nnn' string expansion construct. 51 # =================================================================== # 52 53 echo "Introducing the \$\' ... \' string-expansion construct . . . " 54 echo ". . . featuring more quotation marks." 55 56 echo $'\t \042 \t' # Quote (") framed by tabs. 57 # Note that '\nnn' is an octal value. 58 59 # It also works with hexadecimal values, in an $'\xhhh' construct. 60 echo $'\t \x22 \t' # Quote (") framed by tabs. 61 # Thank you, Greg Keraunen, for pointing this out. 62 # Earlier Bash versions allowed '\x022'. 63 64 echo 65 66 67 # Assigning ASCII characters to a variable. 68 # ---------------------------------------- 69 quote=$'\042' # " assigned to a variable. 70 echo "$quote Quoted string $quote and this lies outside the quotes." 71 72 echo 73 74 # Concatenating ASCII chars in a variable. 75 triple_underline=$'\137\137\137' # 137 is octal ASCII code for '_'. 76 echo "$triple_underline UNDERLINE $triple_underline" 77 78 echo 79 80 ABC=$'\101\102\103\010' # 101, 102, 103 are octal A, B, C. 81 echo $ABC 82 83 echo 84 85 escape=$'\033' # 033 is octal for escape. 86 echo "\"escape\" echoes as $escape" 87 # no visible output. 88 89 echo 90 91 exit 0 |
A more elaborate example:
Example 5-3. Detecting key-presses
1 #!/bin/bash 2 # Author: Sigurd Solaas, 20 Apr 2011 3 # Used in ABS Guide with permission. 4 # Requires version 4.2+ of Bash. 5 6 key="no value yet" 7 while true; do 8 clear 9 echo "Bash Extra Keys Demo. Keys to try:" 10 echo 11 echo "* Insert, Delete, Home, End, Page_Up and Page_Down" 12 echo "* The four arrow keys" 13 echo "* Tab, enter, escape, and space key" 14 echo "* The letter and number keys, etc." 15 echo 16 echo " d = show date/time" 17 echo " q = quit" 18 echo "================================" 19 echo 20 21 # Convert the separate home-key to home-key_num_7: 22 if [ "$key" = $'\x1b\x4f\x48' ]; then 23 key=$'\x1b\x5b\x31\x7e' 24 # Quoted string-expansion construct. 25 fi 26 27 # Convert the separate end-key to end-key_num_1. 28 if [ "$key" = $'\x1b\x4f\x46' ]; then 29 key=$'\x1b\x5b\x34\x7e' 30 fi 31 32 case "$key" in 33 $'\x1b\x5b\x32\x7e') # Insert 34 echo Insert Key 35 ;; 36 $'\x1b\x5b\x33\x7e') # Delete 37 echo Delete Key 38 ;; 39 $'\x1b\x5b\x31\x7e') # Home_key_num_7 40 echo Home Key 41 ;; 42 $'\x1b\x5b\x34\x7e') # End_key_num_1 43 echo End Key 44 ;; 45 $'\x1b\x5b\x35\x7e') # Page_Up 46 echo Page_Up 47 ;; 48 $'\x1b\x5b\x36\x7e') # Page_Down 49 echo Page_Down 50 ;; 51 $'\x1b\x5b\x41') # Up_arrow 52 echo Up arrow 53 ;; 54 $'\x1b\x5b\x42') # Down_arrow 55 echo Down arrow 56 ;; 57 $'\x1b\x5b\x43') # Right_arrow 58 echo Right arrow 59 ;; 60 $'\x1b\x5b\x44') # Left_arrow 61 echo Left arrow 62 ;; 63 $'\x09') # Tab 64 echo Tab Key 65 ;; 66 $'\x0a') # Enter 67 echo Enter Key 68 ;; 69 $'\x1b') # Escape 70 echo Escape Key 71 ;; 72 $'\x20') # Space 73 echo Space Key 74 ;; 75 d) 76 date 77 ;; 78 q) 79 echo Time to quit... 80 echo 81 exit 0 82 ;; 83 *) 84 echo You pressed: \'"$key"\' 85 ;; 86 esac 87 88 echo 89 echo "================================" 90 91 unset K1 K2 K3 92 read -s -N1 -p "Press a key: " 93 K1="$REPLY" 94 read -s -N2 -t 0.001 95 K2="$REPLY" 96 read -s -N1 -t 0.001 97 K3="$REPLY" 98 key="$K1$K2$K3" 99 100 done 101 102 exit $? |
See also Example 37-1.
gives the quote its literal meaning
1 echo "Hello" # Hello 2 echo "\"Hello\" ... he said." # "Hello" ... he said. |
gives the dollar sign its literal meaning (variable name following \$ will not be referenced)
1 echo "\$variable01" # $variable01 2 echo "The book cost \$7.98." # The book cost $7.98. |
gives the backslash its literal meaning
1 echo "\\" # Results in \ 2 3 # Whereas . . . 4 5 echo "\" # Invokes secondary prompt from the command-line. 6 # In a script, gives an error message. 7 8 # However . . . 9 10 echo '\' # Results in \ |
The behavior of \ depends on whether it is escaped, strong-quoted, weak-quoted, or appearing within command substitution or a here document.
Elements of a string assigned to a variable may be escaped, but the escape character alone may not be assigned to a variable.
|
Escaping a space can prevent word splitting in a command's argument list.
1 file_list="/bin/cat /bin/gzip /bin/more /usr/bin/less /usr/bin/emacs-20.7" 2 # List of files as argument(s) to a command. 3 4 # Add two files to the list, and list all. 5 ls -l /usr/X11R6/bin/xsetroot /sbin/dump $file_list 6 7 echo "-------------------------------------------------------------------------" 8 9 # What happens if we escape a couple of spaces? 10 ls -l /usr/X11R6/bin/xsetroot\ /sbin/dump\ $file_list 11 # Error: the first three files concatenated into a single argument to 'ls -l' 12 # because the two escaped spaces prevent argument (word) splitting. |
The escape also provides a means of writing a multi-line command. Normally, each separate line constitutes a different command, but an escape at the end of a line escapes the newline character, and the command sequence continues on to the next line.
1 (cd /source/directory && tar cf - . ) | \ 2 (cd /dest/directory && tar xpvf -) 3 # Repeating Alan Cox's directory tree copy command, 4 # but split into two lines for increased legibility. 5 6 # As an alternative: 7 tar cf - -C /source/directory . | 8 tar xpvf - -C /dest/directory 9 # See note below. 10 # (Thanks, Stéphane Chazelas.) |
If a script line ends with a |, a pipe character, then a \, an escape, is not strictly necessary. It is, however, good programming practice to always escape the end of a line of code that continues to the following line. |
1 echo "foo 2 bar" 3 #foo 4 #bar 5 6 echo 7 8 echo 'foo 9 bar' # No difference yet. 10 #foo 11 #bar 12 13 echo 14 15 echo foo\ 16 bar # Newline escaped. 17 #foobar 18 19 echo 20 21 echo "foo\ 22 bar" # Same here, as \ still interpreted as escape within weak quotes. 23 #foobar 24 25 echo 26 27 echo 'foo\ 28 bar' # Escape character \ taken literally because of strong quoting. 29 #foo\ 30 #bar 31 32 # Examples suggested by Stéphane Chazelas. |