Bei jeder Ausführung git push
muss 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.py
im 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 git
werden 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 /proc
oder .bash_history
finden!). 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 git
und 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 script
damit 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 never
gibt an, dass ich nicht möchte, dass meine Anmeldeinformationen wiederholt (im Terminal gedruckt) werden. Ich verwende es /dev/null
als Protokolldatei, da mir die Protokollierung egal ist.
WICHTIGER HINWEIS: echo
ist 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 git
die screen
gleiche 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.
.bashrc
Es 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.