Почему exec-команда «git pull» застревает и ничего не печатает?

1

При выполнении следующей команды мне предлагается ввести пароль:

$ git pull
Enter passphrase for key (...)

Когда я пытаюсь показать ту же информацию программно с помощью Apache Commons Exec, программа застревает и ничего не печатает:

CommandLine cmd = new CommandLine( "git" );
cmd.addArgument( "pull" );
DefaultExecutor executor = new DefaultExecutor();
executor.setStreamHandler( new PumpStreamHandler( System.out, System.err, System.in ) );
executor.execute( cmd );

Почему этот пример застрял, не печатая ничего, и при использовании родной консоли он предлагает мне предоставить пароль git?

Теги:
apache-commons
apache-commons-exec

1 ответ

2
Лучший ответ

Это происходит потому, что кодовая фраза SSH должна считываться с pseudo terminal не из STDIN. Вы должны создать поток коммуникации псевдо-tty между родительскими (вашими программами) и дочерними (git) процессами и выполнить всю связь по этому потоку. Взгляните на Pseudo терминал, чтобы использовать с ssh в java, чтобы получить идею.

Также следует отметить, что он не git просит ключевую фразу. git сам не выполняет никакой аутентификации, просто полагаясь на ssh (конечно, только для репозиториев, доступных через ssh). Здесь последовательность действий

  1. git обнаруживает, что данный репозиторий доступен через ssh и вызывает ssh-транспорт
  2. ssh transport определяет, запущен ли на компьютере компьютер-агент проверки подлинности ssh.
  3. Если агент не обнаружен (ваш случай), тогда транспорт переключается на базовую аутентификацию на основе консоли. ssh ожидает "настоящую консоль", поэтому простого перенаправления stdin/stdout недостаточно.
  4. или если агент ssh запущен, вся проверка ключа передается агенту.
  5. Могут существовать различные варианты реализации альтернативных агентов. Некоторые просто спрашивают у пользователя пароль для разблокировки ключа ssh, другие сохраняют набор предварительно разблокированных ключей в памяти и т.д. И в зависимости от характера агента он может отображать приглашение пароля в консоли или открывать новое отдельное окно с подсказкой. Проверьте эту страницу, особенно часть о шпаклевке/конкурсе, чтобы понять, как SSH-аутентификация может быть настроена в Windows.

Вы можете взглянуть на pty4j, который использует JNA для реализации терминального и процесса выполнения низкого уровня. Или взгляните на JGit, который представляет собой чистую java-повторную реализацию git, и он вообще не вызывает командную строку git. JGit является базой, например, для плагина Eclipse Git или системы проверки кода Gerrit, поэтому он разработан и отполирован.

  • 0
    Любая идея о том, как я мог бы решить все проблемы, связанные с обработкой git в Java, без необходимости понимать такие вещи низкого уровня, как это? Библиотека что ли?
  • 0
    После вашего редактирования: JGit - это именно то, что я сейчас использую: D, спасибо!
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню