AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1176720
Accepted
Astral Axiom
Astral Axiom
Asked: 2019-09-26 17:09:44 +0800 CST2019-09-26 17:09:44 +0800 CST 2019-09-26 17:09:44 +0800 CST

在 Dropbox 更新后运行备份脚本

  • 772

运行:Ubuntu 18.04(gnome)(如果重要,还安装了 xfce4 包)

cron 版本:3.0pl1-128.1ubuntu1

上:amd64

更新:所有软件包都是最新的,没有我知道的问题

内核:5.0.0-29-generic #31~18.04.1-Ubuntu

我正在尝试运行一个我知道有效的备份脚本,因为我已经对其进行了测试。我也知道 cronjob 将运行,如果我退出 while 循环,脚本将成功执行。我希望保留 while 循环,因为我希望在 Dropbox 更新后进行备份。我已将 echo 命令放在 while 循环中,然后在日志文件中观察 -n1 cat 的输出,并查看每 10 秒记录到文件中的内容是“Dropbox 没有运行!” 但我知道这是因为如果我运行保管箱状态,它会显示“最新”。这是脚本:

#!/bin/bash

if [[ $(($(date +%A-%B-%d-%Y) != $(cat /home/user/Log/backup.log | tail -n1 | cut -d " " -f7))) \
     -eq 1 ]]
then
    while [[ $(dropbox status) != "Up to date" ]]
    do
        echo $(dropbox status) >> /home/user/Log/backup.log
        sleep 10s
    done
    shopt -s dotglob globstar

    if [[ $(($(date +%d) % 2)) -eq 0 ]]
    then
        rm -rf /backup/daily0/home/* >> /home/user/Log/backup.log 2>&1
        rm -rf /backup/daily0/etc/* >> /home/user/Log/backup.log 2>&1
        cp -r --preserve /home/user/*/backup/daily0/home >> /home/user/Log/backup.log 2>&1
        cp -r --preserve /etc/* /backup/daily0/etc >> /home/user/Log/backup.log 2>&1
        rm -rf /backup/daily0/home/Dropbox/.dropbox >> /home/user/Log/backup.log 2>&1
        rm -rf /backup/daily0/home/Dropbox/.dropbox.cache >> /home/user/Log/backup.log 2>&1
        echo "successful backup of /home/user and /etc: $(date +%A-%B-%d-%Y) $(date +%l:%M%P)" >>\
        /home/user/Log/backup.log
    else 
        rm -rf /backup/daily1/home/* >> /home/user/Log/backup.log 2>&1
        rm -rf /backup/daily1/etc/* >> /home/user/Log/backup.log 2>&1
        cp -r --preserve /home/user/* /backup/daily1/home >> /home/user/Log/backup.log 2>&1
        cp -r --preserve /etc/* /backup/daily1/etc >> /home/user/Log/backup.log 2>&1
        rm -rf /backup/daily1/home/Dropbox/.dropbox >> /home/user/Log/backup.log 2>&1
        rm -rf /backup/daily1/home/Dropbox/.dropbox.cache >> /home/user/Log/backup.log 2>&1
        echo "successful backup of /home/user and /etc: $(date +%A-%B-%d-%Y) $(date +%l:%M%P)" >>\
        /home/user/Log/backup.log
    fi
    exit 0
else
    exit 0
fi

这是 sudo crontab:

@reboot /usr/local/bin/dailyBackup

我尝试了几件事:

@reboot sleep 60 && /usr/local/bin/dailyBackup

@reboot /usr/bin/dropbox start && /usr/local/bin/dailyBackup

@reboot /usr/bin/dropbox start && sleep 60 && /usr/local/bin/dailyBackup

我还尝试在脚本本身中放置一个 Dropbox 启动命令,并将 sleep 60 作为脚本中的第一个命令,但无论我做什么,cron 运行的脚本中的 Dropbox 状态输出都是“Dropbox 不是跑步!”。因此 cron 在启动或重新启动时运行脚本,但是一旦确实启动了 dropbox,“dropbox status”命令的输出就不会被更新。我能做些什么来解决这个问题?

编辑:

旨在明确在系统正常运行期间启动后调用时,脚本可以完美地运行 while 循环,例如:

sudo dailyBackup

还尝试在脚本中指定 Dropbox 命令的完整路径,例如:

/usr/bin/dropbox status

这也不起作用。

scripts command-line bash cron dropbox
  • 2 2 个回答
  • 337 Views

2 个回答

  • Voted
  1. Astral Axiom
    2019-09-30T06:45:47+08:002019-09-30T06:45:47+08:00

    我已经想出了如何解决这个问题。我读到这个:https://www.linux.com/news/introduction-services-runlevels-and-rcd-scripts/然后我将我的脚本复制到 /etc/init.d 并从 /etc 建立了一个符号链接/rc5.d 如下:

    sudo ln -s ../init.d/dailyBackup ./S01dailyBackup
    

    现在,当我在启动后观看时,刚刚记录到 /home/user/Log/backup.log 的内容是:

    Dropbox isn't running!
    Checking for changes...
    successful backup of /home/user and /etc: Sunday-September-29-2019 at 10:06am
    

    这感觉像是一个比在启动时运行 cronjob 更可靠的解决方案。这是脚本的最终版本:

    #!/bin/bash
    
    if [[ $(($(date +%A-%B-%d-%Y) != $(cat /home/user/Log/backup.log | tail -n1 | cut -d " " -f7))) \
         -eq 1 ]]
        then
        while [[ $(sudo -u user dropbox status) != "Up to date" ]]
        do
            echo $(sudo -u user dropbox status) >> /home/user/Log/backup.log
            sleep 10s
        done
        shopt -s dotglob globstar
    
        if [[ $(($(date +%d) % 2)) -eq 0 ]]
            then
            if [[ -e /backup/daily0/user ]]
                then
                rm -rf /backup/daily0/user/ >> /home/user/Log/backup.log 2>&1
            fi
            if [[ -e /backup/daily0/etc ]]
                then
                rm -rf /backup/daily0/etc/ >> /home/user/Log/backup.log 2>&1
            fi
            cp -r --preserve /home/user/ /backup/daily0/ >> /home/user/Log/backup.log 2>&1
            cp -r --preserve /etc/ /backup/daily0/ >> /home/user/Log/backup.log 2>&1
            rm -rf /backup/daily0/user/Dropbox/.dropbox >> /home/user/Log/backup.log 2>&1
            rm -rf /backup/daily0/user/Dropbox/.dropbox.cache >> /home/user/Log/backup.log 2>&1
            echo "successful backup of /home/user and /etc: $(date +%A-%B-%d-%Y) $(date +%l:%M%P)" >>\
            /home/user/Log/backup.log
        else 
            if [[ -e /backup/daily1/user ]]
                then
                rm -rf /backup/daily1/user/ >> /home/user/Log/backup.log 2>&1
            fi
            if [[ -e /backup/daily1/etc ]]
                then
                rm -rf /backup/daily1/etc/ >> /home/user/Log/backup.log 2>&1
            fi
            cp -r --preserve /home/user/ /backup/daily1/ >> /home/user/Log/backup.log 2>&1
            cp -r --preserve /etc/ /backup/daily1/ >> /home/user/Log/backup.log 2>&1
            rm -rf /backup/daily1/user/Dropbox/.dropbox >> /home/user/Log/backup.log 2>&1
            rm -rf /backup/daily1/user/Dropbox/.dropbox.cache >> /home/user/Log/backup.log 2>&1
            echo "successful backup of /home/user and /etc: $(date +%A-%B-%d-%Y) $(date +%l:%M%P)" >>\
            /home/user/Log/backup.log
        fi
        exit 0
    else
        exit 0
    fi
    

    我尝试使用 7Z 将目录压缩成一个存档,每次备份确实节省了大约 10GB,因为我在任何给定时间保留 2 天的价值,即节省了 20GB 的磁盘空间。问题是该脚本需要一个小时才能运行,因此我使用 tar -cjf 进行了尝试,每次备份节省了大约 8GB,但脚本仍然需要将近一个小时才能完成其任务。因此,为了提高效率,我牺牲了 20GB 的磁盘空间,毕竟现在 Big-O 通常更重要,除非在嵌入式系统上处理非常小的容量。我喜欢解决这个问题,我希望它可以帮助有人尝试做类似的事情:) 对我来说,最好备份所有这些文件和目录的最后 2 天,以防我想在对学校项目或 /etc 中的配置文件或其他任何内容进行一些更改之前检索旧版本。也许将来我会在备份中添加一些其他目录以了解更多信息。在我的学校,我们所有计算机科学专业的学生在基于 Debian 的学校服务器上都有一个帐户,这真的很酷。我们都可以通过 /backup/daily.20/userName 访问目录 /backup/daily.0/userName 中 21 天的主目录备份,这是我从 21 天保存我的 .bash_history 后得到想法的地方之前并将它与我一天前的历史合并。我编写了一个脚本,每 5 分钟通过一次 cronjob 将我的 .bash_history 和 .tmux_history 合并。在调试脚本时我已经拆除了两个文件'

    • 1
  2. Best Answer
    Astral Axiom
    2019-10-02T03:48:33+08:002019-10-02T03:48:33+08:00

    我选择不编辑上一个答案,正如我单击添加此答案时提示所建议的那样,这样对该答案的评论不会无效,并且因为我觉得之前的答案和评论在它们所反映的学习体验中很有价值。


    在关闭我的机器电源以查看仍在运行的某些问题之前,我很兴奋地发布了先前的答案。我还没有弄清楚那个问题到底是什么,我相信这是由于我的脚本不符合 LSB 并且位于 /etc/init.d 中。

    我现在实际上已经解决了这个问题,而且这个解决方案已经运行了几天,我在那段时间里测试了很多次。

    我做了什么:我在努力让这个相同的脚本在我的 Arch 安装启动时运行时发现了这篇文章,该脚本位于此桌面的单独驱动器上:https ://unix.stackexchange.com/questions/138281/arch- linux-run-script-a-minute-after-boot然后我重新访问了这个我有一段时间没看过的页面:https ://wiki.archlinux.org/index.php/Systemd以下解决方案适用于我的 Arch机器,并且意识到 Ubuntu 也运行 Systemd,我决定在 Ubuntu 上也尝试一下......成功:)

    这是现在有效的解决方案:

    #!/bin/bash
    
    if [[ $(($(date +%A-%B-%d-%Y) != $(cat /home/user/Log/backup.log | tail -n1 | cut -d " " -f7))) \
         -eq 1 ]]
        then
        while [[ $(sudo -u user dropbox status) != "Up to date" ]]
        do
            sleep 10s
            [[ $(uptime | cut -d " " -f4) -ge 30 ]] && echo "Dropbox took to long on $(date)" >> \
            /home/user/Log/backup.log && exit 0
        done
        shopt -s dotglob globstar
    
        # Change to BACKUPNUM=$(($(date +%d) % 10)) when get separate drive to                  
        # backup to some day
    
        BACKNUM=$(($(date +%d) % 2))
        rsync -aAX --delete /home/user/ /backup/daily${BACKNUM}/user/ >> \
        /home/user/Log/backup.log 2>&1
        [[ $? -eq 0 ]] && rsync -aAX --delete /etc/ /backup/daily${BACKNUM}/etc/ >> \
        /home/user/Log/backup.log 2>&1
        [[ $? -eq 0 ]] && rm -rf /backup/daily${BACKNUM}/user/.dropbox >> \
        /home/user/Log/backup.log 2>&1
        [[ $? -eq 0 ]] && rm -rf /backup/daily${BACKNUM}/user/Dropbox/.dropbox >> \
        /home/user/Log/backup.log 2>&1
        [[ $? -eq 0 ]] && rm -rf /backup/daily${BACKNUM}/user/Dropbox/.dropbox.cache >> \
        /home/user/Log/backup.log 2>&1
        [[ $? -eq 0 ]] && \
        echo "successful backup of /home/user and /etc: $(date +%A-%B-%d-%Y) $(date +%l:%M%P)" >> \
        /home/user/Log/backup.log
        exit 0
    else
        exit 0
    fi
    

    所以我添加了以下两个文件/etc/systemd/system/dailyBackup.service:

    [Unit]
    Description=dailyBackup
    
    [Service]
    Type=simple
    ExecStart=/usr/local/bin/dailyBackup
    

    和 /etc/systemd/system/dailyBackup.timer:

    [Unit]
    Desciption=Runs dailyBackup one minute after boot
    
    [Timer]
    #how long to wait before executing
    OnBootSec=1min
    Unit=dailyBackup.service
    
    [Install]
    WantedBy=multi-user.target
    

    然后我跑了:

    sudo systemctl enable dailyBackup.timer
    

    并关闭系统。开机后,脚本成功执行,没有关机或重启问题。如前所述,此解决方案已经运行了几天。从脚本中可以看出,我现在正在使用 rsync,这是 bacOn 在他们对我上一个答案的评论中建议的。我过去曾尝试过 rsync 几次,但从未真正完全弄清楚为什么在运行 diff -r 时仍然存在差异,但我想我已经意识到这些是由于系统 .files 自运行以来略有变化rsync 并且还因为我的桌面上的 ~/snap/gnome-system-monitor/current/.local/share/icons/hicolor 似乎有一些损坏的符号链接,而且我的笔记本电脑 Ubuntu 上什至没有 snap 目录。这一定是由于我之前安装和删除的东西。这是另一个问题,尽管 --delete rsync 标志似乎取消了 --exclude 标志,即使我添加了 --delete-excluded 标志。这就是为什么我的脚本在 rsync 之后仍然有 rm 语句的原因。我希望这对某人有帮助,我从中学到了,对我来说这是无价的。现在我需要做一些实际的学校作业,而不是玩和学习 Linux,这是我最喜欢做的事情之一:)

    更新:

    所以我发现 rsync 标志中的模式 --exclude={} 必须是相对路径,相对于要同步的源目录,这就是完全忽略排除项的原因。我将绝对路径放入其中。因此不再需要 rm -rf 语句。我现在还向 while 循环添加了一些条件,并将睡眠时间减少到一秒(我知道这接近轮询命令),这样如果 Dropbox 需要很长时间才能更新,因为我添加了一些巨大的视频文件或其他东西如果我在脚本仍在运行该 while 循环时关闭或重新启动,脚本将退出 0。因此,直到我找到一种更好的方法来在关机或重新启动的情况下停止脚本,以及让脚本等到 Dropbox 更新的更好方法,也许是 dailyBackup 中的某些东西。

    #!/bin/bash
    
    if [[ $((10#$(date +%d) != 10#$(cat /home/user/Log/backup.log | tail -n1 | cut -d " " -f7 | \
          cut -d "-" -f3))) -eq 1 ]]
        then
        while [[ $(sudo -u user dropbox status) != "Up to date" ]]
        do
            [[ $(runlevel | cut -d " " -f2) -eq 0 ]] && exit 0
            [[ $(runlevel | cut -d " " -f2) -eq 6 ]] && exit 0
            [[ $(uptime | cut -d " " -f4) -ge 30 ]] && echo "Dropbox took to long on $(date)" >> \
            /home/user/Log/backup.err && exit 0
            sleep 1s
        done
        shopt -s dotglob globstar
    
        # Change to BACKUPNUM=$(($(date +%d) % 10)) when get separate drive to backup to someday
    
        BACKNUM=$((10#$(date +%d) % 2))
        rsync -aAX --delete-excluded \
        --exclude={".dropbox","Dropbox/.dropbox",".dropbox-dist","Dropbox/.dropbox.cache"} \
        /home/user/ /backup/daily${BACKNUM}/user/ >> /home/user/Log/backup.err 2>&1
        [[ $? -eq 0 ]] && rsync -aAX --delete /etc/ /backup/daily${BACKNUM}/etc/ >> \
        /home/user/Log/backup.err 2>&1
        [[ $? -eq 0 ]] && \
        echo "successful backup of /home/user and /etc: $(date +%A-%B-%d-%Y) $(date +%l:%M%P)" >> \
        /home/user/Log/backup.log
        exit 0
    else
        exit 0
    fi
    

    我没有说明它,但是为了使用它,我创建了一个 /backup 目录,然后创建了 /backup/daily0 和 /backup/daily1 和“sudo chown me:myGroup”,然后在两者中创建了一个用户和一个 etc 目录每日 0 和每日 1。

    同样在我的笔记本电脑上,我更改了 dailyBackup.timer 以在启动后 3 分钟启动脚本,因为 wifi 需要比有线连接更长的时间才能运行,而在我的桌面上,我将其更改为 2 分钟,只是为了帮助它不会在Dropbox 更新时间较长的情况。

    此外,当日期达到 08 时,我发现由于第一个条件 if 中的数字被解释为八进制,因此我必须在前面加上 10#,以便它在任何地方都使用以 10 为底的数字,这促使我只添加一个额外的 cut -d 以仅使用月份的实际日期,而不是比较整个日期字符串。该网站上的问题是井号在代码块中被解释为注释的开头,因此看起来这些行中的最后一行只是注释,它们不是。我还发现最好将错误发送到一个文件并将成功的日志发送到另一个文件。

    chebang 之后的第一行代码和实例化变量 BACKNUM 的行是我正在谈论的行。

    • 1

相关问题

  • 如何从命令行仅安装安全更新?关于如何管理更新的一些提示

  • 如何从命令行刻录双层 dvd iso

  • 如何从命令行判断机器是否需要重新启动?

  • 文件权限如何工作?文件权限用户和组

  • 如何在 Vim 中启用全彩支持?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve