Error while pushing all *.gz files to aws s3 bucket - “bash: -c: line 0: syntax error near unexpected token `then'”

Clash Royale CLAN TAG#URR8PPPError while pushing all *.gz files to aws s3 bucket - “bash: -c: line 0: syntax error near unexpected token `then'”
I am trying to push all *.gz files to aws s3 bucket but I getting this error bash: -c: line 0: syntax error near unexpected token `then'
ssh root@ "find /tmp/ -name "localhost_*.gz" -mtime -1 -exec s3cmd
put '{}' s3://script-testing/test1/ ; if [ $? == "0" ] ; then echo
"Successfully pushed the backup to s3 bucket" | mail -s
"Successfully pushed backup to S3 " email-id; else echo "Failed
pushing logs to S3 Bucket" | mail -s "Failed Pushing logs to s3"
email-id; fi"
That is one crazy question title. Consider moving the error message into your question. Good luck.
– shellter
Mar 7 '14 at 22:11
Note that unless there is an error with
find itself, $? in your if statement will always be 0, whether or not there are any errors with any of the calls to s3cmd.– chepner
Mar 8 '14 at 0:18
find
$?
if
s3cmd
3 Answers
3
$?
I suggest you start by creating a file with the script you want to execute on the remote side:
find /tmp/ -name 'localhost_*.gz' -mtime -1 -exec s3cmd put '{}' s3://script-testing/test1/ ;
if [ $? == 0 ]
then
echo "Successfully pushed the backup to s3 bucket" | mail -s "Successfully pushed backup to S3 "
else
echo "Failed pushing logs to S3 Bucket" | mail -s "Failed Pushing logs to s3"
fi
Then you can either use the file directly:
ssh root@hostname "$(< yourfile)"
or let bash turn it into a literal argument that you can inline in your script:
printf "ssh root@host %qn" "$(< yourfile)"
giving
ssh root@host $'find /tmp/ -name 'localhost_*.gz' -mtime -1 -exec s3cmd put '{}' s3://script-testing/test1/ \;nnif [ $? == 0 ]nthen n echo "Successfully pushed the backup to s3 bucket" | mail -s "Successfully pushed backup to S3 "nelse n echo "Failed pushing logs to S3 Bucket" | mail -s "Failed Pushing logs to s3"nfi'
Its cool . thanks a lot . All you guys are really awesome :)
– saranjeet singh
Mar 7 '14 at 23:32
ssh really isn't designed to embed complicated scripts in its single command argument. It's much better to save a script, copy that to the remote machine, and then execute it via ssh.
ssh
ssh
The exit status of find is independent of whether or not any call to s3cmd succeeds or fails. Your script should be something like
find
s3cmd
# I'm assuming for simplicity that there is no whitespace in any of the
# files that find will match.
find /tmp/ -name "localhost_*.gz" -mtime -1 | while read fame; do
if s3cmd put "$fname" s3://script-testing/test1/; then
msg="Successfully pushed the backup $fname to s3 bucket"
else
msg="Failed pushing the backup $fname to s3 bucket"
fi
echo "$msg"
done | mail -s "Results of pushing backups to s3 bucket" email-id
This tests the result of running each instance of s3cmd, with a custom line
for each file piped altogether to a single call to mail, so you get one e-mail
summary. You can pipe to mail inside the loop if you really want one e-mail per file.
s3cmd
mail
Copy your script to the remote host.
scp script.sh host:
Now run the script via ssh
ssh
ssh root@host bash script.sh
It would be simpler (and clearer) to put your -exec command into a separate shell script - then you wouldn't have to escape the quotes etc, and you'd never have needed to ask this questions:
remote$ cat myscript.sh
s3cmd put "$1" s3://script-testing/test1/
if [ $? == "0" ] ; then
...
local$ ssh ... -exec myscript.sh '{}' ;
Notwithstanding that though:
Your double quotes aren't right, but that might be SO formatting or a cut/paste-ism, although:
Your entire command ought to be in single quotes rather than double quotes, although that would change your need for escaping.
Use single quotes for "localhost_*.gz" - otherwise bad things will happen if there happens to be a file matching that pattern in the current directory. You'll need to escape those quotes if you abide by step 2
You need to escape the semicolons within the -exec command (unless you put the whole lot into a script).
Strictly speaking, you ought to double-quote the $?, but don't need to quote the "0", but that won't cause any issues in this instance.
#3's the immediate cause of your problem though - the ; isn't escaped and so is taken literally, and bash then tries to run "then" as a shell command, which obviously fails.
If you really want to put the whole thing into one long command then I'd suggest getting it working as a separate shell script ("find ... -exec my-script.sh '{}' ;" where my-script.sh is your current -exec command), and then figure out what quoting/escaping is required to pass that script inline in the find command.
It working.. Thanks for your explanation.
– saranjeet singh
Mar 7 '14 at 23:21
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
I checked syntax in shellcheck.net. It looks all good. But I don't know where is the issue. Any help would be greatful.
– saranjeet singh
Mar 7 '14 at 21:58