前提條件

前提條件

每當我執​​行時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是我的 shell 中的內建命令,這意味著將密碼和令牌作為參數傳遞給它是安全的。如果它是外部程序,有人可以從 讀取參數/proc。我建議您檢查用於管道的命令是否內建於 shell 中。如果您找不到合適的內建函數,請使用 cat 和heredoc:

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

第2部分

將我的設定複製到不同的機器後,我遇到了一個奇怪的錯誤:

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

我已經檢查過gitscreen與原始機器上的版本相同,但未能找到根本原因。然而,這則評論 可能提供一個提示:

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 環境變數。

也可以將這些行新增至.bashrc(或任何替代方案):

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

而且您不需要命令的包裝器。

相關內容