Есть ли инструмент для динамического перенаправления вывода в новый файл по запросу

Вы можете использовать обратные знаки, чтобы сохранить результат команды (в моем примере это uname) в переменной, затем echo его на экране, и в конечном итоге использовать его как аргумент для mkdir:

FOO=`uname -n`
echo "$FOO"
mkdir "$FOO" 

В отличном руководстве Advanced Bash-Scripting Guide есть целая глава о подстановке команд.

Как заметил @KalvinLee, сейчас предпочтительным форматом является $(...):

FOO=$(uname -n)

8
04.05.2016, 19:46
5 ответов

Я предлагаю именованную трубу.

  1. Создайте трубу mkfifo p (назовите ее как угодно, если не 'p')

  2. Создайте "читающий" скрипт, который читает из трубы и пишет куда хотите

  3. Скажите программе мониторинга записывать свои логи в именованную трубу

Вот пример читающего скрипта, который читает из именованной трубы 'p' и записывает данные в индексированный файл 'mylog':

#!/bin/sh

INDEX=0

switchlog() {
  read INDEX < newindex
  echo now writing to "mylog.$INDEX"
}

trap switchlog USR1

while :
do
  cat p >> mylog."$INDEX"
done
9
27.01.2020, 20:09

Основываясь на вашей идее SIGINT, здесь используется SIGQUIT ( Ctrl + \ ), чтобы вы все еще могли использовать Ctrl + C , чтобы остановить все это:

(trap '' QUIT; monitor_command) | (
   trap : QUIT
   ulimit -c 0 # prevent core dump so SIGQUIT behaves like SIGINT
               # for cat
   n=0; while n=$((n+1)); file=output.$n.log; do
     printf 'Outputting to "%s"\n' "$file"
     cat > "$file"
   done)

Предполагается, что cat не является встроенным в вашей оболочке (поэтому он прерывается нажатием Ctrl + \ ).

Обратите внимание, что, как и в вашем подходе, существует вероятность того, что SIGQUIT будет доставлен в неправильное время (в системном вызове записи), что приведет к потере некоторых данных.

7
27.01.2020, 20:09

Благодаря ответу Джеффа Шаллера у меня получилось что-то вроде этого, которое в основном делает то, что мне нужно, назовем его reader.sh :

#!/bin/sh

INDEX=0
LOGNAME="$INDEX.log"

switchlog() {
  local custom_name
  read -p "Add log name: " custom_name
  INDEX=$((INDEX+1))
  LOGNAME="$(printf "%03d" $INDEX).$custom_name.log"
  echo now writing to $LOGNAME
}

trap switchlog INT
switchlog

while :
do
  read foo < p
  printf "%s\n" "$foo" >> "$LOGNAME"
done

Тогда речь идет о создании именованного канала с помощью mkfifo p и использовании двух терминалов, где monitor_program> p и reader.sh запущены. Затем я могу остановить программу чтения, чтобы установить новый журнал, используя Ctrl + C , и ввести новое имя. Ctrl + Z , как обычно, чтобы остановить и убить его.

0
27.01.2020, 20:09

Не зная больше о вашем «запросе», на него невозможно ответить. Если бы это было основано на размере файла или интервале, то rotatelogs (который должен поставляться в комплекте с Apache httpd) работал бы.

0
27.01.2020, 20:09

Вероятно, вы могли бы использовать less и сохранить оттуда, набрав s , а затем имя файла, которое вы хотите сохранить в, затем Введите . Из Как мне записать все строки из less в файл? .

1
27.01.2020, 20:09

Теги

Похожие вопросы