![如何在 Unix 中创建满足以下要求的脚本?](https://linux22.com/image/1432782/%E5%A6%82%E4%BD%95%E5%9C%A8%20Unix%20%E4%B8%AD%E5%88%9B%E5%BB%BA%E6%BB%A1%E8%B6%B3%E4%BB%A5%E4%B8%8B%E8%A6%81%E6%B1%82%E7%9A%84%E8%84%9A%E6%9C%AC%EF%BC%9F.png)
名为 on w01 的脚本/root/backup.sh
将备份 /home 的内容
该脚本将:
/share/<YYYY><MM><DD>_w01.tar
创建名为where 的 tar 存档- YYYY 代表当前年份(即 2014 年)
- MM 代表当前月份(即 11)
- DD 代表当前月份的日期(即 22 号)
- 记录成功和错误到
/tmp/backup.log
- 如果遇到错误则以非零返回代码退出
答案1
编写脚本时需要考虑的主要因素如下(我建议您将每个因素写为单独的代码,进行测试,然后在满意后将它们放在一起):
文件命名(即在您的 tarball 名称中使用当前日期):
如另一个答案所述,man date
将为您提供一些帮助,重点关注格式部分(例如date +%Y%m
......)日志记录(即,将 tar 的输出保存到您稍后可以参考的文件中):
您需要决定的第一件事是将日志保存多长时间,您想要保存前一天的尝试还是只保存最近的尝试?如果您要保存多天的尝试,则需要在每次新运行的顶部添加一个日期戳,以便您可以看到一次运行结束的位置和下一次运行开始的位置。echo "here's a command" > /tmp/backup.log
将覆盖 /tmp/backup.log 的内容,并将字符串“here's a command”放置在其位置。echo "here's a command" >> /tmp/backup.log
将保留 /tmp/backup.log 中的所有现有数据,并将“这是一个命令”附加到其末尾。tar -cvf /share/foo.tar /home > /tmp/backup.log
将只将 STDOUT(即通常的“我将这些文件 tar 化”的输出)放入日志中,但不会捕获任何错误。tar -cvf /share/foo.tar /home 2> /tmp/backup.log
将只将 STDERR(即仅错误)放入日志中。tar -cvf /share/foo.tar /home > /tmp/backup.log 2>&1
将会把 STDOUT 和 STDERR 都放入日志中。
将这些结合起来可以在您的日志中创建完全正确的数据集。
错误处理(例如,如果 tar 返回错误该怎么办:对
命令中的错误做出反应的一种快速而肮脏的方法是|| command_to_run_if_error
在命令后添加。这本质上是说“按顺序运行这些命令,直到一个成功”,你也可以使用&& command_to_run_if_success
它就像说“按顺序运行这些命令,直到一个失败”。command1 || command2
将运行命令 1,如果失败(非零退出代码),将运行命令 2。如果成功,则不会运行命令 2。command1 && command2
将运行命令 1,如果失败,将停止并且不会运行命令 2。如果命令 1 成功,则才会运行命令 2。- 可以使用以下方法创建更完整的错误处理程序
if .. then .. else .. fi
例如
echo "About to run command1" >> logfile.log
if command1 >> logfile.log
then
echo "All went well" >> logfile.log
else
echo "Something went wrong! ABORTING" >> logfile.log
run_some_cleanup_command
exit 1
fi
将这些结合起来,教会你的脚本在每次失败的情况下该做什么。
其他需要注意的事项:
在制作 tarball 之前,您是否想检查 /share 上是否有足够的空间容纳它?
考虑使用du -sk /home
来查看需要备份多少 KB,并将其与 中的可用空间量进行比较df -k /share
。您可以使用 shell 命令(例如[ $space_on_share -lt $data_in_home ] || exit 1
中止)来避免用尽所有可用空间(不过,您可能希望它记录一些有用的信息,而不仅仅是退出)。是否要备份一切在 /home 中?
请考虑列出要排除的内容以节省空间或保护隐私。您是否考虑过使用压缩来节省空间?
某些版本的 tar 接受-z
使用 gzip 压缩的标志,或者您可以将 STDOUT 指定为文件名,然后通过 gzip 管道输出(tar -cf - /home | gzip -c > /share/foo.tar.gz
)
答案2
解决任何脚本问题的关键是将其分解成小块。在添加更多功能之前,先编写代码并测试第一个小块。
例如
步骤1
您可以先编写一个脚本,只打印“开始备份”而不执行任何其他操作。
第2步
一旦工作正常,就修改它以将命令的输出分配date
给shell变量(例如$today
)并打印该变量的内容。
步骤 3
当第 2 步经过全面测试并正常运行后,浏览man date
并查看如何更改输出以获得所需的“<YYYY><MM><DD>”输出格式。
等等。如果您在任何时候遇到困难,请在 SuperUser(等)中搜索该特定的微小重点问题,看看是否有现有答案。如果没有,请写一个精心编写的重点突出的问题,说明您已完成的工作、它做了什么以及您希望它做什么。显示可运行代码,但删除所有无关材料。