Смущен перенаправлением exec в / dev / null, правильно ли я это делаю? - PullRequest
0 голосов
/ 20 апреля 2019

Фон

Я тренируюсь в POSIX сценариях оболочки, пожалуйста, избегайте любых Bashism во время ответа. Спасибо.

Теперь я знаю, благодаря Кусалананде answer , как определить, работает ли мой скрипт в интерактивном режиме, т.е. когда он подключен к stdin.


Вопрос

Поскольку я редко использую exec ( man-страницу ), я не уверен, правильно ли я делаю следующую идею? Пожалуйста, уточните.

Если скрипт запущен:

  • в интерактивном режиме : выводить сообщения об ошибках в stderr, иначе запускаться с настройками среды по умолчанию.

  • неинтерактивно : перенаправить весь вывод в /dev/null в этом примере (в конце я, вероятно, захочу перенаправить stdout и stderr в актуальные файлы).


Код

# test if file descriptor 0 = standard input is connected to the terminal
running_interactively () { [ -t 0 ]; }

# if not running interactively, then redirect all output from this script to the black hole
! running_interactively && exec > /dev/null 2>&1

print_error_and_exit ()
{
    # if running interactively, then redirect all output from this function to standard error stream
    running_interactively && exec >&2

    ...
}

1 Ответ

0 голосов
/ 20 апреля 2019

Кажется, я был близко. Поскольку функция running_interactively работала должным образом, я смог перейти к перенаправлению на файлы следующим образом.

Я отредактировал этот ответ, чтобы иметь больше кода для повторного использования.


#!/bin/sh

is_running_interactively ()
# test if file descriptor 0 = standard input is connected to the terminal
{
    # test if stdin is connected
    [ -t 0 ]
}

redirect_output_to_files ()
# redirect stdout and stderr
# - from this script as a whole
# - to the specified files;
#   these are located in the script's directory
{
    # get the path to the script
    script_dir=$( dirname "${0}" )

    # redirect stdout and stderr to separate files
    exec >> "${script_dir}"/stdout \
        2>> "${script_dir}"/stderr
}

is_running_interactively ||
# if not running interactively, add a new line along with a date timestamp
# before any other output as we are adding the output to both logs
{
    redirect_output_to_files
    printf '\n'; printf '\n' >&2
    date; date >&2
}

print_error_and_exit ()
{
    # if running interactively redirect all output from this function to stderr
    is_running_interactively && exec >&2
    ...
}
...