Recommend to read this first: http://wiki.bash-hackers.org/syntax/quoting

With bash you will see 3 types of quoting & in general typing anything in bash you will be in one of these scenarios (your either in quotes: single OR double, or your not in quotes – thats 3 scenerios)

situation 1. without quotes – not being inside quotes is the common bash world – such as typing date +%z – this behaves like weak quotes (variables expansion and escapes work), however spaces usually seperate different arguments
situation 2. weak quotes / double quotes: “” – variables expand & substitutions work, spaces do not seperate different arguments, whole double quote content is seen as one argument
situation 3. strong quotes / single quotes: ” – variables do not expand, escaping doesnt work, and substitutions dont work

With these 3 situations you can make any type of variable you want. With varying double and single quotes in your content if you want.

sidenote:
* variable expansion (get content of variable): ${i} , $i
* escaping (avoid normal behavior of command): \’ , \” , \$
* substitutions (run command inside and show its output): `date` $(date)

sidenote: to type a single quotes.

echo "'" # works - we get a ' on the screen
echo \' # works - this works because we are not inside a strong quoted environment, we are in a situation 1 (escaping works in situation 1)
echo '\'' # fail (you get PS2 output, usually just a greater than sign like this ">" asking for more info, Control-C or Control-D to get out, or finish the quotes with ' or "), you think your escaping the second quote with a ', but remeber its single/strong quotes so escaping doesnt work in them
echo '\' # fail it draws a \, but at least we dont get a PS2

sidenote: to type a double quotes:

echo '"' # works
echo \" # works - this works because we are in situation 1 and we just typed a character (escaping works in situation 1)
echo """ # fail - the first two quotes complete, but the 3rd is looking for a 4th
echo "\"" # works
echo "\" # fails you get PS2 because its like an incomplete above, it thinks you have double quote, character.. where is the other double quote

sidenote: they differ on ‘\”  vs “\””  thats because situation 3 ignores escapes and situation 2 doesnt ignore escapes.

ideally: each none-escaped single quote needs a partner. each none-escaped double quote also needs a none-escaped double quotes

sidenote: you can make null chars like this “”  or like this

sidenote:
if you see this (its not wrong, its just extra chars):

echo """hello""" # this is wierd but not wrong. you can look at it like this echo "" "hello" "", null, hello, null.. you should of just typed "hello"

Study the behavior of these

COMMAND=this is one item
echo "$COMMAND"
ssh someserver "$COMMAND"
# OUTPUT:
# this is one item
# ERROR <-- this is one item is not a valid program (unless you had a "this" program on someserver)
COMMAND="this"''""is'one'"item"
echo "$COMMAND"
ssh someserver "$COMMAND"
# OUTPUT:
# thisisoneitem
# ERROR <-- thisisoneitem
COMMAND=`hostname`
echo "$COMMAND"
ssh someserver "$COMMAND"
# OUTPUT:
# localhost
# ERROR <-- the command localhost doesnt exist on someserver
COMMAND="hostname"
echo "$COMMAND"
ssh someserver "$COMMAND"
# OUTPUT:
# hostname
# someserver
COMMAND='`hostname`'
echo "$COMMAND"
ssh someserver "$COMMAND"
# OUTPUT:
# `hostname`
# someserver # <- this tries to run the command "someserver" on someserver, "someserver" is not a command (or it might of expanded prior to the ssh and it might run "localhost" on the remote command, either way it fails)
COMMAND='echo HOSTNAME `hostname`'
echo "$COMMAND"
ssh someserver "$COMMAND"
eval "$COMMAND"
$COMMAND
"$COMMAND"
'$COMMAND'
# OUTPUT:
# echo HOSTNAME `hostname`
# HOSTNAME someserver <-------------- the command was basically: ssh someserver "echo HOSTNAME `hostname`"
# HOSTNAME localhost <--------------- eval is the best way to run commands that are in your variables
# HOSTNAME localhost <--------------- you can also run commands that you put into a variable $COMMAND
# FAIL <--- dont quote run commands... thats like typing in "date" at the bash prompt of course it will fail as there isnt a command with the name "date" (including the quotes)
# FAIL <--- dont quote run commands... thats like typing in 'date' at the bash prompt of course it will fail as there isnt a command with the name 'date' (including the quotes)
COMMAND="echo `hostname`"
echo "$COMMAND"
ssh someserver "$COMMAND"
# OUTPUT:
# echo HOSTNAME `hostname`
# HOSTNAME localhost <--------------- the command was basically: ssh someserver "echo HOSTNAME localhost"
# HOSTNAME localhost <--------------- eval is the best way to run commands that are in your variables
# HOSTNAME localhost <--------------- you can also run commands that you put into a variable $COMMAND
# FAIL <--- dont quote run commands... thats like typing in "date" at the bash prompt of course it will fail as there isnt a command with the name "date" (including the quotes)
# FAIL <--- dont quote run commands... thats like typing in 'date' at the bash prompt of course it will fail as there isnt a command with the name 'date' (including the quotes)

NOTE: ssh someserver ‘$COMMAND’ would fail because $COMMAND is not defined on the remote side. its neither a variable and its not a filename/command to run. it literally tries to run $COMMAND.

NOTE: sometimes these combinations of quotes and double quotes can get so confusing that I even think bash gets it wrong (maybe it doesnt and im just not smart enough)

Leave a Reply

Your email address will not be published. Required fields are marked *