2015-07-16 2 views
1

Я пытаюсь понять перенаправление вывода.перенаправить вывод на терминал

У меня есть код:

#!/bin/bash 
function function1() { 
    log=${1}.log 

    exec 3>&1 
    exec 1>>$log 
    exec 2>&1 

    echo checking $log >&3 
    echo txt to $log 
} 

function1 log1 
function1 log2 

exit 0 

вывод, что я получаю:

checking log1.log 

и файл log1.log с содержанием

txt to log1.log 
checking log2.log 

и файл log2.log с содержанием

txt to log2.log 

, что я действительно хочу это файл log1.log с содержанием

txt to log1.log 

и файл log2.log с содержанием

txt to log2.log 

и вывода на терминал, чтобы быть.

checking log1.log 
checking log2.log 

Как я могу это сделать, пожалуйста? Я знаю, что могу использовать function1 log1 > log1.log 2>&1, но чем я не могу перенаправить эхо обратно в терминал в функции1, могу, но это похоже на результат.

+0

Вы устанавливаете 1 в файл журнала, а затем в следующем итерационном задании 3, где 1 балл. – 123

+0

Спасибо, я не знал, что он работает так (1 для журнала, от 3 до 1 ...) – andrej

ответ

2

Если вы хотите установить стандартный вывод и стандартный поток ошибок, а затем восстановить их в функции сделать:

function function1() { 
    log=${1}.log 
    exec 4>&2 3>&1 1>>$log 2>&1 # save 1 and 2 to 3 and 4 
    echo checking $log >&3 
    echo txt to $log 
    exec 1>&3 2>&4 3>&- 4>&- # restore 1 and 2 
} 

3>&- закрывается 3, просто для полноты картины.

1

Это должно сделать это

#!/bin/bash 
function function1() { 
    log=${1}.log 

    echo checking $log 
    echo txt to $log >$log 
} 

function1 log1 
function1 log2 

exit 0 

Там нет причин, чтобы сохранить изменения какого-либо конкретный дескриптор файла, когда вы используете только измененные назначения один раз.

Если вы хотите использовать этот подход, скажем, потому что вы перенаправлять много команд, у вас есть по крайней мере 2 вариант:

  • прогонов Перенаправление и связанные с ними команды в субоболочке, так что, когда он выйдет, вы по-прежнему имеете дело с исходными потоками.
  • обрабатывать переадресацию, как регистры, которые должны быть сохранены в вызове функции - перетащите их во временный (как в вашем &3 выше), а затем восстановите их после вызова.
+0

Спасибо, но я буду использовать его много раз. Сценарий большой, это просто задача представлять проблему. Мне не нравится идея использовать перенаправление повсюду. Существует также много вызовов функции. – andrej

+0

Спасибо за указание на направление, я не знаю, как работать с подоболочкой или регистрами. Я буду смотреть в него. – andrej

1

Не знаю, почему вы хотели бы сделать это таким образом, а другой ответ будет намного лучше, если вы не раскрываете всю информацию, но проблема заключается в вашем понимании того, как работают дескрипторы файлов.

Первый раз

exec 3>&1  ## Assign 3 to where 1 is currently pointing which is /dev/tty 
exec 1>>$log ## assigns 1 to point to logfile 
exec 2>&1  ## Assigns stderr to the 1 which currently points at the logfile 

Второй раз

exec 3>&1  ## Assign 3 to where 1 is currently pointing which is the old logfile 
exec 1>>$log ## assigns 1 to point to new logfile 
exec 2>&1  ## Assigns stderr to the 1 which currently points at the new logfile 

Как вы можете увидеть файл дескрипторы вспомнить, где они указывают и просто указывают на то, что Вы говорите им.

Если вы хотите сделать это таким образом, вместо того, чтобы перенаправлять на 1, просто перенаправляйте прямо в/dev/tty, так как в отличие от 1 это никогда не изменится (надеюсь!).

#!/bin/bash 
function function1() { 
    log=${1}.log 

    exec 3>/dev/tty 
    exec 1>>$log 
    exec 2>&1 


    echo checking $log >&3 
    echo txt to $log 

    exec 1>/dev/tty # Probably want this line as well so your not writing to 
        # the logfile for the rest of the script 
} 

function1 log1 
function1 log2 

exit 0 
+0

Спасибо за объяснение. Я прошу прощения, если мое объяснение не было ясным о проблеме, но я, конечно, не намеренно «не раскрывал всю информацию», – andrej

Смежные вопросы