1. ホーム
  2. linux

[解決済み] に送られたコマンドから mailx に stdout と stderr の両方を送ろうとすると "Ambiguous output redirect" と表示される。

2022-02-18 07:51:40

質問内容

というbashスクリプトを持っています。 test.sh に一行だけ出力します。 標準出力 と1行を 標準エラー .

test.sh:

#!/bin/bash
echo "this is to stdout"
echo "this is to stderr" 1>&2

スクリプトを実行したい test.sh を午後7時に、ただし特定の条件が満たされた場合のみ。そのために、私はもうひとつ schedule.sh このコマンドは、いくつかのことをチェックした後、コマンドを at を後で実行させる。

の出力が欲しい。 test.sh (両方とも 標準出力 標準エラー )をメールで送信するようにしました。私は mailx を使用することで、素敵な件名にすることができます。

さらに at を黙らせる。からの出力はありません。 at の場合、いつも醜いメール(件名なし)を送ってくるからです。 at は、何らかの出力を行います。

schedule.sh です。

#!/bin/bash
my_email="[email protected]" # 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

面白いのは schedule.sh から cron (でスクリプトを実行する)。 sh ) では、完全に動作します。しかし、手動で schedule.sh を使用しています。 tcsh ), at (ただし mailx というメールが届きます。

Ambiguous output redirect.

私が実行するシェルはなぜか schedule.sh を使用した場合、その違いは schedule.sh はbashスクリプトです。

を見ての私の考え方は以下の通りです。 schedule.sh . 引用符の中のすべて "~/test.sh 2>&1 | mailx -s\"Cool title\" [email protected]" への引数であるべきです。 at であり、かつ at を使用して、その引数をコマンドとして実行します。 sh . リダイレクトの 2>&1 | のスタイルになっています。 sh という理由からです。

を削除すると 2>&1 を追加し、パイプのみ 標準出力 test.sh から mailx というメールが2通届きますが、1通は 標準出力 から mailx と、もうひとつは 標準エラー から at .

どうする?どうすれば、呼び出すシェルに関係なく、これを動作させることができるのでしょうか?

ありがとうございます。

を編集します。

uname -o は、私のOSが GNU/Linux

以下は 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

を確認すると 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" [email protected]

最後の2行目がよくわからないのですが、これは $SHELL を使って実行するのでしょうか? /bin/sh ?

解決方法は?

を介して実行されるコマンドは at

~/test.sh 2>&1 | mailx -s\"Cool title\" $my_email

の動作は at コマンドは、システムによって異なります。Linuxでは、コマンドは /bin/sh . 実際、私のシステム(Linux Mint 14)では、警告メッセージが表示されます。

$ echo 'printenv > at.env' | at 19:24
warning: commands will be executed using /bin/sh

Solaris では、コマンドは、現在の値で指定されたシェルによって実行されます。 $SHELL 環境変数を使用します。デフォルトのシェルが /bin/tcsh をSolaris 9で実行すると、次のようになります。

% 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

ということを考えると at の動作が一貫していない(そして率直に言って混乱している)ので、単一のコマンドだけを実行させ、I/Oリダイレクションはそのコマンドの内部で実行させることを提案します。これは、どのシェルでコマンドを実行しても、正しく実行されることを保証する最善の方法です。

例えば(以下未検証のコード)。

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