2010-03-09 2 views
-1

У меня есть сценарий, который вызывает кучу команд, некоторые из которых шумны для stdout, некоторые - для stderr, некоторые для обоих. Я намереваюсь, чтобы сценарий запускался cron, поэтому я не хочу, чтобы он был шумным и отправлял мне по почте каждый день - только в условиях ошибки. Так что я:Bash + cron: перенаправление и восстановление, stdout и stderr выдает разрешение denied

be_quiet() { 
    # save stderr in FD 3 
    exec 3>&2 

    exec &> /dev/null 
} 

die() { 
    # restore stderr 
    exec 2>&3 

    echo $* > /dev/stderr 
    exit 1 
} 

Затем, т.е.

be_quiet 
mkdir -p $CLIENT_ROOT || die "Could not create client root." 
cd $CLIENT_ROOT || die "Could not cd to client root." 

Цель в том, что я получаю конкретные и значимые к мне сообщения, если есть ошибка, и ничто иное. Но теперь я вижу только

line 48: /dev/stderr: Permission denied 

При запуске из командной строки это работает. При запуске через cron он получает сообщение об отказе в разрешении. Я не понимаю, почему.

+0

Действительно ли 'exec 3> & 2' правильный? Обычно stderr '2'. –

+0

Это означает, что у вас нет прав на запись в/dev/stderr. Выполняют ли ваши задания cron под тем же именем пользователя и группы, что и ваша интерактивная оболочка? Вы автоматически переключаетесь на определенную группу в ваш .profile, возможно, tty? –

+0

> Правильно ли exec 3> & 2? Да. Как я уже сказал, это работает при интерактивном запуске. Попробуйте этот скрипт: эхо "Видимый 1" >>/DEV/Stderr Exec 3> & 2 Exec &>/DEV/нуль эхо "невидимом" >>/разработчика/Stderr Exec 2> & 3 эхо «Видимый 2» >>/dev/stderr Опять же, это работает в интерактивном режиме, но не работает через cron. > Выполняют ли ваши задания cron под тем же именем пользователя и группы, что и ваша интерактивная оболочка? Да. > Вы автоматически переключаетесь на определенную группу в своем профиле № – arantius

ответ

2

Вместо

exec 2>&3 

сделать

exec 3>&- 
+0

Что это значит? Можете ли вы включить полный пример с помощью stdout/stderr? –

0

Почему не просто перенаправить стандартный вывод в cronjob к/DEV/нуль? Не используйте функцию be_quiet и резьбонарезную к:

die() { 
    echo "$*" >&2 
} 

Тогда в вашем cronjob:

* * * * * /path/to/script.sh >/dev/null 

Вы должны получить только почту от хрон, когда ваш скрипт выводит что-то с помощью функции штампа.

+0

> Почему бы не просто перенаправить stdout ... Поскольку некоторые из команд, которые я запускаю, являются шумными для stdout, а некоторые - stderr (и некоторые из них). Как я сказал в самом первом предложении моего вопроса. – arantius

+0

Я, должно быть, неправильно понял, вы сказали, что хотите, чтобы вас отправляли по почте для условий ошибки, поэтому я предположил, что вы не хотите видеть что-либо вообще из stdout и всего от stderr. –