2017-03-05 395 views
15

我擁有最簡單的腳本調用update.sh運行shell腳本

#!/bin/sh 
cd /home/pi/circulation_of_circuits 
git pull 

當我把這個從終端與./update.sh我得到已經起牀了最新或者更新文件像預期一樣。

我也有一個Python腳本,裏面那個素文字是:

subprocess.call(['./update.sh'])

當調用同一個腳本,我得到:

權限被拒絕(公鑰)。 致命:無法從遠程存儲庫讀取。

請確保您擁有正確的訪問權限 並存在存儲庫。

(我使用SSH)。

-----------------更新--------------------

其他人有一個找我:

好吧,這樣有些進步。當我啓動映像時,我無法在 的repo目錄中運行git pull,並且bash腳本也失敗。它似乎是 ,因爲bitbucket存儲庫是私人的,需要認證 拉(我使用的是公開的,這就是爲什麼我沒有 問題)。大概git在第一個輸入 之後記得這個,bash不知何故會讓git認爲你隨後輸入了 命令,但是從python運行它並不相同。

我不是git專家,但必須有一些方法來設置這個,所以 python可以提供身份驗證。

+0

這是否解決您的問題(傳遞'殼=真'標誌):http://stackoverflow.com/a/325474/608259 – kalaracey

+0

沒有,萬一它的事項我把它叫做這樣'CMD = [ '/home/pi/circulation_of_circuits/update.sh'] \t \t過程= subprocess.Popen(CMD,殼=真,標準輸出= subprocess.PIPE) \t \t process.wait()' – clankill3r

+0

如果有人想知道, 'os.geteuid()'給出一個0,所以應該是好的。 – clankill3r

回答

11

聽起來像你需要給你的ssh命令公共或私有密鑰也可以或許訪問:

ssh -i /backup/home/user/.ssh/id_dsa [email protected] 

-i告訴它在哪裏尋找關鍵

3

好像你的版本控制系統,需要認證的pull這樣可以建立與使用pexpect蟒蛇,

import pexpect 
child = pexpect.spawn('./update.sh') 
child.expect('Password:') 
child.sendline('SuperSecretPassword') 
2

嘗試使用sh包而不是使用子進程調用。 https://pypi.python.org/pypi/sh 我試過這段代碼,它爲我工作。

#!/usr/local/bin/python 

import sh 

sh.cd("/Users/siyer/workspace/scripts") 
print sh.git("pull") 

輸出:

已經跟上時代的。

5

此問題是由git repo身份驗證失敗導致的。你說你正在使用SSH,而git正在抱怨publickey auth失敗。通常你可以在私人倉庫上使用git命令而不需要輸入密碼。所有這些都意味着git使用ssh,但在後一種情況下,它找不到正確的私鑰。

由於該問題僅在通過另一個腳本運行時纔會顯現,因此很可能是由與環境變量混淆造成的。 Subprocess.call應該按原樣傳遞環境,所以有幾個常見的嫌疑人:

  1. sudo。
    • 如果你正在使用sudo,它會通過一個幾乎爲空的環境,過程
  2. 的python腳本本身
    • 如果python腳本改變它的包膜,這些變化將得到傳播到子過程也是如此。
  3. sh -lsu -
    • 這些命令設置一個登錄外殼,這意味着它們的環境被重置爲默認值。

所有的這些原因可以隱藏的環境變量的ssh-agent(或其他一些重要的管理工具)可能需要工作。

步驟來診斷和修復:

  1. 隔離問題。

    • 創建一個最小的python腳本,除了運行subprocess.call(['./update.sh'])以外別無其他。運行update.sh和新腳本。
  2. 診斷問題,並據此定出:

    a)如果update.sh工作,而新的腳本不,你可能遇到系統錯誤配置的一些奇怪的極端情況。嘗試升級你的系統和Python;如果問題依然存在,則可能需要對受影響的系統本身進行額外的調試。 b)如果update.sh和新腳本都工作,那麼問題在於調用shell腳本的外部python腳本。尋找發生的sudo,su -,sh -l,envos.environ,其中之一是最有可能的罪魁禍首。

    c)如果update.sh和新腳本都不起作用,那麼您的問題可能與ssh客戶端配置有關;一個典型的原因是您使用的是非默認身份,沒有在~/.ssh/config中配置它,而是使用了ssh-add,之後,ssh-agent的緩存過期。在這種情況下,運行ssh-add identityfile獲取您用於驗證該git倉庫的標識,然後重試。

1

我可以重現你的錯。它與權限無關,它取決於您的系統上如何安裝ssh。到驗證這是因爲我需要diff output

將下列內容保存到一個文件​​,

#!/bin/bash 

log="shell_env"$1 
echo "create shell_env"$1 

echo "shell_env" > $log 

echo "whoami="$(whoami) >> $log 
echo "which git="$(which git) >> $log 
echo "git status="$(git status 2>&1) >> $log 
echo "git pull="$(git pull 2>&1) >> $log 
echo "ssh -vT [email protected]="$(ssh -T [email protected] 2>&1) >> $log 

echo "ssh -V="$(ssh -V 2>&1) >> $log 
echo "ls -al ~/.ssh="$(ls -a ~/.ssh) >> $log 

echo "which ssh-askpass="$(which ssh-askpass) >> $log 
echo "ps -e | grep [s]sh-agent="$(ps -e | grep [s]sh-agent) >> $log 
echo "ssh-add -l="$(ssh-add -l) >> $log 

echo "set=" >> $log 
set >> $log 

組執行權限,並運行它兩次:與參數
1.從控制檯不帶參數
2.從你的Python腳本」。 python'
請從相同的python腳本中運行它!

For instance: 
    try: 
     output= subprocess.check_output(['./log_shell_env.sh', '.python'], stderr=subprocess.STDOUT) 
     print(output.decode('utf-8')) 

    except subprocess.CalledProcessError as cpe: 
     print('[ERROR] check_output: %s' % cpe) 

diff shell_env shell_env.python > shell_env.diff 產生的shell_env.diff應該顯示比下面來進行比較:

15,16c15,16 
< BASH_ARGC=() 
< BASH_ARGV=() 
--- 
> BASH_ARGC=([0]="1") 
> BASH_ARGV=([0]=".python") 
48c48 
< PPID=2209 
--- 
> PPID=2220 
72c72 
< log=shell_env 
--- 
> log=shell_env.python 

回來和評論,如果你得到更多的diff 更新您的問題與差異輸出。

2
import subprocess 

subprocess.call("sh update.sh", shell=True) 
+1

儘管此代碼可能會回答這個問題,但提供關於此代碼爲何和/或如何回答問題的其他上下文可提高其長期價值。 –

+0

我已經添加了「sh update.sh」,因爲我們可以用兩種方式執行shell腳本,即1)./update.sh和2)sh update.sh,這裏兩者都應該工作。但對他來說,一個人工作,所以我被建議他嘗試一個。謝謝 –

+0

您可以[編輯]您的答案以包含更多信息。 –

1

使用Git 1.7.9或更高版本,你可以使用以下憑據助手之一:

一個超時

git config --global credential.helper cache 

...它告訴混帳保持您的密碼緩存在內存中(默認)15分鐘。您可以設置一個較長的超時:

git config --global credential.helper "cache --timeout=3600" 

(即例如建議在GitHub help page的Linux版本。)您還可以永久如果需要保存您的憑據。

無限期

保存您可以使用git-credential-store通過

git config credential.helper store 

GitHub's help還建議,如果你在Mac OS X和使用自制軟件安裝Git,那麼可以使用原生Mac OS X密鑰存儲庫:

git config --global credential.helper osxkeychain 

對於Windows,有一個名爲Git Credential Manager for Windows的助手或者msysgit中的wincred。

git config --global credential.helper wincred # obsolete 

使用Git的Windows 2.7.3+(2016年3月):

git config --global credential.helper manager 

對於Linux,你可以使用GNOME的鑰匙圈(或其他鑰匙圈實現諸如KDE錢包)。

最後,手動執行一次建議的命令之一後,您可以執行腳本而不更改它。

+0

@ clankill3r你試過我的建議嗎?如果您的問題得到良好記錄,對我們所有人都將是有益的 – sdikby

1

使用下面的python代碼。這將在python中導入os模塊,並使用sudo權限進行系統調用。

#!/bin/python 
import os 
os.system("sudo ./update.sh") 
+0

如果他們想要使用非root用戶,會發生什麼情況?或者他們想在不輸入密碼的情況下做到這一點? – tahsmith

+0

如果用戶不是root用戶,那麼他們必須至少成爲sudo組的成員。 shell腳本還必​​須具有sudo組的可執行權限,否則'sudo bash update.sh'就足夠了。有些方法可以在不輸入密碼的情況下執行此操作,但它們有風險,我建議不要這樣做。 –