Я пытаюсь понять, что делает следующий фрагмент сценария оболочки. Я знаю, что exec без аргументов перенаправляет вывод текущей оболочки, но я не могу понять, что делает команда ниже:
exec 1>/var/opt/log/my_logs/MYPROG_`date '+%Y%m%d_%H%M%S'`.log 2>&1
На самом деле существует 4 важных бита информации:
Встроенный модуль exec используется для перенаправления всего вывода для сеанса командной строки на файл. 1><FILENAME> сообщает оболочке redirect stdout, т. е. нормальный вывод ошибок без ошибок будет идти в <FILENAME>. [F8] создаст, если <FILENAME> не существует или усекается, если <FILENAME> уже существует. Переадресованное имя файла создается с помощью дополнительных обратных ссылок с помощью команды date '+%Y%m%d_%H%M%S'. Backticks являются формой Command Substitution и функционально эквивалентны форме $(date '+%Y%m%d_%H%M%S'), и в настоящее время $(...) является предпочтительным для удобочитаемости и потому что эта форма может быть легко вложенной (то есть иметь несколько уровней). Таким образом, вывод date с указанным форматом '+%Y%m%d_%H%M%S' приведет к созданию имени файла, отмеченного по времени. Если ваша команда выполнялась в 2018 году, 4 июля, 4:20:20, выход будет /var/opt/log/my_logs/MYPROG_20180704_042020.log. 2>&1 перенаправляет поток stderr в этот файл также, это стандартный, совместимый с POSIX (что означает, что подобные Bourne оболочки, отличные от bash, понимают его). Это функционально эквивалентно синтаксису &> bash. Порядок заданных перенаправлений в оболочке важен, поэтому почему это появляется после перенаправления 1>.В заключение не должно быть выхода из этой команды. Он должен только обновлять два потока вывода всех последовательных команд, чтобы войти в указанный вами файл.
Интересно, что с этой командой my bash 4.4 выводит все в файл и включает в себя подсказку и все, что я набираю (так вот мне пришлось ввести слепо echo hello world и нажать Ctrl + D, чтобы выйти потом ):
$ bash --posix
bash-4.4$ exec 1>./mylog_`date '+%Y%m%d_%H%M%S'`.log 2>&1
$ cat ./mylog_20180424_010800.log
bash-4.4$ echo hello world
hello world
bash-4.4$ exit
Выполняя это по частям, показывает, что bash выводит запрос на поток stderr и удивительно вместе с тем, что я набираю:
bash-4.4$ exec 1> ./mylog.txt
bash-4.4$ echo Hello World
bash-4.4$ cat ./mylog.txt
cat: ./mylog.txt: input file is output file
bash-4.4$ exec 2>&1
В случае из ksh происходит то же самое, но я могу видеть, что набирается, только запрос переходит к файлу, то есть stdin не перенаправляется:
bash-4.4$ ksh
$ exec 1>./mylog 2>&1
echo hello askubuntu
bash-4.4$ cat ./mylog
$ hello askubuntu
$
bash-4.4$
Итак, здесь мы можем видеть, что оболочки могут выберите вывод PS1 также в один из стандартных потоков, чтобы он включался в файл.
На самом деле существует 4 важных бита информации:
Встроенный модуль exec используется для перенаправления всего вывода для сеанса командной строки на файл. 1><FILENAME> сообщает оболочке redirect stdout, т. е. нормальный вывод ошибок без ошибок будет идти в <FILENAME>. [F8] создаст, если <FILENAME> не существует или усекается, если <FILENAME> уже существует. Переадресованное имя файла создается с помощью дополнительных обратных ссылок с помощью команды date '+%Y%m%d_%H%M%S'. Backticks являются формой Command Substitution и функционально эквивалентны форме $(date '+%Y%m%d_%H%M%S'), и в настоящее время $(...) является предпочтительным для удобочитаемости и потому что эта форма может быть легко вложенной (то есть иметь несколько уровней). Таким образом, вывод date с указанным форматом '+%Y%m%d_%H%M%S' приведет к созданию имени файла, отмеченного по времени. Если ваша команда выполнялась в 2018 году, 4 июля, 4:20:20, выход будет /var/opt/log/my_logs/MYPROG_20180704_042020.log. 2>&1 перенаправляет поток stderr в этот файл также, это стандартный, совместимый с POSIX (что означает, что подобные Bourne оболочки, отличные от bash, понимают его). Это функционально эквивалентно синтаксису &> bash. Порядок заданных перенаправлений в оболочке важен, поэтому почему это появляется после перенаправления 1>.В заключение не должно быть выхода из этой команды. Он должен только обновлять два потока вывода всех последовательных команд, чтобы войти в указанный вами файл.
Интересно, что с этой командой my bash 4.4 выводит все в файл и включает в себя подсказку и все, что я набираю (так вот мне пришлось ввести слепо echo hello world и нажать Ctrl + D, чтобы выйти потом ):
$ bash --posix
bash-4.4$ exec 1>./mylog_`date '+%Y%m%d_%H%M%S'`.log 2>&1
$ cat ./mylog_20180424_010800.log
bash-4.4$ echo hello world
hello world
bash-4.4$ exit
Выполняя это по частям, показывает, что bash выводит запрос на поток stderr и удивительно вместе с тем, что я набираю:
bash-4.4$ exec 1> ./mylog.txt
bash-4.4$ echo Hello World
bash-4.4$ cat ./mylog.txt
cat: ./mylog.txt: input file is output file
bash-4.4$ exec 2>&1
В случае из ksh происходит то же самое, но я могу видеть, что набирается, только запрос переходит к файлу, то есть stdin не перенаправляется:
bash-4.4$ ksh
$ exec 1>./mylog 2>&1
echo hello askubuntu
bash-4.4$ cat ./mylog
$ hello askubuntu
$
bash-4.4$
Итак, здесь мы можем видеть, что оболочки могут выберите вывод PS1 также в один из стандартных потоков, чтобы он включался в файл.