2013-08-01 2 views
0

Это упрощенная версия используемого сценария: В упрощенной версии tt следует читать файл input по очереди, а затем печатать его на стандартный вывод, а также записывать на файл log.Командная строка, появляющаяся во время выполнения сценария bash

input файл:

asas 
haha 
asha 
hxa 

Сценарий (названный simple):

#!/bin/bash 

FILE=input 
logfile="log" 

exec > >(tee "$logfile") # redirect the output to a file but keep it on stdout 
exec 2>&1 

DONE=false 
until $DONE; do 
read || DONE=true 
    [[ ! $REPLY ]] && continue      #checks if a line is empty 

    echo "----------------------" 

    echo $REPLY 

done < "$FILE" 
echo "----------------------" 
echo ">>> Finished" 

Выход (на консоли):

-bash-3.2$ ./simple 
-bash-3.2$ ---------------------- 
asas 
---------------------- 
haha 
---------------------- 
asha 
---------------------- 
hxa 
---------------------- 
>>> Finished 

В это время мне нужно нажать войти для завершения сценария. Обратите внимание, что во время выполнения появилось командное приглашение -bash-3.2$.

Я проверил, что эти строки виноваты:

exec > >(tee "$logfile") # redirect the output to a file but keep it on stdout 
exec 2>&1 

Без них выход, как ожидается:

-bash-3.2$ ./simple 
---------------------- 
asas 
---------------------- 
haha 
---------------------- 
asha 
---------------------- 
hxa 
---------------------- 
>>> Finished 
-bash-3.2$ 

Что больше не нужно нажимать ввести для завершения сценария , К сожалению, мне нужно сохранить вывод как на консоль (stdout), так и на файл журнала.

Как это можно исправить?

ответ

1

Вы можете использовать tee на эхо-линии непосредственно.

Например:

[[email protected] ~]$ echo "echo and save to log" | tee -a example.log 
echo and save to log 
[[email protected] ~]$ cat example.log 
echo and save to log 

-a аргумент tee будет добавлять в журнал.

+0

Можно ли исправить это, не изменяя каждое 'echo' во всем скрипте? Скрипт очень большой. –

+0

Если вы не хотите изменять все, и вы не против записи в журнал _everything_, вы можете выполнить сам скрипт, например. '$ ./your_script.sh | tee -a $ LOG_FILE.' – Ben

1

Если вам просто нужно это сделать паузу и ждать ввода пользователя с помощью команды паузы:

pause 
+0

Это не отвечает на мой вопрос. –

1

Происходит то, что tee "$logfile" запускается асинхронно. Когда вы используете подобную замену, основной скрипт не ждет завершения процесса.

Таким образом, цикл цикла until запускается, главный сценарий завершается, оболочка печатает приглашение, а затем tee печатает свой вывод.

Вы можете увидеть это более легко с:

echo Something > >(sleep 5; cat) 

Вы получите командную строку, а затем через 5 секунд Something появится.

Об этом поведении в comp.unix.shell было сообщено пару лет назад. См. Его here

+0

'Когда вы используете подобную подстановку, основной скрипт не ждет завершения процесса.' Как заставить основной скрипт ждать завершения 'tee'? –

+0

Насколько я знаю, вы не можете. – Barmar

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