Передайте несколько команд, чтобы собираться

11
flock -x -w 5 ~/counter.txt 'COUNTER=$(cat ~/counter.txt); echo $((COUNTER + 1)) > ~/counter.txt'

Как бы я передал несколько команд, flockкак в примере выше?

Насколько я понимаю, flockпринимает различные флаги (-x для исключительного, -w для тайм-аута), затем файл для блокировки, а затем команду для запуска. Я не уверен, как мне передать две команды в эту функцию (установить переменную с содержимым заблокированного файла, а затем увеличить этот файл).

Моя цель здесь состоит в том, чтобы создать несколько атомарный приращение для файла, блокируя его каждый раз, когда скрипт пытается получить доступ к counter.txtфайлу.

d -_- б
источник

Ответы:

7

Вызовите оболочку явно.

flock -x -w 5 ~/counter.txt sh -c 'COUNTER=$(cat counter.txt); echo $((COUNTER + 1)) > ~/counter.txt'

Обратите внимание, что любая изменяемая вами переменная является локальной для этого экземпляра оболочки. Например, COUNTERпеременная не будет обновлена ​​в вызывающем скрипте: вам придется прочитать ее обратно из файла (но она могла измениться за это время) или как результат вывода команды:

new_counter=$(flock -x -w 5 ~/counter.txt sh -c 'COUNTER=$(cat counter.txt); echo $((COUNTER + 1)) | tee ~/counter.txt')
Жиль "ТАК - перестань быть злым"
источник
офигенно, спасибо большое! Объяснение, которое вы дали, определенно спасло меня от еще одного часа головной боли
d -_- b
4

Или вы можете собирать файловый дескриптор

exec {counterfd}<~/counter.txt
flock -x -w 5 "$counterfd"
COUNTER=$(cat ~/counter.txt)
COUNTER=$(( COUNTER +1 ))
echo "$COUNTER" >~/counter.txt
exec {counterfd}<&-

Это также имеет то преимущество, что позволяет использовать переменную counter напрямую, в отличие от подходов, основанных на подоболочках.

Ричард Мо
источник
Пожалуйста, не могли бы вы объяснить exec {counterfd}? Сам Debian ошибается not found, но возвращает 0 с перенаправлением. Очень странный.
Стив Алмонд
2

flockИнструмент немного сложнее в использовании и страница людей довольно короткая. Страница man предоставляет три способа использования инструмента:

  • flock [options] <file|directory> <command> [command args]
  • flock [options] <file|directory> -c <command>
  • flock [options] <file descriptor number>

То, как этот вопрос сформулирован, я бы определенно использовал третью форму flock. Если вы пойдете дальше на странице руководства, flockесть несколько примеров, в которых показан точный синтаксис использования третьей формы:

#!/bin/bash
(
 flock -n 9 || exit 1
 echo "commands executed under lock..."
 echo "go here..."
) 9>/tmp/mylockfile

Я добавил #!/bin/bash.

Я успешно использовал эту форму flock.

Тревор Бойд Смит
источник