Есть ли способ перенаправить stdout и stderr через переменную, например, добавив параметры команды в сценарии?
Например, у меня есть скрипт:
#!/bin/bash -x
TEST=">/dev/null 2>&1"
OPT='-p -v'
mkdir $OPT 123/123/123 $TEST
Я вижу, что OPT заменяется -p
без каких-либо проблем, и bash интерпретирует его как опцию. Но перенаправление интерпретируется как имя каталога.
$ ./test.sh
+ TEST='>/dev/null 2>&1'
+ OPT='-p -v'
+ mkdir -p -v 123/123/123 '>/dev/null' '2>&1'
mkdir: created directory `123/123'
mkdir: created directory `123/123/123'
mkdir: created directory `>/dev'
mkdir: created directory `>/dev/null'
mkdir: created directory `2>&1'
Есть ли способ сказать bash, что $ VAR - это перенаправление, а не имена dirs.
PS. Может быть, я нахожусь на неправильном пути, но я хочу сделать дополнительный подробный или не многословный вывод из моего сценария. Но мне нужен вывод даже в не подробном режиме, поэтому я не могу просто перенаправить весь stdout и stderr, только с некоторых команд внутри моего скрипта.
«Как» было хорошо объяснено в других ответах; Я хочу ответить на вопрос «почему», код OP не работает.
Суть в том, что перенаправления вывода помечаются до раскрытия переменной. Перенаправления фактически выполняются после раскрытия переменной (следовательно, вы можете перенаправить вывод в имя файла, которое хранится в переменной), но оболочка идентифицирует перенаправления для последующей обработки до раскрытия переменных.
Другими словами, после раскрытия переменных «слишком поздно» рассматривать символ перенаправления (
<
или>
и т. Д.), Поскольку оболочка уже определила, какие части командной строки она будет обрабатывать как перенаправления.Для дальнейшего чтения, см. Шаги 1 и 3, перечисленные в разделе:
источник
Это не интерпретирует его как «имя каталога»,
>
кавычки, поэтому оно трактуется буквально (точнее, вы отправляете строку>dev/null 2>&1
. Единственный способ обойти это - использоватьeval
или порождать новую оболочку.Что касается вашей «многословной» проблемы, о которой идет речь в вашем вопросе, просто сделайте это вместо этого:
источник
В ваших переменных много пробелов, которые не будут оцениваться должным образом. Вы хотите использовать,
eval
чтобы настроить это.Это позволит разделить $ OPT на два аргумента (
-p
и-v
) вместо одного (-p -v
) и то же самое с $ TEST. Также изменено для использования,/dev/null
так как очень маловероятно, что у вас будетdev
каталог в текущем каталоге.источник
Ответ enzotib использует некоторый хороший файловый дескриптор магии, но более простым решением было бы просто использовать
eval
строку (которая делает накладные расходы дополнение процесса, однако):источник