У меня есть папка на сервере Ubuntu, где пользователи с разных клиентских машин (также Ubuntu) могут редактировать файлы (через FileZilla, но подойдет любой другой). Однако, когда один пользователь редактирует один файл, этот файл должен быть заблокирован поэтому другие не могут редактировать его одновременно. Это должно быть ожидаемое поведение (и это, в другом месте). Как этого добиться в Ubuntu Server 14.04? Вроде бы простая, даже очевидная задача, но я просто нигде не могу ее найти. Гугл дает мне только «как разблокировать файл, заблокированный кем-то другим».
РЕДАКТИРОВАТЬ
Следуя предложению Lmwangi, я пытаюсь создать сценарий bash для автоматизации задачи. Сначала я использовал NFS для монтирования образа папки сервера на моем клиентском компьютере. Затем я создал в папке сервера следующий скрипт:
flock -nx "$1" xdg-open "$1"
До сих пор не могу это проверить.
должен быть заблокирован ... ожидаемое поведение ...
Ваше понимание семантики блокировки файлов в Linux неверно. Судя по приведенной справочной ссылке, вы основываете свое предположение на семантике файлов Windows. Они не применяются в большинстве систем на основе UNIX.
Я не смог найти очень авторитетного источника, но википедия, однако, тривиальна для тестирования.
https://en.wikipedia.org/wiki/File_locking#In_Unix-like_systems
Unix-подобные операционные системы (включая Linux и Apple OS X) обычно не блокируют автоматически открытые файлы или запущенные программы.
(Википедия ошибается в отношении запуска программ, поэтому я ее отредактировал!)
В Linux это нормальная работа, позволяющая нескольким модулям записи и чтения одновременно работать с одним и тем же файлом.
Это неверно только в том случае, если сам файл является исполняемым объектом, который в данный момент загружен, и вы запрашиваете доступ для записи.
Блокировка файлов выполняется как необязательная опция и осуществляется через fcntl
, flock
или lockf
который все приложения, использующие файл, должны поддерживать и использовать один и тот же метод блокировки для его работы.
Другой часто используемый метод - создать новый файл, который является копией старого файла как файл с временным именем, а затем переименовать его поверх старого файла. Это работает, поскольку все переименования атомарны в файловых системах, совместимых с posix - люди будут видеть либо старый файл, либо новый файл, но не их сочетание.
Если вы хотите, чтобы несколько авторов редактировали один и тот же файл, вам, вероятно, понадобится такой метод, как git
чтобы пользователи могли отправить изменения в репозиторий изменений.
Или, в качестве альтернативы, просто используйте систему Windows, которая выполняет блокировку, которую вы понимаете, если эта функция так важна для вас.
FTP (filezilla) не поддерживает блокировку. Возможно, если вы настроите NFS или SaMBa, тогда сработает обычная блокировка редактора файлов.
Зависит от режима доступа к файлам. Например,
Помощь стаи:
❯ flock -h
Usage:
flock [-sxun][-w #] fd#
flock [-sxon][-w #] file [-c] command...
flock [-sxon][-w #] directory [-c] command...
Options:
-s --shared Get a shared lock
-x --exclusive Get an exclusive lock
-u --unlock Remove a lock
-n --nonblock Fail rather than wait
-w --timeout Wait for a limited amount of time
-o --close Close file descriptor before running command
-c --command Run a single command string through the shell
-h --help Display this text
-V --version Display version
пример.
Первая подоболочка получает блокировку на 20 секунд и отодвигается на задний план. Любой другой процесс (второй) немедленно терпит неудачу, если блокировка получена.
❯ (flock -nx /tmp/a sleep 20 && echo nice..)& flock -nx /tmp/a sleep 20 || echo failed to lock ⏎
[1] 2546
failed to lock
❯ jobs
[1] + running ( flock -nx /tmp/a sleep 20 && echo nice..; )
❯ nice..
[1] + 2546 done ( flock -nx /tmp/a sleep 20 && echo nice..; )
--- редактировать
# Flock using a lock file based on the md5 of the content. I'm being lazy here. I should md5 the filename...
❯ open_something() { md5=$(md5sum /tmp/a | awk '{print $1}'); flock -nx /tmp/$md5 vim "$1" || echo "Oops. Go away" }
# So now let's vim a file and background it immediately.
❯ open_something /tmp/a
[1] + 9185 suspended open_something /tmp/a
❯ jobs
[1] + suspended (signal) open_something /tmp/a
# Let's see whether flock created a lock file based on the md5 of the file and who's using it...
❯ ls /tmp
vagrant VMwareDnD vmware-root a d41d8cd98f00b204e9800998ecf8427e vgauthsvclog.txt.0
❯ fuser /tmp/d41d8cd98f00b204e9800998ecf8427e
/tmp/d41d8cd98f00b204e9800998ecf8427e: 9175 9176
# Another user/process tries to open the file
❯ open_something /tmp/a
Oops. Go away
# Let's kill the original vim process and another process can now acquire the lock.
❯ fg
[1] + 9185 continued open_something /tmp/a
vagrant@ubuntu-trusty ~ ❯❯❯ open_something /tmp/a
Проще говоря, FTP не поддерживает блокировку.
Причина проста: при редактировании файла по протоколу FTP вы действительно не редактировать сам файл на стороне сервера, а вы редактируете загруженная копия то есть повторно загрузить с тем же путем / именем исходного файла.
С другой стороны, такие протоколы, как NFS или SMB, представляют собой протоколы блочного обмена, которые позволяют осуществлять прямое редактирование программным обеспечением на стороне клиента.
Вкратце: если вам нужна блокировка, FTP не подходит.
Здесь нет решения, просто ссылка на более подробное объяснение Я нашел.