在自动 ftp 脚本中通过管道将 stderr 传输到 syslog

Posted

技术标签:

【中文标题】在自动 ftp 脚本中通过管道将 stderr 传输到 syslog【英文标题】:pipe stderr to syslog inside automated ftp script 【发布时间】:2012-08-29 12:54:42 【问题描述】:

我正在使用简单的脚本来自动化 ftp。脚本如下所示:

ftp -nv $FTP_HOST<<END_FTP
user $FTP_USER $FTP_PASS
binary
mkdir $REMOTE_DIR
cd $REMOTE_DIR
lcd $LOCAL
put $FILE
bye
END_FTP

但我想通过管道将 STDERR 传输到 syslog 并将 STDOUT 传输到日志文件。通常我会做这样的事情:ftp -nv $FTP_HOST 1&gt;&gt;ftp.log | logger&lt;&lt;END_FTP,但在这种情况下,由于&lt;&lt;END_FTP,这将不起作用。我应该如何正确地使脚本工作?请注意,我只想重定向脚本中 FTP 命令的输出,而不是整个脚本。

【问题讨论】:

here-document输入重定向属于ftp命令(|符号之前),是一个可以在行上左右移动的词;它不必是命令行的最后一部分(尽管它通常是行中的最后一项)。 | 后面不能放任何东西,在这种情况下,后面的行是 here 文档,而 here-document 结束标记之后的(非空)行是作为管道的 RHS 执行的命令. 【参考方案1】:

这可以在不使用临时文件进行错误输出的情况下工作。 2&gt;&amp;1 将错误输出发送到标准输出所在的位置——即管道。 &gt;&gt; 改变了标准输出的去向——现在是文件——而不改变标准错误的去向。因此,错误转到logger,输出到ftp.log

ftp -nv $FTPHOST <<END_FTP 2>&1 >> ftp.log | logger
user $FTP_USER $FTP_PASS
binary
mkdir $REMOTE_DIR
cd $REMOTE_DIR
lcd $LOCAL
put $FILE
bye
END_FTP

【讨论】:

ftp -nv $FTPHOST &lt;&lt;END_FTP 2&gt;&amp;1 &gt;&gt; ftp.log | logger 应该删除临时文件。 @SiliconMind 不要将编辑信息放到帖子正文中。这就是编辑摘要框的用途。 @SiliconMind,OP 说:系统日志的 STDERR 和日志文件的 STDOUT。 2&gt;&amp;1 解决方案不完整。【参考方案2】:

怎么样:

 exec > mylogfile; exec 2> >(logger -t myftpscript)

在你面前的 ftp 脚本

【讨论】:

请注意,我只想重定向脚本内 FTP 命令的输出,而不是整个脚本。我只发布了处理 ftp 上传的脚本的一部分。整个脚本的作用远不止于此。 然后在您的 ftp 命令之后重置重定向,例如 exec &gt;/dev/tty 2&gt;&amp;1 'exec to do I/O redirection' 技术在它的位置上很有用,而且它是一种有用的技术。不过,尚不清楚这是它的位置。当可以通过特定命令行上的“临时”重定向完成所有操作时,必须撤消它使得它不太合理。【参考方案3】:

执行此 I/O 重定向的另一种方法是使用 ... 操作,因此:


ftp -nv $FTPHOST <<END_FTP >> ftp.log
user $FTP_USER $FTP_PASS
binary
mkdir $REMOTE_DIR
cd $REMOTE_DIR
lcd $LOCAL
put $FILE
bye
END_FTP
# Optionally other commands here...stderr will go to logger too
 2>&1 | logger

当多个命令(但不是所有命令)需要相同的 I/O 重定向时,这通常是最佳机制。

不过,在上下文中,我认为这个解决方案是最好的(但这是别人的答案,不是我的):

ftp -nv $FTPHOST <<END_FTP 2>&1 >> ftp.log | logger
...
END_FTP

【讨论】:

【参考方案4】:

为什么不创建一个netrc 文件,然后让它登录并为您放置文件。

netrc 文件将允许您登录并允许您定义一个 init 宏,该宏将创建所需的目录并将您想要的文件放在那里。大多数 ftp 命令允许您指定要使用的 netrc 文件,因此您可以将各种 netrc 文件用于各种目的。

这是一个名为 my_netrc 的示例 netrc 文件:

machine ftp_host
user ftp_user
password swordfish
macrodef init
binary
mkdir my_dir
cd my_dir
put my_file
bye

那么,你可以这样做:

$ ftp -v -Nmy_netrc $FTPHOST 2>&1 >> ftp.log | logger

【讨论】:

以上是关于在自动 ftp 脚本中通过管道将 stderr 传输到 syslog的主要内容,如果未能解决你的问题,请参考以下文章

在 Bash 脚本中通过管道传入/传出剪贴板

Pygments 在 python 脚本中通过管道传输到 less 中断突出显示

将 stdout 和 stderr 管道传输到 shell 脚本中的两个不同进程?

无法在批处理脚本中通过FTP上传目录中的文件和文件夹

说解在shell中通过mkfifo创建命名管道来控制多个进程并发执行

在 pentaho CDE 中通过kettleTransFromFile 将参数传递给 pentaho 水壶