====== BASH Quotes examples ====== BASH uses single quotes, double quotes and backticks. They all have their uses and using the wrong ones at the wrong time will cause unpredictable results. This page attempts to clarify their usage. Note, just to confuse new users, BASH uses $ as a normal user prompt as well as $ as a variable identifier. user@ubuntu20:~$ <- User Prompt \\ root@ubuntu20:~# <- root user prompt \\ $VARIABLE <- Variable There is no connection between their uses. ===== Good and Bad quotes ===== 0-bad-quotes.sh #!/bin/bash goodquote="Anyone who has never made a mistake has never tried anything new. Albert Einstein." echo "Quote 1. ${goodquote}" echo "" badquote=“To be is to do - Socrates, To do is to be - Sartre, Do Be Do Be Do - Sinatra” echo "Quote 2. ${badquote}" $ ./0-bad_quotes.sh Quote 1. Anyone who has never made a mistake has never tried anything new. Albert Einstein. ./0-bad_quotes.sh: line 8: be: command not found Quote 2. $ goodquote is fine, it uses normal double quotes. badquote is bad because it uses [[https://www.businesslegions.com/blog/2014/01/17/simple-explanation-quotation-marks-66-99/|"66's and 99's"]] which are not valid quotes. Usual source of these is MS word and others, so copy and paste carefully. Better still just don't use windows. ===== Set Variables ===== 1-set_variable.sh #!/bin/bash VAR1='abc 123' VAR2="abc 123" echo $VAR1 $VAR2 $ ./1-set_variable.sh abc 123 abc 123 $ Although not important here, single quotes produces a literal string whilst double quotes allows BASH to expand any variables referenced in them. ===== Print variables ===== 2-print_variable.sh #!/bin/bash VAR1='abc 123 ABC 321' VAR2="abc 123 ABC 321" echo '$VAR1 is ' $VAR1 echo "$VAR2 is " $VAR2 $ ./2-print_variable.sh $VAR1 is abc 123 ABC 321 abc 123 ABC 321 is abc 123 ABC 321 $ VAR1 is printed with echo using single quotes ('$VAR1 is '), so it prints the literal string, $VAR1, and outside the quotes, VAR1 is expanded to the abc string. VAR2 is printed inside double quotes, so BASH expands it to the abc string and then expands it as well outside the quotes, giving a probably unintended statement of the obvious. Although not visible here, BASH treats VAR1 and VAR2 differently as they are declared with either single or double quotes. ===== Newlines with echo and printf ===== newlines_printf.sh #!/bin/bash VAR='abc 123 ABC 321' LINE1="Line one." LINE2="Line two." echo "${LINE1}" echo "${LINE2}" echo '' echo -n "${LINE1}" echo "${LINE2}" echo '' printf "printf variables:- %s\n\n\n" "${VAR}" $ ./3a-newlines_printf.sh Line one. Line two. Line one.Line two. printf variables:- abc 123 ABC 321 $ To use ''echo'' to print multiple statements on one line, use a ''-n'' to supress newlines as ''echo'' will add them unless told not to. On the other hand, ''printf'' needs a ''\n'' to print a new line, the default is not to include one. ''\t'' can be used to print a tab character. Additionally, ''printf'' can use a ''%s'' (string) substitution so it then takes the second argument and uses that to replace the ''%s'' . ===== Strings or Lists? ===== 3-string_or_list.sh #!/bin/bash VAR='abc 123 ABC 321' echo '$VAR is ' "${VAR}" echo 'Single quotes with spaces in the string causes BASH to treat it as a list.' for WORD in ${VAR} do echo '"${WORD}" is:- ' "${WORD}" done echo '' echo 'Double quotes forces variable to include spaces.' echo '' for WORD in "${VAR}" do echo '"${WORD}" is:- ' "${WORD}" done $ $ ./3-string_or_list.sh $VAR is abc 123 ABC 321 Single quotes with spaces in the string causes BASH to treat it as a list. "${WORD}" is:- abc "${WORD}" is:- 123 "${WORD}" is:- ABC "${WORD}" is:- 321 Double quotes forces variable to include spaces "${WORD}" is:- abc 123 ABC 321 In this example, the two identical loops have a different way to start the FOR loop, double quoting the FOR part ( for WORD in "${VAR}" ) causes BASH to treat the string as one string rather than using a space as an element separator in the forst example. This is what you usually want, so remember to use the format "${VARIABLE}". ===== Commands and paths ===== 4-commands_and_paths.sh #!/bin/bash PWD=$(which pwd) echo "pwd command lives in:- ${PWD}" CMD=$(basename "${PWD}") PATH=$(dirname "${PWD}") echo "path $PATH and command $CMD" echo 'How to remake absolute path and file' echo "Is it:- $PATH/$CMD" echo '' echo "Or:- ${PATH}/${CMD}" echo '' echo '' ENVIR='prod' BUCKET1="env$ENVIRbucket" echo 'No brace BUCKET1:- "env$ENVIRbucket" -> ' ${BUCKET1} BUCKET2="env${ENVIR}bucket" echo 'BUCKET with braces:- "env${ENVIR}bucket" -> ' ${BUCKET2} echo '' echo 'Quotes inside quotes' echo 'BUCKET with braces and quotes:- \"${BUCKET2}\" -> ' ">\"${BUCKET2}\"<" $ ./4-commands_and_paths.sh pwd command lives in:- /usr/bin/pwd path /usr/bin and command pwd How to remake absolute path and file Is it:- /usr/bin/pwd Or:- /usr/bin/pwd No brace BUCKET1:- "env$ENVIRbucket" -> env BUCKET with braces:- "env${ENVIR}bucket" -> envprodbucket Quotes inside quotes BUCKET with braces and quotes:- \"${BUCKET2}\" -> >"envprodbucket"< ===== Braces in variables ===== #!/bin/bash PWD=$(which pwd) echo "pwd command lives in:- ${PWD}" CMD=$(basename "${PWD}") PATH=$(dirname "${PWD}") echo "$PATH - $CMD" echo "Let's remake absolute path and file" echo "Is it:- $PATH/$CMD" echo "" echo "Or:- ${PATH}/${CMD}" echo "" echo "" echo "" ENVIR='prod' BUCKET1="env$ENVIRbucket" echo 'No brace BUCKET1:- "env$ENVIRbucket" -> ' ${BUCKET1} BUCKET2="env${ENVIR}bucket" echo 'BUCKET with braces:- "env${ENVIR}bucket" -> ' ${BUCKET2} echo '' echo 'Quotes inside quotes' echo 'BUCKET with braces and quotes:- \"${BUCKET2}\" -> ' "\"${BUCKET2}\"" $ ./5-braces.sh pwd command lives in:- /usr/bin/pwd /usr/bin - pwd Let's remake absolute path and file Is it:- /usr/bin/pwd Or:- /usr/bin/pwd No brace BUCKET1:- "env$ENVIRbucket" -> env BUCKET with braces:- "env${ENVIR}bucket" -> envprodbucket Quotes inside quotes BUCKET with braces and quotes:- \"${BUCKET2}\" -> "envprodbucket" ===== Weird Stuff ===== 6-weird-stuff.sh #!/bin/bash WEIRD1='\\\\' echo "No expansion setting variable:- ${WEIRD1}" echo '' WEIRD2="\\\\" echo "Variable expanded when set:- ${WEIRD2}" echo '' WEIRD3="\\\\\" " echo "W3" echo "${WEIRD3}" echo '' echo "This works:- Why can't I write 's between single quotes?" echo "But this works:- Why can\"t I write \"s between single quotes?" echo '' echo '' echo "This works (clue):-" echo 'Why can\t I write \s between single quotes with backslash escape?' echo '' echo 'This fails:-' echo "'Why can\'t I write \'s between single quotes with backslash escape?'" echo 'Why can\'t I write \'s between single quotes with backslash escape?' $ ./6-weird-stuff.sh No expansion setting variable:- \\\\ Variable expanded when set:- \\ W3 \\" This works:- Why can't I write 's between single quotes? But this works:- Why can"t I write "s between single quotes? This works (clue):- Why can\t I write \s between single quotes with backslash escape? This fails:- 'Why can\'t I write \'s between single quotes with backslash escape?' ./6-weird-stuff.sh: line 33: unexpected EOF while looking for matching `'' $ ===== Backticks and round brackets ===== 7-backticks.sh #!/bin/bash PWD=`pwd` echo "Current backtick directory is:- ${PWD}." DIR=$(pwd) echo "Dollar bracket dir is:- ${DIR}". $ ./7-backticks.sh Current backtick directory is:- /home/cloudshell-user/quotes. Dollar bracket dir is:- /home/cloudshell-user/quotes. $