Принятие your-filter
считывает его данные с stdin:
while your-filter; do
sleep 60
done < file.log
Это принимает your-filter
просто считывает данные и не пытается lseek
в нем, например.
Теперь, для решения проблемы вращения журнала, если на Linux (где, вопреки большинству других систем, /dev/fd/n
символьные ссылки на фактические файлы), с ksh
, bash
, zsh
, dash
, yash
(большая часть POSIX окружает кроме наиболее педантично POSIX как posh
как -ef
не POSIX):
while your-filter; do
if [ file.log -ef /dev/stdin ]; then
sleep 60
else
exec < file.log
fi
done < file.log
После вращения журнала, которое звонило бы your-filter
дважды, если Вы быть бы то, чтобы он был названным однажды с конкатенацией старого и нового:
while
if [ file.log -ef /dev/stdin ]; then
your-filter
else
exec 3<&0 < file.log
(cat <&3; cat) | your-filter &&
exec 3<&-
fi
do
sleep 60
done < file.log
Теперь после вращения журнала, может быть время, когда старый file.log был переименован, но новое file.log
не созданный все же, в этом случае вышеупомянутое перестанет работать, если оно сделает exec < file.log
в ту же минуту. Затем Вы могли зафиксировать это с:
while
if [ file.log -ef /dev/stdin ] || ! command exec 3< file.log; then
your-filter
else
(cat; cat <&3) | your-filter &&
exec <&3 3<&-
fi
do
sleep 60
done < file.log
Таким образом, это продолжает читать старый файл, пока новый не обнаруживается.
command
необходим для предотвращения exec
заставить оболочку выходить, когда это перестало работать (поскольку POSIX требует). Это не нужно с zsh
или bash
если не в sh
режим.
Теперь, мы спим в течение 60 секунд в цикле, и your-filter
мог бы занять несколько секунд для выполнения. Если это важно для your-filter
выполняться каждую минуту в среднем, с ksh
, bash
или zsh
, Вы могли изменить его на:
t=$SECONDS
while
if [ file.log -ef /dev/stdin ] || ! command exec 3< file.log; then
your-filter
else
(cat; cat <&3) | your-filter &&
exec <&3 3<&-
fi
do
t=$(($t + 60))
sleep "$((t - SECONDS))"
done < file.log
С ksh93
и zsh
, и обеспеченный Ваш sleep
принимает аргументы с плавающей точкой, Вы могли работать typeset -F SECONDS
.
Хорошо, я предполагаю, что это проблема udev
(большинство дистрибутивов Linux используют ее default), это то, что создает символические ссылки. Вы можете исправить это, добавив новое правило. Я дам некоторую информацию по этому поводу, но она в значительной степени привязана к моему собственному дистрибутиву - Debian.
Прежде всего, вам нужно выяснить, где находятся ваши правила.В Debian они есть в двух местах - /lib/udev/rules.d
и /etc/udev/rules.d
. Если это так, вам следует добавлять / изменять только те, которые находятся в / etc
, поскольку изменение другого местоположения с большей вероятностью приведет к перезаписи при обновлении.
Перейдите в каталог правил и посмотрите, сможете ли вы найти файл (ы) с правилами для создания ссылок в disk / by-id
. Здесь поможет команда grep -r disk / by-id /
(хотя запускайте ее только в каталоге правил, чтобы избежать поиска в других местах). Для меня это /var/lib/rules.d/60-persistent-storage.rules
. Вот строки, которые создают для меня ссылки «disk / by-id / usb- *»:
ENV{DEVTYPE}=="disk", ENV{ID_BUS}=="?*", ENV{ID_SERIAL}=="?*", \
SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
ENV{DEVTYPE}=="partition", ENV{ID_BUS}=="?*", ENV{ID_SERIAL}=="?*", \
SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
Здесь есть две возможности (кроме той, где ваша система не использует udev
вообще):
Строки могут выглядеть как тарабарщина, но в основном первые две (на самом деле одна, поскольку \
- это просто способ разделения длинной строки) предназначены для ссылок, относящихся к самому диску, а две другие - для его перегородки.
Надеюсь, выполнение этой команды должно упростить задачу:
udevadm info --name=/dev/sdb --query=property
Здесь отображаются имена / значения всех свойств вашего устройства. По сути, все, что делает правило, это просматривает все свойства каждого устройства и сопоставляет их с первой частью строки (например, первое ищет устройства с DEVTYPE = disk
и непустым ID_BUS
и ID_SERIAL
).Следующая часть создает символическую ссылку, имя которой содержит ID_BUS
и ID_SERIAL
.
В любом случае, это сводится к тому, что если у вас есть ID_BUS = usb
, вы, вероятно, можете пойти дальше и добавить вышеупомянутое правило. В противном случае вам, вероятно, потребуется добавить определенные правила для вашего устройства. Что-то вроде:
ENV{ID_SERIAL}=="SAMSUNG_HM321HX_C5733G82AB0BPW", \
SYMLINK+="disk/by-id/usb-$env{ID_SERIAL}"
ENV{ID_SERIAL}=="SAMSUNG_HM321HX_C5733G82AB0BPW", \
SYMLINK+="disk/by-id/usb-$env{ID_SERIAL}-part%n"
Я угадал ваш ID_SERIAL
из вопроса, если он неправильный, вставьте правильный.
Правила, вероятно, лучше всего поместить в отдельный файл, например s2-samsung-usb.rules
в каталоге, который вы нашли в начале.
Обновление: вероятно, приведенное ниже не является необходимым, просто отключите и снова подключите устройство - Как перезагрузить правила udev без перезагрузки?
Как только вы закончите, вы можете перезагрузить правила с помощью (unplug сначала ваше устройство):
udevadm control --reload-rules
Затем снова подключите устройство. Если это не сработает, вы всегда можете попробовать перезагрузиться (на самом деле это может быть безопаснее).