Bash 脚本,检查错误,记录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2362255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:59:16  来源:igfitidea点击:

Bash scripting, checking for errors, logging

bashshellloggingscripting

提问by dr Hannibal Lecter

Here's one for the bash-fu wizards. No, actually, I'm just kidding, you'll all probably know this except for me..

这是 bash-fu 向导的一个。不,实际上,我只是在开玩笑,除了我之外,你们可能都知道这一点......

I'm trying to create a backup shell script. The idea is fairly simple: find files in a certain folder, older than 7 days, tar/gzip them to another directory, and remove them. The problem is, I'm not sure if I'll have enough permissions to create a tar/gzip file in the target dir. Is there any (proper) way to check if the file has been created successfully, and if so, delete the files. Otherwise, skip that part and don't destroy customers' data. I hear they are not very fond of that.

我正在尝试创建一个备份 shell 脚本。这个想法相当简单:在某个文件夹中找到超过 7 天的文件,将它们 tar/gzip 压缩到另一个目录,然后删除它们。问题是,我不确定我是否有足够的权限在目标目录中创建 tar/gzip 文件。是否有任何(适当的)方法来检查文件是否已成功创建,如果是,请删除文件。否则,跳过该部分,不要破坏客户的数据。我听说他们不太喜欢那个。

Here's what I have so far:

这是我到目前为止所拥有的:

01: #!/bin/bash
02: 
03: ROOTDIR="/data/www"
04: 
05: TAR="${ROOTDIR}/log/svg_out_xml/export_out_ack_$(date +%Y-%m-%d).tar"
06: cd ${ROOTDIR}/exchange/export/out_ack/
07: find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}"
08: gzip ${TAR}
09: find . -mtime +7 -type f -print0 | xargs -0 rm -f

Basically, I'd need to check if everything went fine on lines 7 and 8, and if so execute 9.

基本上,我需要检查第 7 行和第 8 行是否一切正常,如果是,则执行第 9 行。

Additionally, I'd like to make a log file of these operations so I know everything went fine (this is a nightly cron job).

此外,我想制作这些操作的日志文件,以便我知道一切顺利(这是每晚的 cron 作业)。

回答by Idelic

For logging, you can arrange for all output written on standard output and/or standard error to go to a file. That way, you don't need to redirect the output of each command:

对于日志记录,您可以将所有写在标准输出和/或标准错误上的输出安排到一个文件中。这样,您就不需要重定向每个命令的输出:

# Save standard output and standard error
exec 3>&1 4>&2
# Redirect standard output to a log file
exec 1>/tmp/stdout.log
# Redirect standard error to a log file
exec 2>/tmp/stderr.log

# Now the output of all commands goes to the log files
echo "This goes to /tmp/stdout.log"
echo "This goes to /tmp/stderr.log" 1>&2
...

# Print a message to the original standard output (e.g. terminal)
echo "This goes to the original stdout" 1>&3

# Restore original stdout/stderr
exec 1>&3 2>&4
# Close the unused descriptors
exec 3>&- 4>&-

# Now the output of all commands goes to the original standard output & error
...

To execute a command only if a previous one succeeds, you can chain them with conditionals:

要仅在前一个命令成功时才执行命令,您可以使用条件链接它们:

# Execute command2 only if command1 succeeds, and command3 only if both succeed:
command1 && command2 && command3

# Execute command2 only if command1 fails
command1 || command2

so you can do things like

所以你可以做这样的事情

{ find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" &&
  gzip ${TAR} && 
  find . -mtime +7 -type f -print0 | xargs -0 rm -f } || 
    { echo "Something failed" 1>&2; exit 1 }

or provide details in the log output:

或在日志输出中提供详细信息:

find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" || 
  { echo "find failed!!" 1>&2; exit 1 }
gzip ${TAR} || 
  { echo "gzip failed!!" 1>&2; exit 1 }
find . -mtime +7 -type f -print0 | xargs -0 rm -f || 
  { echo "cleanup failed!!" 1>&2; exit 1}

回答by Paused until further notice.

For logging, you can wrap sections of your script in curly braces and redirect the stdout to a log file:

对于日志记录,您可以将脚本的各个部分括在花括号中,并将标准输出重定向到日志文件:

{
    script_command_1
    script_command_2
    script_command_3
} >> /path/to/log_file

回答by falstro

The easy way out, but with no explicit error message add -eto the shebang, i.e. #!/bin/sh -ewhich will cause the shell to exit if a command fails..

简单的方法,但没有明确的错误消息添加-e到shebang,即#!/bin/sh -e如果命令失败,这将导致shell退出..

Cron should give you an error message through the mail I guess though.

我想 Cron 应该通过邮件给你一条错误消息。

If you want to go full blown back-up scheme though, I'd suggest you use something that has already been made. There are a bunch out there, and most work very well.

但是,如果您想使用完整的备份方案,我建议您使用已经制作好的东西。那里有很多,而且大多数工作得很好。

回答by Ignacio Vazquez-Abrams

GNU tar has --remove-filesthat will remove files once they've been added to the archive. vwill cause it to list out files as it adds them. zwill pipe the tar through gzip on the fly.

GNU tar--remove-files会在将文件添加到存档后将其删除。v将导致它在添加文件时列出文件。z将通过 gzip 动态传输焦油。

Your findsolution is racy; a file may fit the criteria in between invocations, thus getting deleted but not backed up.

你的find解决方案是活泼的;文件可能符合调用之间的条件,因此会被删除但不会备份。