Voraussetzungen

Voraussetzungen

Bei jeder Ausführung git pushmuss ich in der Eingabeaufforderung meinen Benutzernamen und mein Passwort manuell eingeben.
Ich möchte diesen Vorgang jedoch automatisieren.

Also habe ich versucht, die Anmeldeinformationen per Piping an den Befehl zu übergeben:

printf 'username\npassword' | git push

aber die Eingabeaufforderung für Benutzername und Passwort verschwindet immer noch nicht!
Warum funktioniert es nicht?

Notiz:
Ich weiß, dass dies mit folgendem Verfahren möglich ist: mich interessiert aber, was an der Piping-Methode falsch ist.
git push 'https://username:[email protected]/username/repo.git'


Um zu bestätigen, dass dieser Prozess auch in anderen Fällen funktioniert, habe ich ein Experiment durchgeführt.
Ich habe ein Skript erstellt b.py:

b.py:

#!/usr/bin/env python3

username = input()
password = input()

log = open("log.txt", "w")
print(username + "\n" + password, file=log)

Anschließend habe ich es printf 'abcd\nefgh' | ./b.pyim Terminal ausgeführt. Es funktionierte wie erwartet und führte zu einer Protokolldatei mit den Zeichenfolgen für Benutzername und Kennwort:

log.txt:

abcd
efgh

Antwort1

Dies würde nur bei sequenziellen Eingabeaufforderungen funktionieren, die gemäß Ihrem Beispiel der unmittelbare Teil des Skripts sind. In Ihrem Fall gitwerden Ihre Werte jedoch vor jeder Eingabeaufforderung für Benutzername/Passwort an den Prozess übergeben – wahrscheinlich, während dieser zuvor alles andere (Netzwerk usw.) erledigt GIT_ASKPASS– als Referenz: https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables

Antwort2

Voraussetzungen

Vor einiger Zeit akzeptierte GitHub keine Passwörter mehr und forderte die Benutzer auf, stattdessen Token zu erstellen. Natürlich konnte ich mich nicht an das Token erinnern, aber ich wollte es auch nicht als Klartext in speichern .git-credentials. Außerdem wollte ich es nicht als Argument übergeben (jemand kann es lesen /procoder .bash_historyfinden!). Ich habe meinen einfachen Verschlüsseler geschrieben, um das Token mit einem Passwort zu verschlüsseln, aber genau wie Sie konnte ich das entschlüsselte Token nicht weiterleiten gitund fand diese Frage bei der Suche nach einer Lösung. Leider habe ich die Antwort hier nicht gefunden. Ich hatte jedoch Glück, eine nicht damit zusammenhängende Frage zu finden, die mich zur Antwort führte. Und die Antwort lautetSkript.

Lösung

Wir können scriptdamit eine automatisierte Sitzung erstellen und Anmeldeinformationen dorthin weiterleiten. Dies ist das Skript, das ich dafür geschrieben habe:

#!/bin/bash

read -p "Password: " -s password
echo
token=$(echo "$password" | decrypt_token) || exit $?
cmd="git push $@"
echo -e "username\n$token" | script -E never -c "$cmd" /dev/null

-E nevergibt an, dass ich nicht möchte, dass meine Anmeldeinformationen wiederholt (im Terminal gedruckt) werden. Ich verwende es /dev/nullals Protokolldatei, da mir die Protokollierung egal ist.

WICHTIGER HINWEIS: echoist ein integrierter Befehl in meiner Shell, was bedeutet, dass es sicher ist, Passwort und Token als Argumente an ihn zu übergeben. Wenn es ein externes Programm wäre, könnte jemand die Argumente von lesen /proc. Ich empfehle Ihnen zu prüfen, ob der Befehl, den Sie für die Weiterleitung verwenden, in Ihre Shell integriert ist. Wenn Sie keinen geeigneten integrierten Befehl finden konnten, verwenden Sie cat mit heredoc:

token=$(
  (
  cat <<EOF
$password
EOF
  ) | decrypt_token
)

Teil 2

Nachdem ich mein Setup auf einen anderen Computer kopiert habe, erhalte ich einen seltsamen Fehler:

fatal: could not read Password for 'https://[email protected]': Success

Ich habe überprüft, dass beide gitdie screengleiche Version wie auf dem Originalcomputer sind, und konnte die Grundursache nicht finden.dieser Kommentar Maigib einen Tipp:

getpass() tries too hard to find the real terminal

Als Workaround habe ich ein separates Skript erstellt GIT_ASKPASS(und ich denke, das ist eine sauberere Lösung).

Dies ist das Hauptskript nach den Änderungen:

#!/bin/bash

if ! tty -s; then
  echo "Can't operate without tty."
  exit 1
fi

TTY=$(tty) GIT_USERNAME=username GIT_ASKPASS=~/git-creds git push $@

Und das ist git-creds:

#!/bin/bash

if echo "$1" | grep -q '^Password'; then
  read -p "Password: " -s password < $TTY
  echo "$password" | decrypt_token
  # put a newline to separate prompt and output
  echo > $TTY
else
  echo "$GIT_USERNAME"
fi

Es liest das Passwort direkt von Ihrem TTY und gibt den entschlüsselten Token an Git weiter. Für den Benutzernamen gibt es einfach die Umgebungsvariable GIT_USERNAME aus.

.bashrcEs ist auch möglich, diese Zeilen (oder eine beliebige Alternative) hinzuzufügen :

export TTY=$(tty)
export GIT_USERNAME=username
export GIT_ASKPASS=~/git-creds

Und Sie benötigen den Wrapper für Befehle nicht.

verwandte Informationen