null

Нетрадиционный вызов scp

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

Автоматизируя сборку тестовых стендов, я захотел в скрипте копировать некоторые файлы, а именно развёрнутый Liferay и дамп его базы данных (postgres). Развёрнутый Liferay оказался очень большим, захотелось его заархивировать и немножко сжать. И тут вспомнился один факт об scp, которым можно воспользоваться.

Давайте взглянем на подробный вывод его действий при копировании файла:

% scp -v -P 2242 127.1:/tmp/123 ./ 
Executing: program /usr/bin/ssh host 127.1, user (unspecified), command scp -v -f /tmp/123
OpenSSH_7.9p1 Debian-6, OpenSSL 1.1.1a  20 Nov 2018
[ Применение настроек ]
debug1: Connecting to 127.0.0.1 [127.0.0.1] port 2242.
debug1: Connection established.
[ Попытки установить защищённое соединение по ключу ]
debug1: Next authentication method: password
kk@127.0.0.1's password: 
debug1: Enabling compression at level 6.
debug1: Authentication succeeded (password).
Authenticated to 127.0.0.1 ([127.0.0.1]:2242).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending environment.
[ Отправка переменных окружения ]
debug1: Sending command: scp -v -f /tmp/123
Sending file modes: C0644 0 123
Sink: C0644 0 123
123                                                                                                                                                                                              100%    0     0.0KB/s   00:00    
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
Transferred: sent 2264, received 2800 bytes, in 0.3 seconds
Bytes per second: sent 8422.2, received 10416.2
debug1: Exit status 0
debug1: compress outgoing: raw data 236, compressed 180, factor 0.76
debug1: compress incoming: raw data 1080, compressed 1038, factor 0.96

Самая интересная строка:

debug1: Sending command: scp -v -f /tmp/123

Этот «command» — действительно команда, выполняемая в шелле. Например:

% scp -P 2242 127.1:'/tmp/123; rm /tmp/123' ./
kk@127.0.0.1's password: 
123                                                                                                                                                                                              100%    0     0.0KB/s   00:00    

% scp -P 2242 127.1:/tmp/123 ./            
kk@127.0.0.1's password: 
scp: /tmp/123: No such file or directory

Сработало как надо. Почему именно в шелле, а не просто какой-то exec? Потому что следующий код тоже работает «как надо»:

scp -o SendEnv=GZIP -o SendEnv=PGPASSWORD "www@example.com:\`tar -czf /tmp/$LIFERAY_DIR.tar.gz $LIFERAY_DIR; echo /tmp/$LIFERAY_DIR.tar.gz\`; rm /tmp/$LIFERAY_DIR.tar.gz" 'www@example.com:`pg_dump -h 127.1 -U lportal > /tmp/lportal.sql; echo /tmp/lportal.sql`; rm /tmp/lportal.sql' ./

По мне так интересное решение проблемы.