我正在编写一个脚本,在其中执行一些命令,这些命令在 上显示一些输出STDOUT
(STDERR
以及,但这没问题)。我需要我的脚本生成一个 .tar.gz 文件到STDOUT
,因此脚本中执行的一些命令的输出也会转到STDOUT
,这以输出中无效的 .tar.gz 文件结束。
因此,简而言之,可以将第一个命令输出到屏幕(因为我仍然想看到输出),但不是通过STDOUT
?另外,我想保持STDERR
不变,以便只有错误消息出现在那里。
举一个简单的例子来说明我的意思。这是我的脚本:
#!/bin/bash
# the output of these commands shouldn't go to STDOUT, but still appear on screen
some_cmd foo bar
other_cmd baz
#the following command creates a tar.gz of the "whatever" folder,
#and outputs the result to STDOUT
tar zc whatever/
我试过弄乱exec
文件描述符,但仍然无法让它工作:
#!/bin/bash
# save STDOUT to #3
exec 3>&1
# the output of these commands should go to #3 and screen, but not STDOUT
some_cmd foo bar
other_cmd baz
# restore STDOUT
exec 1>&3
# the output of this command should be the only one that goes to STDOUT
tar zc whatever/
我想我缺少STDOUT
在第一次执行后关闭并再次重新打开它之类的东西,但我找不到正确的方法来做到这一点(现在的结果与我没有添加exec
s
答案1
stdout 是屏幕。stdout 和“屏幕”之间没有区别。
在这种情况下,我只需在1>&2
子 shell 中将 stdout 临时重定向到 stderr。这将导致命令的输出显示在屏幕上,但不会在程序的 stdout 流中。
#!/bin/bash
# the output of these commands shouldn't go to STDOUT, but still appear on screen
# Start a subshell
(
1>&2 # Redirect stdout to stderr
some_cmd foo bar
other_cmd baz
)
# At the end of the subshell, the file descriptors are
# as they usually are (no redirection) as the subshell has exited.
#the following command creates a tar.gz of the "whatever" folder,
#and outputs the result to STDOUT
tar zc whatever/
您是否需要将此脚本的输出通过管道传输到其他内容?通常,您只需使用标志将 tar 写入文件-f
或仅在 tar 命令上执行重定向:(tar zc whatever > filename.tar.gz
除非您将其放在磁带等设备上或将其用作副本形式)。
答案2
-f
如果您使用开关到 tar 命令来告诉 tar 写入文件,是不是更容易呢?
tar zcf whatever.tar.gz whatever/
如果这不能满足您的要求,那么您将必须单独重定向每个可能写入 STDOUT 的命令
some_cmd foo bar 1>&2
答案3
我认为您正在寻找某种多路复用。
这是一个如何将时间戳附加到每个标准输出行的简单示例:http://www.podciborski.co.uk/programming/perl/add-a-timestamp-to-every-stdout-line/
您可以使用一些特殊标签代替时间戳来标记日志行。然后您必须在另一端删除这些行。因此用法如下:
ssh user@remoteserver the_script.sh | create_tar.sh filename
create_tar.sh 应该是打印带有日志标签的行并将其他行重定向到文件的脚本。