I have a following Shell command which runs successfully:
sed -e "1,/^$(date -d -24hour +'%Y-%m-%d %H')/d" logfile | grep -A20 -B10 'Exception' | mail -s "Sample report" xyz@yourdomain
However, I have to SSH to a particular machine to run this. To avoid this, I modified it in following way which leads to the failure:
ssh myserver 'sed -e "1,/^$(date -d -24hour +'%Y-%m-%d %H')/d" logfile | grep -A20 -B10 'Exception' | mail -s "Sample report" xyz@yourdomain '
What is wrong with this command? How can I fix this?
Advertisement
Answer
Embed your code in a quoted heredoc to avoid needing to modify it (which is an error-prone process by nature):
ssh myserver 'bash -s' <<'EOF' sed -e "1,/^$(date -d -24hour +'%Y-%m-%d %H')/d" logfile | grep -A20 -B10 'Exception' | mail -s "Sample report" xyz@yourdomain EOF
In the specific case here, the obvious reason that your original modifications failed was internal single quotes terminating the ones surrounding the code as a whole.
Specifically:
+'%Y-%m-%d %H'
…the first '
in that expression terminates the one opening before the command, so the space isn’t syntactically protected.
You could instead do the following, since your shell is bash:
ssh myserver $'sed -e "1,/^$(date -d -24hour +'%Y-%m-%d %H')/d" logfile | grep -A20 -B10 Exception | mail -s "Sample report" xyz@yourdomain'
$''
is an extension within which backslashes can escape single quotes (and also be used for other literals — n
for a newline, t
for a tab, etc), functionality not available with typical POSIX sh syntax.
By contrast, in POSIX sh, one can switch quoting types to embed a literal single-quote: 'foo'"'"'bar'
to defines a string with both foo
and bar
single-quoted, and separated by a single literal single-quote between them — perfectly valid syntax, but not necessarily easy for readers unfamiliar with the idiom to process).