Condiciones previas

Condiciones previas

Cada vez que ejecuto git push, tengo que escribir mi nombre de usuario y contraseña cuando se me solicite manualmente.
Sin embargo, quiero automatizar este proceso.

Entonces, intenté pasar las credenciales al comando usando tuberías:

printf 'username\npassword' | git push

¡Pero el mensaje de nombre de usuario y contraseña aún no desaparece!
¿Por qué no funciona?

Nota:
Sé que esto se puede hacer usando: pero me interesa saber qué hay de malo con el método de tubería.
git push 'https://username:[email protected]/username/repo.git'


Además, para confirmar que este proceso funciona en otros casos, hice un experimento.
Creé un script b.py:

b.py:

#!/usr/bin/env python3

username = input()
password = input()

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

Luego, ejecuté printf 'abcd\nefgh' | ./b.pyen la terminal, lo que funcionó como se esperaba y resultó en el archivo de registro que contiene las cadenas de nombre de usuario y contraseña:

log.txt:

abcd
efgh

Respuesta1

Esto solo funcionaría en el caso de indicaciones secuenciales que son la parte inmediata del script según su ejemplo. Sin embargo, en el caso de que gitsus valores se pasen al proceso antes de cualquier solicitud de nombre de usuario/contraseña, probablemente mientras hace todo (red, etc.) antes, GIT_ASKPASScomo referencia: https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables

Respuesta2

Condiciones previas

Hace algún tiempo, GitHub dejó de aceptar contraseñas y pidió a los usuarios que crearan tokens. Por supuesto, no podía recordar el token, pero tampoco quería almacenarlo como texto sin formato en formato .git-credentials. Además, no quería pasarlo como argumento (¡alguien puede leerlo /proco .bash_historyencontrarlo!). Escribí mi cifrador simple para cifrar el token con una contraseña, pero, al igual que usted, no pude canalizar el token descifrado gity encontré esta pregunta mientras buscaba una solución. Desafortunadamente, no encontré la respuesta aquí. Sin embargo, tuve suerte de encontrar una pregunta no relacionada que me llevó a la respuesta. Y la respuesta esguion.

Solución

Podemos usarlo scriptpara crear una sesión automatizada y canalizarle credenciales. Este es el guión que he escrito para ello:

#!/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 neverindica que no quiero que se repitan mis credenciales (impresas en la terminal). Lo estoy usando /dev/nullcomo archivo de registro ya que no me importa registrar.

NOTA IMPORTANTE: echoes un comando integrado en mi shell, lo que significa que es seguro pasarle contraseña y token como argumentos. Si fuera un programa externo, alguien podría leer los argumentos de /proc. Le recomiendo que verifique si el comando que usa para la tubería está integrado en su shell. Si no pudo encontrar una función incorporada adecuada, use cat con heredoc:

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

Parte 2

Después de copiar mi configuración en una máquina diferente, aparece un error extraño:

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

Verifiqué que ambos gity screentienen la misma versión que en la máquina original y no pude encontrar la causa raíz. Sin embargo,este comentario puededar un consejo:

getpass() tries too hard to find the real terminal

Como solución alternativa, creé un script separado GIT_ASKPASS(y creo que es una solución más limpia).

Este es el script principal después de los cambios:

#!/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 $@

Y esto es 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

Lee la contraseña directamente desde su TTY y proporciona un token descifrado a git. Para el nombre de usuario simplemente hace eco de la var de entorno GIT_USERNAME.

También es posible agregar estas líneas .bashrc(o cualquier alternativa):

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

Y no necesitarás el contenedor para los comandos.

información relacionada