Запустить оболочку script из python с разрешениями

У меня самый простой script, называемый update.sh

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

Когда я вызываю это из терминала с помощью ./update.sh, я получаю Уже обновленный или он обновляет файлы, как ожидалось.

У меня также есть python script, внутри которого scipt:

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

Когда это вызывает тот же script, я получаю:

Отказано в доступе (публикация). fatal: Не удалось прочитать из удаленного репозитория.

Пожалуйста, убедитесь, что у вас есть правильные права доступа и существует репозиторий.

(Я использую SSH).

----------------- обновление --------------------

Кто-то еще посмотрел на меня:

ОК, так что прогресс. Когда я загружаю ваш образ, я не могу запустить git втянуть ваш каталог репо и bash script также не работает. Это кажется потому что репозиторий bitbucket является конфиденциальным и требует аутентификации для pull (тот, который я использовал, был общедоступным, так что у меня не было вопросы). Предположительно git запоминает это после того, как вы введете его в первый время, bash как-то трюки git, думая, что вы печатаете command, но запуск его из python не является тем же.

Я не эксперт git, но должен быть какой-то способ настроить это так python может обеспечить аутентификацию.

Ответ 1

звучит так, как будто вы должны дать команде ssh открытый или закрытый ключ, к которому он может получить доступ:

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

-i указывает, где искать ключ

Ответ 2

Эта проблема вызвана ошибкой аутентификации git repo. Вы говорите, что используете SSH, а git жалуется на отказ публики auth. Обычно вы можете использовать команды git на частном репо без ввода пароля. Все это означало бы, что git использует ssh, но в последнем случае он не может найти правильный закрытый ключ.

Поскольку проблема проявляется только при прохождении через другой script, это, скорее всего, вызвано тем, что возится с переменными среды. Subprocess.call должен передать среду как есть, поэтому есть несколько обычных подозреваемых:

  • Судо.
    • Если вы используете sudo, он будет пропускать в процесс в основном пустую среду
  • сам python script
    • если python script изменяет свой env, эти изменения также будут распространяться на подпроцесс.
  • sh -l или su -
    • эти команды настраивают оболочку входа, что означает, что их среда получает reset по умолчанию.

Любая из этих причин может скрыть переменные среды. ssh-agent (или какой-либо другой инструмент управления ключами) может работать.

Шаги по диагностике и исправлению:

  • Изолируйте проблему.

    • Создайте минимальный python script, который делает ничего, кроме запуска subprocess.call(['./update.sh']). Запустите оба update.sh и новый script.
  • Диагностируйте проблему и исправьте ее соответствующим образом:

    a) Если update.sh работает, а новый script - нет, вы, вероятно, испытываете какой-то странный угловой случай неправильной конфигурации системы. Попробуйте обновить систему и python; если проблема не устранена, возможно, потребуется дополнительная отладка самой затронутой системы.

    b) Если работают update.sh и new script, проблема лежит в внешнем python script, вызывающем оболочку script. Ищите вхождения sudo, su -, sh -l, env и os.environ, один из них является наиболее вероятным виновником.

    c) Если ни update.sh, ни новый script не работают, ваша проблема, скорее всего, будет связана с конфигурацией клиента ssh; типичной причиной будет то, что вы используете нестандартный идентификатор, не настроили его в ~/.ssh/config, а использовали ssh-add вместо этого, и после этого кеш-сервер ssh истек. В этом случае запустите ssh-add identityfile для идентификатора, который вы использовали для аутентификации для этого репозитория git, и повторите попытку.

Ответ 3

Я верю, что этот ответ поможет вам: https://serverfault.com/questions/497217/automate-git-pull-stuck-with-keychain?answertab=votes#tab-top

Я не использовал ssh-agent, и он сработал: измените свой script на тот, который следует и попробуйте.

#!/bin/bash
cd /home/pi/circulation_of_circuits 
ssh-add /home/yourHomefolderName/.ssh/id_rsa
ssh-add -l
git pull

Это предполагает, что вы правильно настроили свой ssh-ключ.

Ответ 4

Кажется, что ваша система контроля версий нуждается в аутентификации для pull, поэтому можно построить питон с помощью pexpect,

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

Ответ 5

Попробуйте использовать пакет sh вместо использования вызова подпроцесса. https://pypi.python.org/pypi/sh Я попробовал этот сниппет, и это сработало для меня.

#!/usr/local/bin/python

import sh

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

Вывод:

Уже обновлен.

Ответ 6

import subprocess 

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

Ответ 7

Я могу воспроизвести вашу ошибку. Это не имеет никакого отношения к разрешению, это зависит от того, как ваш ssh установлен в вашей системе. Чтобы проверить, мне нужна такая же причина diff output.

Сохраните следующее в файле 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

установите разрешение на выполнение и запустите его дважды:
  1. На консоли без параметра
  2. Из вашего python script с параметром ".python"
      Пожалуйста, запустите его с помощью того же python script!

   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.

Ответ 8

С помощью Git 1.7.9 или более поздней версии вы можете просто использовать один из следующих помощников учетных данных:

С таймаутом

git config --global credential.helper cache

..., который сообщает Git сохранить ваш пароль в кеше в памяти (по умолчанию) 15 минут. Вы можете установить более длительный тайм-аут с помощью:

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

(Этот пример был предложен в странице справки GitHub для Linux.) Вы также можете сохранить свои учетные данные навсегда, если это необходимо.

Сохранение неопределенно

Вы можете использовать git-credential-store через

git config credential.helper store

GitHub help также предполагает, что если вы используете Mac OS X и используете Homebrew для установки Git, вы можете использовать собственный Хранилище Mac OS X с:

git config --global credential.helper osxkeychain

Для Windows есть помощник под названием Git Credential Manager для Windows или wincred в msysgit.

git config --global credential.helper wincred # obsolete

С Git для Windows 2.7.3+ (март 2016):

git config --global credential.helper manager

Для Linux вы можете использовать gnome-keyring (или другую реализацию таких ключей, как KWallet).

Наконец, после выполнения одной из предложенных команд один раз вручную, вы можете выполнить свой script без изменений в нем.

Ответ 9

Используйте следующий код python. Это будет импортировать модуль os в python и сделать системный вызов с разрешениями sudo.

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