[英]“Ambiguous output redirect” trying to send both stdout and stderr to mailx from a command sent to at
I have a bash script called test.sh which, for the sake of simplicity, prints one line to stdout and one line to stderr . 我有一个名为test.sh的bash脚本,为了简单起见,将一行打印到stdout ,将一行打印到stderr 。
test.sh: test.sh:
#!/bin/bash
echo "this is to stdout"
echo "this is to stderr" 1>&2
I want to run the script test.sh at 7:00 PM, but only if certain conditions are met. 我想在晚上7点运行脚本test.sh ,但仅限于满足某些条件。 To this end, I have another bash script called schedule.sh , which checks some stuff and then submits the command to
at
to be run later. 为此,我有一个名为schedule.sh另一个bash脚本,检查一些东西,然后提交命令
at
稍后运行。
I want the output of test.sh (both stdout and stderr ) to be sent to me in an email. 我希望test.sh ( stdout和stderr )的输出通过电子邮件发送给我。 I use
mailx
to do this so I can get a nice subject name. 我使用
mailx
来做这个,所以我可以得到一个很好的主题名称。
Furthermore, I want at
to shut up. 此外,我想
at
闭嘴。 No output from at
because it always sends me ugly emails (no subject line) if at
produces any output. 没有来自
at
输出at
因为它总是向我发送丑陋的电子邮件(没有主题行),如果at
产生任何输出。
schedule.sh: schedule.sh:
#!/bin/bash
my_email="me@example.com" # Email is a variable
# Check some stuff, exit if certain conditions not met
echo "~/test.sh 2>&1 | mailx -s\"Cool title\" $my_email" | at 7:00 PM &> /dev/null
What's interesting is that when I run schedule.sh from cron
(which runs the script with sh
), it works perfectly. 有趣的是,当我从
cron
运行schedule.sh (用sh
运行脚本)时,它运行得很好。 However, when I manually run schedule.sh from the terminal (NB: I'm using tcsh
), at
(not mailx
) sends me an email saying 但是,当我从终端手动运行schedule.sh时 (注意:我正在使用
tcsh
), at
(不是mailx
)给我发电子邮件说
Ambiguous output redirect.
I'm not sure why the shell I run schedule.sh from makes a difference, when schedule.sh is a bash script. 当schedule.sh是一个bash脚本时,我不确定为什么运行schedule.sh的shell会产生影响。
Here is my thinking in looking at schedule.sh . 这是我在查看schedule.sh时的想法。 Everything within the quotation marks
"~/test.sh 2>&1 | mailx -s\\"Cool title\\" me@email.com"
should be an argument to at
, and at
runs that argument as a command using sh
. 引号内的所有内容
"~/test.sh 2>&1 | mailx -s\\"Cool title\\" me@email.com"
应该是at
的参数,并且at
运行时将该参数作为使用sh
的命令运行。 The redirection 2>&1 |
重定向
2>&1 |
is in the style of sh
for this reason. 因此,是
sh
的风格。
When I remove 2>&1
and only pipe the stdout of test.sh to mailx
, it does work; 当我删除
2>&1
并且只将test.sh的stdout传递给mailx
,它确实有效; however, I receive 2 emails: one with stdout from mailx
and another from stderr from at
. 不过,我收到2封电子邮件:一个来自标准输出
mailx
和另一个从标准错误 at
。
What gives? 是什么赋予了? How can I make this work regardless of the shell I'm calling it from?
无论我从哪个shell调用它,我怎样才能使这个工作?
Thanks. 谢谢。
edit: 编辑:
uname -o
says my OS is GNU/Linux
uname -o
说我的操作系统是GNU/Linux
Here is uname -a
if it helps: 这是
uname -a
如果它有帮助:
Linux [hostname censored] 2.6.9-89.ELlargesmp #1 SMP Mon Jun 22 12:46:58 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
When I check the at
contents using at -c
, here's what I see: 当我使用
at -c
检查at
内容at -c
,这是我看到的:
#!/bin/sh
# atrun uid=xxxxx gid=xxxxx
# mail username 0
# ...
SHELL=/bin/tcsh; export SHELL
# ...
${SHELL:-/bin/sh} << `(dd if=/dev/urandom count=200 bs=1 2>/dev/null|LC_ALL=C tr -d -c '[:alnum:]')`
~/test.sh 2>&1 | mailx -s"Cool title" me@example.com
I'm having a hard time understanding the second to last line... is this going to execute using $SHELL or /bin/sh
? 我很难理解倒数第二行......这是使用$ SHELL还是
/bin/sh
?
The command executed via at
is: 通过
at
执行的命令是:
~/test.sh 2>&1 | mailx -s\"Cool title\" $my_email
The behavior of at
command varies from one system to another. at
命令的行为因系统而异。 On Linux, the command is executed using /bin/sh
. 在Linux上,使用
/bin/sh
执行命令。 In fact, on my system (Linux Mint 14), it prints a warning message: 实际上,在我的系统(Linux Mint 14)上,它会输出一条警告消息:
$ echo 'printenv > at.env' | at 19:24
warning: commands will be executed using /bin/sh
On Solaris, the command is executed by the shell specified by the current value of the $SHELL
environment variable. 在Solaris上,该命令由
$SHELL
环境变量的当前值指定的shell执行。 Using an account where my default shell is /bin/tcsh
on Solaris 9, I get: 在Solaris 9上使用我的默认shell为
/bin/tcsh
的帐户,我得到:
% echo 'printenv > at.env' | at 19:25
commands will be executed using /bin/tcsh
job 1397874300.a at Fri Apr 18 19:25:00 2014
% echo 'printenv > at.env' | env SHELL=/bin/sh at 19:28
commands will be executed using /bin/sh
job 1397874480.a at Fri Apr 18 19:28:00 2014
Given that at
's behavior is inconsistent (and frankly confusing), I suggest having it execute just a single command, with any I/O redirection being performed inside that command. 鉴于
at
的行为不一致(并且坦率地混淆),我建议让它只执行一个命令,在该命令中执行任何I / O重定向。 That's the best way to ensure that the command will be executed correctly regardless of which shell is used to execute it. 无论使用哪个shell执行命令,这都是确保命令正确执行的最佳方法。
For example (untested code follows): 例如(未经测试的代码如下):
echo '#!/bin/bash' > tmp.bash
echo "~/test.sh 2>&1 | mailx -s\"Cool title\" $my_email" >> tmp.bash
chmod +x tmp.bash
echo "./tmp.bash" | at 7:00 PM
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.