Bash script to share snippets of code using rsync
Your read calls perform \ expansion: if the line ends with \, the shell continues reading the next line and returns the text without the backslash-newline sequence; any other backslash quotes the next character (i.e. the backslash is ignored, except that \\ yields \). This is probably not desirable; use read -r to avoid this behavior. Also, for future reference, note that whitespace at the beginning and end of the input is stripped (you need to set IFS to the empty string to avoid this, but here stripping whitespace is desirable); see Understanding IFS and the linked posts.

Furthermore, since this script is designed for interactive use, you should use read -e to enable editing of the input line (with readline). It would also be nicer to have the prompt together with the input line: use read -p 'Server name: ' and so on instead of calling echo (and don't SHOUT). For example:

if [[ -z $SERVER ]]; then
    read -rep 'Server name: ' SERVER
fi

rsync -avz --progress -e ssh "$UN"@"$SERVER":"$remoteSnippetFile" "$localSnippetFile"


This looks a little more complicated than it needs to be, you can write "$UN@$SERVER:$remoteSnippetFile".

The following part has a bug and is not as readable as it could be:


echo -e "&lt;time&gt;"$TIME"&lt;/time&gt;\n" &gt;&gt; "$localSnippetFile"
echo -e "&lt;header&gt;"$snippetTitle"&lt;/header&gt;" &gt;&gt; "$localSnippetFile"
echo "&lt;pre&gt;&lt;/pre&gt;" &gt;&gt; "$localSnippetFile"



The bug is that $TIME and $snippetTitle undergo word splitting and filename generation (i.e. globbing). For example, if $snippetTitle is The A* algorithm and the current directory contains the files Astar.tex, Astar.pdf and test.c, then you're writing &lt;header&gt;The Astar.pdf Astar.tex algorithm&lt;/header&gt; to the file. Always use double quotes around variable and command substitutions, unless you know why you must leave them off and why it's safe to do so. (Exception: you may leave off the double quotes in contexts where they are explicitly not needed, such as inside [[ … ]].)

The readability improvement is to use a here document.

cat &lt;&lt;EOF &gt;&gt;"$localSnippetFile"
&lt;time&gt;$TIME&lt;/time&gt;
&lt;header&gt;$snippetTitle&lt;/header&gt;
&lt;pre&gt;&lt;/pre&gt;
EOF



nano "$localSnippetFile"



glenn jackman has already mentioned this: it's rude to impose your editor on the user. There is a standard for letting the user choose an editor: use the VISUAL environment variable, falling back to EDITOR. Use a sensible fallback if neither variable is set.

if [[ -z ${VISUAL=$EDITOR} ]]; then
  for VISUAL in sensible-editor nano vi; do
    if type "$VISUAL" &gt;/dev/null 2&gt;/dev/null; then break; fi
  done
fi

Drop this …



       while [[ $? = 1 ]]; do
           syncSnippet
       done



… and instead change syncSnippet to first call read until the user enters an accepted input, and then perform the actions based on this input.

while
    read -p "Sync snippet file now [y/n]: " -rN1 yn
    [[ $yn != [YNyn] ]]
do :; done
if [[ $yn = [Yy] ]]; then
  rsync …
fi