Профиты от использования консольного FTP-клиент lftp

Занимаясь веб-разработкой мы часто сталкиваемся с такой типовой задачей: надо забрать с клиентского хостинга сайт, что-то там покрутить, вернуть обновлённую версию обратно. При этом клиентские виртуальные хостинги бывают разные: не на каждом есть SSH или SFTP доступ. Зато старый пыльный FTP есть везде. Если задача простая и затрагивает 1-2 файла, то их «забирает» напрямую программист к себе в IDE, редактирует и выгружает обновления на боевой хост, благо современные IDE снабжены FTP-клиентами. Но если задача требует экспериментов или тестирования, то на боевом клиентском хостинге её решать нельзя стыдно, надо делать «зеркало» у себя. А значит необходим удобный инструмент, позволяющий забрать файлы сайта к себе на сервер по FTP и потом выгрузить их обратно. Задачу блестяще решает консольный FTP-клиент lftp.

Вообще мы долго обходились возможностями mc, но наш серверный администратор на него ругается, не рекомендует через него лазить по многогигабайтным tar`ам, качать большие сайты по FTP и т.д. И также сразу отмечу, что идейно верным решением был бы rsync, но из-за того, что не к любому виртуальному хостингу его применишь — он не подходит тоже. Поэтому вернёмся к герою сегодняшнего обзора.

В Ubuntu из коробки lftp отсутствует, поэтому для начала экспериментов надо его установить. Как обычно:

sudo apt-get install lftp

Далее можно смело запускать программу, для удобства сразу же передав ей реквизиты удалённого хоста в формате логин:пароль@хост (такой же стандарт используется в mc и вообще описан в RFC 1738):

lftp ftp://user:PassW0rd@example.com

После успешного коннекта вас ждёт приглашение вида:

lftp user@example.com:~>

Теперь вы можете вводить команды в интерактивном режиме. К счастью, запомнить придётся только несколько самых простых и понятных команд, потом сразу перейдём к самому вкусному.

  • exit — выход из lftp
  • pwd — вывод текущего пути на удалённом сервере (в общем, помогает узнать, где вы находитесь в структуре файлов и каталогов)
  • ls — листинг текущей директории на удалённом сервере
  • ls -al — листинг с расширенными параметрами представления (объём, права и т.п.)
  • cd dir — переход в директорию dir на удалённом сервере
  • lpwd — вывод текущего пути на локальной машине (куда по умолчанию будут скачиваться файлы и директории или откуда закачивать на удалённый сервер)
  • lcd dir — переход в директорию dir на локальной машине
  • !ls — листинг текущей директории на локальной машине (на самом деле, вы можете после ! написать любую команду и она будет выполнена локально: например, вместо lpwd можно использовать !pwd)
  • !ls -al — ну, вы поняли
  • get file — скачать file из текущей директории удалённого сервера в текущую локальную директорию (file может быть не только относительным, но и абсолютным именем, что конечно же позволяет забирать файл не обязательно из текущей директории)
  • get rfile -o lfile — скачать rfile с удалённого сервера и сохранить на локальном как rfile
  • put file — закачать file из локальной директории на удалённый сервер
  • put lfile -o rfile — закачать lfile на удалённый сервер как rfile
  • help — справка по доступным командам (вы удивитесь, но среди команд есть torrent — и, да, это простенький встроенный торрент-клиент)

Перечисленного выше минимума хватит чтобы освоиться и что-то сделать руками. Но руками придётся делать немногое, поскольку мы переходим к самому вкусному — команде mirror. Простейшие примеры использования:

  • mirror public_html — синхронизирует директорию public_html с удалённого сервера на локальный, включая все поддиректории и файлы, с сохранением прав и всего такого прочего
  • mirror -R public_html — синхронизирует директорию public_html в обратном направлении, с локальной машины на удалённую

Тут с удовольствием поясню, что значит «синхронизирует». При первом запуске будет произведено полное рекурсивное копирование. Но при повторных запусках передаваться по сети будут только те файлы, которые изменились с момента предыдущей синхронизации. Насколько я понял, факт изменения устанавливается по двум параметрам: дата последнего сохранения файла и его объём. Никакие хеши, конечно, не считаются, но и без с них, к счастью, мы сильно сокращаем скорость синхронизации и объём передаваемых данных.

Вот пример отчёта о первой синхронизации (скачивании) довольно большого сайта в несколько гигабайт:

Total: 1307 directories, 48196 files, 0 symlinks New: 48196 files, 0 symlinks

3962870501 bytes transferred in 495 seconds (7.64M/s)

Зато повторный запуск и выполнение той же команды занимает несколько секунд (в этом конкретном случае около 20). И отчёт мы получаем примерно такой:

Total: 1307 directories, 48196 files, 0 symlinks
New: 10 files, 0 symlinks

В итоге в нашем распоряжении оказывается современный механизм (синхронизация) поверх древних технологий (FTP). И это отлично!

В интерактивный режим lftp входить не обязательно, можно из локальной консоли сразу дать такую команду, чтобы директорию синхронизировалась, например:

lftp -e 'mirror -c public_html /var/www/testsite/public_html; bye;' ftp://user:PassW0rd@example.com

Ключ -e для lftp позволяет указать команду(ы) для выполнения, а после команд идёт хост с реквизитами доступа.

Параметром ключу -e мы в кавычках передаём последовательность команд, сначала команду mirror, она будет синхронизировать контент из удалённой папки ./public_html в локальную /var/www/testsite/public_html, потом FTP-команду bye — для закрытия соединения.

Ключ для команды mirror активирует докачку (поэтому его лучше всегда использовать).

Для верности дам ещё один пример, в котором мы обратно на удалённый сервер синхронизируем данные из локальной директории (например, после того, как изменим пару файлов локально):

lftp -e 'mirror -c -R /var/www/testsite/public_html public_html; bye;' ftp://user:PassW0rd@example.com

Разница тут в том, что мы добавили уже известный ключ -R, ну и поменяли местами каталоги (сначала указывается откуда, а потом куда синхронизировать).

Можно любую последовательность команд вынести в отдельный файл и запустить lftp с ключом -f для выполнения этой последовательности:

lftp -f commands.ftp

Контент commands.ftp может быть таким (для примера выполню там те же действия, что и в предыдущем запуске):

open ftp://user:PassW0rd@example.com mirror -c -R /var/www/testsite/public_html public_html

exit

В интерактивном режиме lftp позволяет легко устанавливать кодировки для удалённого сервера. Вот так:

set ftp:charset cp1251

Ещё одна полезная опция (которая по умолчанию добавляет ключ -a к FTP-команде LIST на удалённом сервере, в результате чего начинают видеться и копироваться «скрытые» файлы и папки, названия которых начинаются с точки):

set ftp:list-options -a

Вообще команда set позволяет на лету и на время перенастраивать lftp не лазя руками в конфиг. Все действующие параметры конфига можно посмотреть так:

set -a

Базовый конфиг хранится в /etc/lftp.conf, а логи и история хранятся в директории ~/.lftp отдельно для каждого пользователя.

Могу вам порекомендовать в базовом конфиге раскомментировать вот эти две строчки (ищите их ближе к концу файла /etc/lftp.conf):

set at-exit "set > ~/.lftp/settings"
source ~/.lftp/settings

Тогда все настройки, задаваемые через set будут сохранятся перед выходом из lftp.

Кроме упомянутого торрент-клиента в lftp есть ещё много примочек, например, очереди (см. help queue в интерактивном режиме) и альясы (см. help alias). lftp умеет работать с протоколами FTPS, FISH и SFTP, т.е. если к файловой системе хостинга есть хоть какой-то доступ, то lftp вам поможет забрать и выгрузить файлы. А ещё lftp поддерживает FXP — это протокол, позволяющий передавать файлы с одного FTP-сервера на другой напрямую, не копируя их на локальную машину. В lftp такая передача реализуется командой типа get ftp://... -o ftp://...

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

»

Оцените статью
Про Ubuntu — блог о популярном СПО GNU/Linux-дистрибутиве Ubuntu (Убунту Линукс)