2012-01-06 2 views
18

У меня есть сценарий bash, который я хочу быть спокойным, когда вы бежите без привязки tty (например, cron). Я теперь искал способ условно перенаправить вывод в/dev/null в одной строке. Это пример того, что я имел в виду, но у меня будет гораздо больше команд, которые делают вывод в сценарииусловное перенаправление в bash

#!/bin/bash 
# conditional-redirect.sh 
if tty -s; then 
    REDIRECT= 
else 
    REDIRECT=">& /dev/null" 
fi 
echo "is this visible?" $REDIRECT 

К сожалению, это не работает:

$ ./conditional-redirect.sh 
is this visible? 
$ echo "" | ./conditional-redirect.sh 
is this visible? >& /dev/null 

, что я не» т нужно сделать, это дублировать все команды в с-перенаправлением или-не-перенаправлением вариант:

if tty -s; then 
    echo "is this visible?" 
else 
    echo "is this visible?" >& /dev/null 
fi 

EDIT:

Было бы здорово, если бы решение предоставило мне способ вывода чего-либо в «тихом» режиме, например. когда что-то действительно не так, я мог бы получить уведомление от cron.

ответ

20

Для bash, вы можете использовать строку:

exec &>/dev/null 

Это направит всеstdout и stderr к /dev/null с этого момента. Он использует версию без аргументов exec.

Как правило, что-то вроде exec xyzzy заменит программу в текущем процессе новой программой, но вы можете использовать эту версию без аргументов, чтобы просто изменять перенаправления при сохранении текущей программы.

Таким образом, в вашем конкретном случае, вы могли бы использовать что-то вроде:

tty -s 
if [[ $? -eq 1 ]] ; then 
    exec &>/dev/null 
fi 

Если вы хотите, большинство продукции будет отброшены, но все еще хочет вывести некоторые вещи, вы можете создать новый дескриптор файла сделай это. Что-то вроде:

tty -s 
if [[ $? -eq 1 ]] ; then 
    exec 3>&1 &>/dev/null 
else 
    exec 3>&1 
fi 
echo Normal    # won't see this. 
echo Failure >&3   # will see this. 
+1

Да, это работает ! (Или даже более простой 'exec &>/dev/null') –

+0

.., но имеет недостаток, что все выходные данные теряются в« тихом »режиме; могут быть ситуации, когда я действительно хочу что-то выводить, даже в режиме ожидания; см. обновленный вопрос. –

+0

Хорошая точка, @ даниэль, я немного устал от зубов, и старые привычки сильно падают, но я обновил ответ, используя ваш предпочтительный способ. – paxdiablo

2

Я нашел другое решение, но я чувствую, что это неуклюжая, по сравнению с paxdiablo-х answer:

if tty -s; then 
    REDIRECT=/dev/tty 
else 
    REDIRECT=/dev/null 
fi 
echo "Normal output" &> $REDIRECT 
+2

Это будет работать, но только если выход не перенаправлен. '/ dev/tty' всегда ссылается на ваше терминальное устройство, поэтому, если вы запустили свой скрипт с помощью' myscript> xyzzy.log', вывод, который вы отправляете в '/ dev/tty', не попадет в этот файл журнала , Это может быть неважно, хотя это зависит от того, как вы хотите использовать свою программу. – paxdiablo

1

Вы можете использовать функцию:

function the_code { 
    echo "is this visible?" 
    # as many code lines as you want 
} 

if tty -s; then # or other condition 
    the_code 
else 
    the_code >& /dev/null 
fi 
Смежные вопросы