我们有一个cron工作,使用SCP将资料发送给另一家公司。 该命令如下所示:
10 0 * * * ssh USER@LOCAL-SERVER 'scp -q ~/some/dir/* REMOTE_SERVER:/other/dir/' >> ~/log/some.log
这是由其他人设置的。 现在我的问题是,我的老板是在cron邮件列表中,尽pipe“〜〜/ log / some.log”每天仍然发送一封电子邮件,因为即使转移成功,它仍然输出:
Connection to REMOTE_SERVER 12345 port [tcp/*] succeeded!
除非发生错误,否则我的老板不想收到这封电子邮件。
这个命令真的在一个脚本里面,我忽略了这个问题使得问题变得简单。 它运行在RHEL 6服务器上。 但是因为这是我们与REMOTE_SERVER交谈的唯一线路,所以它必须来自那里。 而我们在LOCAL-SERVER(Ubuntu 10.04.4 LTS)上执行命令的原因是因为我们在数据库服务器上,它不能通过防火墙,所以我们首先将数据复制到另一台本地服务器,并从那里上传。
当没有使用-q时,我也会得到以下输出:
SSH Server supporting SFTP and SCP
我不想redirect所有的stderr输出,因为我仍然想在发生错误时收到邮件。
我不认为你可以有select地redirectSTDERR输出,而不用重写程序来写这些特定的消息到STDOUT而不是STDERR 。 但是,你可以做的是编写一个包装脚本来过滤不需要的消息,并在cron作业中运行该脚本。
#!/bin/bash (ssh USER@LOCAL-SERVER ... 3>&1 1>&2- 2>&3-) 2>> ~/log/some.log \ | grep -v "Connection .* succeeded" 1>&2 exit $?
出于好奇,为什么不直接在LOCAL-SERVER上用scp命令运行cron作业?
编辑:你想过滤出一些STDERR输出,同时将所有STDOUT输出redirect到一个文件,但是pipe道可以将一个进程的STDOUT连接到另一个进程的STDIN 。 |&或2>&1 | 将不起作用,因为STDOUT已经被redirect到~/log/some.log ,所以没有任何东西进入pipe道,并且在你的日志文件中有很多不需要的输出。
但是,可以交换描述符,这样STDOUT实际上转到了STDERR而STDERR实际上转到了STDOUT 。 然后,您可以将所有STDERR输出redirect到您的日志文件,并通过grep过滤STDOUT输出。 有人在stackoverflow发布这个巧妙的小技巧。 1>&2将过滤的输出返回到STDERR 。
假设你正在使用BASH:
首先进行复制,交换stdout和stderr:
2>&1 >>〜/ log / some.log ssh USER @ LOCAL-SERVER'scp -q〜/ some / dir / * REMOTE_SERVER:/ other / dir /'
然后你build立一个pipe道来抓取任何正在stderr的东西:
2>&1 >>〜/ log / some.log ssh USER @ LOCAL-SERVER'scp -q〜/ some / dir / * REMOTE_SERVER:/ other / dir /'|
而grep只为失败的消息:
2>&1 >>〜/ log / some.log ssh USER @ LOCAL-SERVER'scp -q〜/ some / dir / * REMOTE_SERVER:/ other / dir /'| grep -E“失败消息”
这将产生cron抓取并包含在其MAIL消息中的输出。 所有其他“stderr”输出将消失(丢失)。 如果由于某种原因,您想保存所有stderr的副本,请先使用tee命令:
2>&1 >>〜/ log / some.log ssh USER @ LOCAL-SERVER'scp -q〜/ some / dir / * REMOTE_SERVER:/ other / dir /'| tee -a〜/ log / some_other.log | grep -E“失败消息”
将所有stderr的副本放入新的日志文件,然后只有失败消息才会进入CRON邮件。