简体   繁体   English

“模糊输出重定向”尝试将stdout和stderr从发送到的命令发送到mailx

[英]“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.shstdoutstderr )的输出通过电子邮件发送给我。 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.shstdout传递给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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM