Передайте кілька команд на зграю


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

Як я можу передати кілька команд, flockяк у наведеному вище прикладі?

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

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

Відповіді:


8

Викликайте оболонку прямо.

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}<&-

Це також має перевагу, що дозволяє безпосередньо використовувати змінну лічильника, на відміну від підходів, що базуються на нижній частині.


Будь ласка, поясніть 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. Якщо ви перейдете далі на сторінку "man", flockто є кілька прикладів, які показують точний синтаксис використання третьої форми:

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

Я додав #!/bin/bash.

Я успішно використовував цю форму flock.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.