Возможно, можете Вы решать, это путем создания сервисного зависимого другого сервиса еще не включило.
Другое решение могло быть следующим:
#!/bin/bash
verbose=0
exec 3>&1
exec 4>&2
if ((verbose)); then
echo "verbose=1"
else
echo "verbose=0"
exec 1>/dev/null
exec 2>/dev/null
fi
echo "this should be seen if verbose"
echo "this should always be seen" 1>&3 2>&4
Затем добавьте 1>&3 2>&4
только к командам, из которых Вы хотите видеть вывод.
Это не интерпретирует его как "имя каталога", >
заключается в кавычки, таким образом, это рассматриваемый буквально (более конкретно, Вы отправляете строку >dev/null 2>&1
. Ваш единственный способ обойти это использует eval
или порождение новой оболочки.
Что касается Вашей "подробной" проблемы, которую ссылаются на в Вашем вопросе, просто сделайте это вместо этого:
verbose=1
if (( verbose )); then
mkdir -v -p /foo
else
mkdir -p /foo > /dev/null 2>&1
fi
У Вас есть много пробелов в Ваших переменных, которые не будут оценены правильно. Вы захотите использовать eval
настраивать это.
#!/bin/bash -x
TEST=">/dev/null 2>&1"
OPT='-p -v'
eval mkdir $OPT 123/123/123 $TEST
Это позволит $OPT быть разделенным на два аргумента (-p
и -v
) вместо одного (-p -v
) и то же с $TEST. Также измененный на использование /dev/null
так как очень маловероятно, что у Вас будет a dev
каталог в текущем каталоге.
"Как" было хорошо объяснено в других ответах; я хочу рассмотреть "почему" код ОП не работает.
Ключевым моментом является то, что перенаправления вывода помечаются перед расширением переменной. Перенаправления на самом деле выполняются после расширения переменных (поэтому вы можете перенаправить вывод на имя файла, которое хранится в переменной), но оболочка идентифицирует перенаправления для последующей обработки до расширения переменных.
Другими словами, после расширения переменных уже "слишком поздно" рассматривать символ перенаправления (<
или >
и т.д.), потому что оболочка уже определила, какие части командной строки она будет обрабатывать как перенаправления.
Для дальнейшего чтения смотрите шаги 1 и 3, перечисленные в разделе:
LESS='+/^SIMPLE COMMAND EXPANSION' man bash
В ответе enzotib используется хорошая магия файлового дескриптора, но более простым решением было бы просто eval
использовать строку (, которая увеличивает нагрузку на процесс, однако):
$ rm /tmp/foo
$ ll /tmp/foo
ls: cannot access /tmp/foo: No such file or directory
$ FOO=">/tmp/foo"
$ date $FOO
date: invalid date '>/tmp/foo'
$ cat /tmp/foo
cat: /tmp/foo: No such file or directory
$ eval date $FOO
$ cat /tmp/foo
Thu Dec 13 14:08:17 EST 2018