Перейти к содержимому
ecdsa.com
Git commit signing with GnuPG 2Git

Сообщение об ошибке

gpg: signing failed: Inappropriate ioctl for device

Также выводится как

  • [GNUPG:] FAILURE sign 83918950

Git выводит это сообщение под строкой «error: gpg failed to sign the data». С `--status-fd` gpg также выдаёт `[GNUPG:] FAILURE sign 83918950` (числовой код ошибки GPG для этой ситуации).

Git commit signing with GnuPG 2 — pinentry has no terminal

Что это означает

Ключ подписи защищён парольной фразой, gpg-agent запустил терминальный pinentry, чтобы её запросить, а pinentry не смог открыть терминал. «Inappropriate ioctl for device» — это `ENOTTY` операционной системы: stdin — не TTY, а `GPG_TTY` не указывает ни на один TTY. С ключом и конфигурацией всё в порядке: не удался только запрос парольной фразы.

Почему это происходит

Как исправить

  1. 1.

    Экспортируйте GPG_TTY

    Добавьте экспорт в профиль оболочки; если запущенный агент стартовал из другого терминала, обновите его командой `updatestartuptty`.

    bash
    # ~/.bashrc or ~/.zshrc
    export GPG_TTY=$(tty)
    # if gpg-agent was started before, tell it about the current terminal
    gpg-connect-agent updatestartuptty /bye
  2. 2.

    Используйте графический pinentry

    `pinentry-mac`, `pinentry-gnome3` или `pinentry-qt` показывают диалоговое окно, которое работает и при запуске из IDE.

    bash
    # macOS (Homebrew): a GUI pinentry works for IDEs and GUI Git clients too
    brew install pinentry-mac
    echo "pinentry-program $(brew --prefix)/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
    gpgconf --kill gpg-agent
  3. 3.

    Loopback-режим pinentry для автоматизации

    С `allow-loopback-pinentry` gpg может читать парольную фразу из файла. Используйте отдельный ключ для CI, предназначенный только для подписи, и никогда не используйте личный ключ.

    bash
    # CI: a dedicated signing key; passphrase supplied non-interactively via loopback pinentry
    echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf && gpgconf --kill gpg-agent
    cat > /usr/local/bin/gpg-ci <<'EOF'
    #!/bin/sh
    exec gpg --batch --pinentry-mode loopback --passphrase-file "$GPG_PASSPHRASE_FILE" "$@"
    EOF
    chmod +x /usr/local/bin/gpg-ci
    git config --global gpg.program gpg-ci

Связанные ошибки

Открыть всю базу ошибок подписей