2017-03-05 30 views
15

mam najbardziej prosty skrypt o nazwie update.shUruchom skrypt z pytona z uprawnieniami

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

Kiedy nazywają to z terminala z ./update.sh dostaję Już up-to-date lub aktualizuje pliki jak oczekiwano.

Mam też skrypt Pythona, że ​​wewnątrz jest skrypcie:

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

Kiedy który wywołuje ten sam skrypt uzyskać:

Permission denied (PublicKey). fatal: Nie można odczytać z zdalnego repozytorium.

Upewnij się, że masz prawidłowe prawa dostępu i istnieje repozytorium.

(Używam SSH).

----------------- zmiana --------------------

Ktoś miał szukaj mnie:

OK, więc trochę postępu. Kiedy uruchamiam twój obraz, nie mogę uruchomić git w katalogu twojego katalogu repo, a skrypt bash również zawiedzie. Wydaje się być , ponieważ repozytorium bitbucket jest prywatne i wymaga uwierzytelnienia dla pull (ten, którego używałem był publiczny, dlatego nie miałem problemów z ). Przypuszczalnie git pamięta o tym po wpisaniu go w pierwszym momencie czasu, bash jakoś sztuczki gita w myślenie, że piszesz później polecenie , ale uruchomienie go z Pythona nie jest takie samo.

Nie jestem ekspertem od gitów, ale musi być jakiś sposób ustawienia tego, aby pyton mógł dostarczyć uwierzytelnienia.

+0

Czy to rozwiązać problem (przechodzącego na flagę 'shell = TRUE): http://stackoverflow.com/a/325474/608259 – kalaracey

+0

Nie, w przypadku, gdy liczy nazwałem go tak' cmd = [ '/home/pi/circulation_of_circuits/update.sh'] \t \t proces = subprocess.Popen (cMD, powłoki = True stdout = subprocess.PIPE) \t \t process.wait() ' – clankill3r

+0

W przypadku, gdy ktoś dziwi, 'os.geteuid()' daje 0, więc powinno być dobre. – clankill3r

Odpowiedz

11

brzmi jak trzeba dać polecenie ssh klucz publiczny lub prywatny może uzyskać dostęp może:

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

-i informuje go, gdzie szukać klucza

3

Wydaje się swojej kontroli wersji System, trzeba uwierzytelniania dla pull więc można zbudować Pythona z wykorzystaniem pexpect,

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

Spróbuj użyć sh pakiet zamiast używania wywołania podprocesowego. https://pypi.python.org/pypi/sh Wypróbowałem ten fragment i zadziałało to dla mnie.

#!/usr/local/bin/python 

import sh 

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

wyjściowa:

Już up-to-date.

5

Ten problem jest spowodowany niepowodzeniem uwierzytelniania git repo. Mówisz, że używasz SSH, a git narzeka na błąd auth opublikowania. Zwykle można użyć komend git na prywatnym repo bez wprowadzania hasła. Wszystko to sugerowałoby, że git używa ssh, ale w tym drugim przypadku nie może znaleźć właściwego klucza prywatnego.

Ponieważ problem pojawia się tylko wtedy, gdy uruchamiany jest inny skrypt, najprawdopodobniej jest spowodowany zakłóceniami ze zmiennymi środowiskowymi. Subprocess.call powinien przejść środowisko tak, jak jest, więc jest kilka zwykłych podejrzanych:

  1. sudo.
    • jeśli używasz sudo, to przejdzie do większości pusty środowisko w procesie
  2. skrypt python sama
    • jeśli skrypt python zmienia env, zmiany te będą się propagowane również podproces.
  3. sh -l lub su -
    • te polecenia założyć powłokę logowania, co oznacza, że ​​ich środowisko zostanie zresetowany do ustawień domyślnych.

Każdy z tych powodów mógł ukryć zmienne środowiskowe ssh-agent (lub jakiś inny kluczowym narzędziem zarządzania) mogą potrzebować do pracy.

kroki, aby zdiagnozować i naprawić:

  1. Izolowanie problemu.

    • Utwórz minimalny skrypt python, który nie wykonuje niczego innego niż uruchamia subprocess.call(['./update.sh']). Uruchom zarówno update.sh, jak i nowy skrypt.
  2. zdiagnozować problem i naprawić odpowiednio:

    a) Jeżeli update.sh działa, a nowy skrypt nie, prawdopodobnie przeżywa jakiś dziwny przypadek węgielny systemu błędną. Spróbuj uaktualnić swój system i pythona; jeśli problem będzie się powtarzał, prawdopodobnie wymaga dodatkowego debugowania w systemie, którego dotyczy luka.

    b) Jeśli zarówno update.sh, jak i nowy skrypt działają, problem leży w zewnętrznym skrypcie python wywołującym skrypt powłoki. Poszukaj wystąpień sudo, su -, sh -l, env i , jeden z nich jest najbardziej prawdopodobnym winowajcą.

    c) Jeśli ani update.sh, ani nowy skrypt nie działają, Twój problem prawdopodobnie dotyczy konfiguracji klienta ssh; typową przyczyną jest to, że używasz innej niż domyślna tożsamości, nie skonfigurowałeś jej w ~/.ssh/config, ale użyłeś zamiast tego ssh-add, a po tym cache ssh-agenta wygasła. W takim przypadku uruchom ssh-add identityfile dla tożsamości użytej do uwierzytelnienia w repozytorium git i spróbuj ponownie.

1

mogę odtworzyć swoją usterkę. Nie ma to nic wspólnego z pozwolenie, to zależy od tego, jak twój ssh są zainstalowane w systemie. Aby zweryfikować, to ta sama przyczyna, której potrzebuję diff output.

Zapisz następujący tekst w pliku log_shell_env.sh,

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

zestaw prawo wykonywania i uruchomić go dwukrotnie:
1. Na konsoli bez parametru
2. Z skryptu Pythona z parametrem”. python '
Proszę, uruchom to naprawdę z tego samego skryptu 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) 

zrobić diff shell_env shell_env.python > shell_env.diff Powstały shell_env.diff powinien pokazać nie więcej niż następujące dyferencjału:

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 

wrócić i komentarza, jeśli uzyska więcej dyferencjału zaktualizować swoje pytanie z wyjście diff.

2
import subprocess 

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

Podczas gdy ten kod może odpowiedzieć na pytanie, podanie dodatkowego kontekstu dotyczącego tego, dlaczego i/lub jak ten kod odpowiada na pytanie, poprawia jego długoterminową wartość. –

+0

Dodałem "sh update.sh", ponieważ możemy wykonać skrypt powłoki na dwa sposoby, tj. 1) ./update.sh i 2) sh update.sh, tutaj oba powinny działać. ale dla niego ten 1 działa, więc zasugerowano mu, aby spróbował 2. dzięki –

+0

Możesz [edytować] swoją odpowiedź, aby zawrzeć więcej informacji. –

1

Z Git 1.7.9 lub nowszy, można po prostu użyć jednego z następujących poświadczeń pomocników:

Z timeout

git config --global credential.helper cache 

... który mówi Git zachować twoje hasło jest buforowane w pamięci przez (domyślnie) 15 minut.Można ustawić dłuższy czas oczekiwania z:

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

(to przykład sugerowano w GitHub help page dla systemu Linux). Można również zapisać swoje dane na stałe, jeśli jest to pożądane.

Zapisywanie nieskończoność

Można użyć git-credential-store poprzez

git config credential.helper store 

GitHub's help również sugeruje, że jeśli jesteś na Mac OS X i używane Homebrew zainstalować Git, można użyć natywny magazyn kluczy Mac OS X z:

git config --global credential.helper osxkeychain 

W systemie Windows dostępny jest helper o nazwie Git Credential Manager dla systemu Windows lub wincred w msysgit.

git config --global credential.helper wincred # obsolete 

Z Git dla Windows 2.7.3+ (marzec 2016):

git config --global credential.helper manager 

Dla systemu Linux, można użyć gnome-Kluczy (lub inną realizację keyring takich jak Portfelu KDE).

Wreszcie, po wykonaniu jednej z sugerowanych poleceń jeden raz ręcznie, można wykonać skrypt bez zmian w nim.

+0

@ clankill3r czy próbowałeś tego, co sugerowałem? Byłoby korzystne dla nas wszystkich, gdyby twoje pytanie zostało dobrze udokumentowane. – sdikby

1

Użyj następującego kodu Pythona. Spowoduje to zaimportowanie modułu os w pythonie i wykonanie wywołania systemowego z uprawnieniami sudo.

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

Co się stanie, jeśli chcą użyć użytkownika, który nie jest rootem? Czy też chcą to zrobić bez podawania hasła? – tahsmith

+0

Jeśli użytkownik nie jest rootem, to musi być przynajmniej członkiem grupy sudo. Skrypt powłoki musi również mieć uprawnienia do wykonywania dla grupy sudo, w przeciwnym razie wystarczy "sudo bash update.sh". Istnieją sposoby, aby to zrobić bez wpisywania hasła, jednak są one ryzykowne i radziłbym, by nie odpowiadał. –