전제 조건

전제 조건

을 실행할 때마다 git push프롬프트에 사용자 이름과 비밀번호를 수동으로 입력해야 합니다.
하지만 저는 이 과정을 자동화하고 싶습니다.

그래서 파이핑을 사용하여 자격 증명을 명령에 전달하려고 했습니다.

printf 'username\npassword' | git push

하지만 사용자 이름과 비밀번호를 묻는 메시지는 여전히 사라지지 않습니다!
왜 작동하지 않나요?

메모:
다음을 사용하여 이 작업을 수행할 수 있다는 것을 알고 있습니다. 하지만 배관 방법에 어떤 문제가 있는지 알고 싶습니다.
git push 'https://username:[email protected]/username/repo.git'


또한 이 프로세스가 다른 경우에도 작동하는지 확인하기 위해 실험을 수행했습니다.
스크립트를 만들었습니다 b.py.

b.py:

#!/usr/bin/env python3

username = input()
password = input()

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

printf 'abcd\nefgh' | ./b.py그런 다음 예상대로 작동하는 터미널에서 실행했고 사용자 이름과 비밀번호 문자열이 포함된 로그 파일이 생성되었습니다.

log.txt:

abcd
efgh

답변1

이는 귀하의 예에 따라 스크립트의 직접적인 부분인 순차 프롬프트의 경우에만 작동합니다. 그러나 git사용자 이름/비밀번호 프롬프트 이전에 값이 프로세스에 전달되는 경우 - 아마도 이전에 모든 작업(네트워크 등)을 수행하는 동안일 것입니다 GIT_ASKPASS. - 참고용: https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables

답변2

전제 조건

얼마 전 GitHub는 비밀번호 허용을 중단하고 사용자에게 대신 토큰을 생성하도록 요청했습니다. 물론 토큰을 기억할 수 없었지만 .git-credentials. 게다가 나는 그것을 인수로 전달하고 싶지 않았습니다(누군가가 읽고 찾을 수 있습니다 /proc! .bash_history). 비밀번호로 토큰을 암호화하기 위해 간단한 암호화기를 작성했지만 여러분과 마찬가지로 해독된 토큰을 파이프에 연결하지 못하고 git솔루션을 검색하는 동안 이 질문을 발견했습니다. 안타깝게도 여기서는 답을 찾지 못했습니다. 그러나 나는 운이 좋게도 관련 없는 질문을 발견하여 답을 얻었습니다. 그리고 대답은스크립트.

해결책

script자동화된 세션을 생성하고 여기에 자격 증명을 파이프하는 데 사용할 수 있습니다 . 이것은 내가 작성한 스크립트입니다.

#!/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내 자격 증명이 에코되는(터미널에 인쇄되는) 것을 원하지 않음을 나타냅니다. /dev/null로깅에 신경 쓰지 않기 때문에 로그 파일로 사용하고 있습니다 .

중요 사항: echo내 셸에 내장된 명령입니다. 즉, 암호와 토큰을 인수로 전달하는 것이 안전하다는 의미입니다. 외부 프로그램이라면 누군가가 /proc. 파이핑에 사용하는 명령이 쉘에 내장되어 있는지 확인하는 것이 좋습니다. 적절한 내장 기능을 찾을 수 없다면 heredoc과 함께 cat을 사용하세요:

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

2 부

내 설정을 다른 컴퓨터에 복사한 후 이상한 오류가 발생했습니다.

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

git둘 다 원래 컴퓨터와 동일한 버전인지 확인했지만 screen근본 원인을 찾지 못했습니다. 하지만,이 댓글 5월팁을 제공하세요:

getpass() tries too hard to find the real terminal

해결 방법으로 별도의 스크립트를 만들었습니다 GIT_ASKPASS(그리고 이것이 더 깔끔한 솔루션인 것 같습니다).

변경 후의 기본 스크립트는 다음과 같습니다.

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

그리고 이건 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

TTY에서 직접 비밀번호를 읽고 해독된 토큰을 git에 제공합니다. 사용자 이름의 경우 GIT_USERNAME env var를 에코합니다.

.bashrc다음 줄을 다음 항목(또는 다른 대안) 에 추가할 수도 있습니다 .

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

그리고 명령에 대한 래퍼가 필요하지 않습니다.

관련 정보