将所有* .gz文件推送到aws s3存储桶时出错 - “bash:-c:第0行:语法错误接近意外令牌`然后'”

时间:2014-03-07 21:56:10

标签: shell amazon-s3

我正在尝试将所有* .gz文件推送到aws s3存储桶但我收到此错误bash:-c:第0行:语法错误接近意外令牌`然后'

  

ssh root @“find / tmp / -name”localhost _ * .gz“-mtime -1 -exec s3cmd   put'{}'s3:// script-testing / test1 / \;如果[$? ==“0”];回声   “成功将备份推送到s3桶”|邮件-s   “成功将备份推送到S3 \”email-id;否则回声\“失败   将日志推送到S3 Bucket \“| mail -s \”将日志推送到s3 \“失败   电子邮件ID;科幻“

3 个答案:

答案 0 :(得分:1)

将-exec命令放入单独的shell脚本会更简单(也更清晰) - 然后你就不必转义引号等,而且你永远不需要问这个问题:

remote$ cat myscript.sh
s3cmd put "$1" s3://script-testing/test1/

if [ $? == "0" ] ; then
  ...


local$ ssh ... -exec myscript.sh '{}' \;

尽管如此:

  1. 您的双引号不对,但可能是SO格式或剪切/粘贴主义,但是:

  2. 你的整个命令应该是单引号而不是双引号,不过这会改变你逃避的需要。

  3. 对“localhost _ * .gz”使用单引号 - 否则如果在当前目录中恰好存在与该模式匹配的文件,则会发生错误。如果你遵守第2步

  4. ,你需要逃避这些引用
  5. 您需要在-exec命令中转义分号(除非您将整批内容放入脚本中)。

  6. 严格来说,你应该引用$?,但不需要引用“0”,但这不会引起任何问题。

  7. #3是你问题的直接原因 - 但是;没有转义,所以从字面上看,然后bash尝试运行“then”作为shell命令,显然失败了。

    如果你真的想把整个东西放到一个长命令中,那么我建议让它作为一个单独的shell脚本工作(“find ... -exec my-script.sh'{}'\;”其中my-script.sh是你当前的-exec命令),然后弄清楚在find命令中内联传递该脚本需要什么引用/转义。

答案 1 :(得分:1)

  1. 您不会终止查找命令,从而导致出现错误
  2. 您的$?在客户端扩展
  3. 你忽略了一些双引号。
  4. 我建议您首先使用要在远程端执行的脚本创建一个文件:

    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
    

    然后您可以直接使用该文件:

    ssh root@hostname "$(< yourfile)"
    

    或者让bash将其转换为可以在脚本中内联的文字参数:

    printf "ssh root@host %q\n" "$(< yourfile)"
    

    给予

    ssh root@host $'find /tmp/ -name \'localhost_*.gz\' -mtime -1 -exec s3cmd put \'{}\' s3://script-testing/test1/ \\;\n\nif [ $? == 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'
    

答案 2 :(得分:1)

ssh实际上并不是设计用于在其单个命令参数中嵌入复杂的脚本。最好保存脚本,将其复制到远程计算机,然后通过ssh执行 it

  1. 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
    

    这将使用自定义行测试运行s3cmd的每个实例的结果 对于每个文件通过管道传输到mail,您就会收到一封电子邮件 摘要。如果你真的想要为每个文件发送一封电子邮件,你可以在循环内管道邮件。

  2. 将脚本复制到远程主机。

    scp script.sh host:
    
  3. 现在通过ssh

    运行脚本
    ssh root@host bash script.sh