The shell shall expand the command substitution by executing command
in a subshell environment (see Shell Execution Environment) and
replacing the command substitution (the text of command plus the
enclosing "$()" or backquotes) with the standard output of the
command, removing sequences of one or more characters at the
end of the substitution. Embedded characters before the end
of the output shall not be removed; however, they may be treated as
field delimiters and eliminated during field splitting, depending on
the value of IFS and quoting that is in effect. If the output contains
any null bytes, the behavior is unspecified.
So the normal quoting rule "$(...)" only preserves non-trailing newlines.
% is a special character in printf. That's what's causing the error. You need to escape it as %%.
$ may also be substituted when within double quotes by the outer shell, so you should to escape that (\$). It is usually just easier to use single quotes.
You are using two different things here and should be using a third. Let's see:
| : This is the pipe operator, it serves to pass the output of one process as input to another:
foo | bar
This runs the program foo and passes its output as input to the program bar.
>,<,>> and <<: These are the redirection operators, they serve to send data to/from files:
foo > bar : runs the program foo and saves its output to the filebar, overwriting1 its contents and creating it if it does not exist.
foo >> bar : runs the program foo and saves its output to the filebar, appending to its contents and creating it if it does not exist.
foo < bar : runs foo, telling it to read input from the filebar.
The << is a special case, since there is no point in "appending" input to a command, the << is primarily (exclusively AFAIK) used for Here Documents:
$ cat << EOF > file.txt
> Hello World!
> EOF
The construct << SomeStringHere > Out.file will redirect all text written until it encounters the ending string (EOF in the example above) to the target file. Here docs allow you to easily format multi-line strings and include variables and special characters.
The <<< operator, the Here String, is like a Here Document but it expands variables. So, for example:
grep foo <<< "$bar"
The command above is equivalent to echo "$bar" | grep foo.
What you are actually looking for is called process substitution and is another way to pass the output of a command to another. It consists of <(command).
foo <(bar)
So, for your at example, you could do
at now < <(echo "notify-send HELLO")
The above works because process substitution actually creates a file (read the link above for more details) and it is the file descriptor of that file that is passed with < to at now.
1 The default behavior is to overwrite, this can be modified by setting the noclobber option to bash. If set, echo foo > bar will fail if bar exists. In that case, it can be forced using echo foo |> bar instead. See section 3.6.2 here.
Best Answer
This behavior is actually part of the POSIX specification for command substitution:
So the normal quoting rule
"$(...)"
only preserves non-trailing newlines.Some suggestions for preserving trailing newlines are given in shell: keep trailing newlines ('\n') in command substitution
See also When printing a variable that contains newlines, why is the last newline stripped? for discussion of the rationale behind the specification.