Вопрос или проблема
В качестве эксперимента я пытаюсь написать сценарий, в котором я направляю ZIP-файл в unzip
на своем сервере через ssh
. Однако что, если у меня не настроены ключи SSH, и мне предлагается ввести пароль? Я бы все равно хотел, чтобы он поступал из stdin
, а не из ZIP-файла. ЗАТЕМ я хочу направить ZIP-файл в unzip
, как только установится соединение (возможно, используя два отдельных входных потока, один для пароля SSH, другой для процесса unzip
, который запускает ssh
?).
Также я в настоящее время записываю в /tmp
на сервере, а затем удаляю, потому что unzip
, похоже, не нравится /dev/stdin
на моем сервере (я использую Arch, сервер работает на Ubuntu 20.04). /dev/stdin
работает, когда я направляю в пределах сеанса ssh
, работает, когда я направляю на своей машине, но не работает, когда я направляю С моей машины в ssh
. Почему?
У вас, кажется, две несвязанные проблемы.
- Как программно передать пароль в
ssh
.
Как уже отмечено в комментариях, ssh
не читает пароль из stdin (потока); он читает непосредственно из терминала. Таким образом, вы не можете передать пароль в ssh
через поток, но вы можете сделать это, используя инструмент sshpass
(его нужно установить), как это:
sshpass -p 'password' ssh user@host
Или вы можете считать пароль из файла, вместо того чтобы передавать его напрямую в командной строке:
sshpass -f passwordfile.txt ssh user@host
Вы также, вероятно (я не проверял), можете использовать команду plink
, которая является частью PuTTY for Linux вместо ssh
. plink
принимает пароль в качестве параметра:
plink -pw 'password' user@host
unzip
не принимает ввод из stdin.
Согласно тексту, отображаемому unzip -hh
, unzip
просто не поддерживает чтение zip-файла из stdin. Если вы хотите распаковать файл, который вы предоставляете через stdin, вы должны использовать утилиту funzip
, как это:
cat file.zip | funzip >file.out
или
funzip <file.zip >file.out
Однако учтите, что funzip
извлекает только первый файл из zip-файла.
Таким образом, комбинируя эти две проблемы, вам нужно будет использовать следующую команду:
cat file.zip | sshpass -p 'password' ssh user@host "funzip >file.out"
или
sshpass -p 'password' ssh user@host "funzip >file.out" <file.zip
Заключение команды funzip >file.out
в кавычки приводит к тому, что файл file.out
создается на удаленном компьютере, а не на вашем локальном (если вы уберете кавычки, файл будет создан на вашей локальной машине).
Ответ или решение
При решении задачи передачи ZIP-файла на сервер для последующей распаковки с использованием SSH необходимо учитывать несколько технических нюансов.
Проблема с предоставлением пароля для SSH
По умолчанию SSH запрашивает пароль напрямую с терминала, из-за чего невозможно передать его через стандартный ввод (stdin). Чтобы обойти это ограничение, можно воспользоваться инструментом sshpass
, который позволяет автоматизировать ввод пароля для сеанса SSH.
Использование sshpass
-
Установка sshpass: Перед началом работы убедитесь, что
sshpass
установлен на вашей системе. На системах на базе Ubuntu это можно сделать с помощью команды:sudo apt install sshpass
-
Передача файла и пароля: Для передачи ZIP-файла через SSH и распаковки его удаленно можно использовать следующую конструкцию:
sshpass -p 'ваш_пароль' ssh пользователь@хост "unzip -o > /tmp/output_dir" < ваш_файл.zip
В данном примере
ваш_пароль
— это пароль для подключения к серверу,пользователь@хост
— учетные данные и адрес сервера, аваш_файл.zip
— путь к локальному ZIP-файлу.
Проблема с распаковкой ZIP-файла с использованием stdin
Некоторые версии unzip
могут иметь сложности с обработкой архивов через stdin. В таких случаях стоит использовать утилиту funzip
, которая распаковывает содержимое, переданное через стандартный ввод, но только первый файл архива. Если вам необходимо извлечь весь архив, а не только первый файл, стоит записать файл во временную директорию на сервере и затем распаковать его обычным способом.
Пример с использованием funzip
cat ваш_файл.zip | sshpass -p 'ваш_пароль' ssh пользователь@хост "funzip > /tmp/output_file"
Обратите внимание: funzip
подходит только для извлечения одного файла. Если в архиве содержится несколько файлов, funzip
не подойдет.
Вывод
Для решения вашей задачи необходимо четко разграничивать процесс передачи пароля системой аутентификации SSH (с помощью sshpass
) и процесс обработки архива с учетом ограничений вашего окружения. Учитывая указанные выше нюансы, можно эффективно автоматизировать задачу извлечения данных на удаленном сервере.
Важно также помнить о безопасном хранении пароля и не хардкодить его непосредственно в скриптах в открытом виде, используйте защищенные методы передачи конфиденциальных данных.