Существует ли способ изменить идентификатор устройства в/dev/disk/by-id?

Принятие 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.

3
21.08.2018, 01:15
1 ответ

Хорошо, я предполагаю, что это проблема 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 вообще):

  1. У вас нет строки, похожей на эту, и вам нужно ее создать.
  2. Да, но это просто не работает для вашего диска.

Строки могут выглядеть как тарабарщина, но в основном первые две (на самом деле одна, поскольку \ - это просто способ разделения длинной строки) предназначены для ссылок, относящихся к самому диску, а две другие - для его перегородки.

Надеюсь, выполнение этой команды должно упростить задачу:

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

Затем снова подключите устройство. Если это не сработает, вы всегда можете попробовать перезагрузиться (на самом деле это может быть безопаснее).

6
27.01.2020, 21:14

Теги

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