使用权限从python运行shell脚本

时间:2021-12-23 01:14:46

I have the most simple script called update.sh

我有一个最简单的脚本叫做update.sh

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

When I call this from the terminal with ./update.sh I get a Already up-to-date or it updates the files like expected.

当我从终端调用。/update。我已经得到一个最新的或者它像预期的那样更新文件。

I also have a python script, inside that scipt is:

我还有一个python脚本,在那个scipt里面是:

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

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

When that calls the same script I get:

当它调用相同的脚本时,我得到:

Permission denied (publickey). fatal: Could not read from remote repository.

没有权限(publickey)。无法从远程存储库中读取。

Please make sure you have the correct access rights and the repository exists.

请确保您拥有正确的访问权限,并且存储库已经存在。

(I use SSH).

(我使用SSH)。

----------------- update --------------------

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

Someone else had a look for me:

有人找过我:

OK so some progress. When I boot your image I can't run git pull in your repo directory and the bash script also fails. It seems to be because the bitbucket repository is private and needs authentication for pull (the one I was using was public so that's why I had no issues). Presumably git remembers this after you type it in the first time, bash somehow tricks git into thinking it's you typing the command subsequently but running it from python isn't the same.

所以一些进展。当我引导您的映像时,我不能运行git拉入您的repo目录,而bash脚本也失败了。这似乎是因为bitbucket存储库是私有的,并且需要对pull进行身份验证(我使用的那个是公共的,所以我没有遇到任何问题)。可能git在第一次输入后会记住这个,bash会让git认为是您在输入命令,但是从python中运行它是不一样的。

I'm not a git expert but there must be some way of setting this up so python can provide the authentication.

我不是一个git专家,但是必须有一些方法来设置这个,以便python能够提供身份验证。

9 个解决方案

#1


11  

sounds like you need to give your ssh command a public or private key it can access perhaps:

听起来好像需要给ssh命令一个公钥或私钥,它可以访问:

ssh -i /backup/home/user/.ssh/id_dsa user@unixserver1.nixcraft.com

-i tells it where to look for the key

-我告诉它去哪里找钥匙。

#2


5  

This problem is caused by the git repo authentication failing. You say you are using SSH, and git is complaining about publickey auth failing. Normally you can use git commands on a private repo without inputting a password. All this would imply that git is using ssh, but in the latter case it cannot find the correct private key.

这个问题是由于git repo身份验证失败引起的。您说您正在使用SSH, git正在抱怨publickey auth失败。通常,您可以在私有repo上使用git命令,而无需输入密码。所有这些都意味着git正在使用ssh,但是在后一种情况下,它无法找到正确的私钥。

Since the problem only manifests itself when run through another script, it is very likely caused by something messing with the environment variables. Subprocess.call should pass the environment as is, so there are a couple of usual suspects:

由于这个问题只在运行另一个脚本时显现出来,很可能是由于环境变量的混乱造成的。子流程。调用应该按原样通过环境,因此有几个常见的怀疑因素:

  1. sudo.
    • if you are using sudo, it will pass a mostly empty environment to the process
    • 如果您使用的是sudo,它将会传递一个主要为空的环境。
  2. sudo。如果您使用的是sudo,它将会传递一个主要为空的环境。
  3. the python script itself
    • if the python script changes its env, those changes will get propagated to the subprocess too.
    • 如果python脚本更改其env,这些更改也将传播到子进程。
  4. 如果python脚本更改其env,那么这些更改也将传播到子进程。
  5. sh -lor su -
    • these commands set up a login shell, which means their environment gets reset to defaults.
    • 这些命令设置了一个登录shell,这意味着它们的环境将被重置为默认值。
  6. 这些命令设置了一个登录shell,这意味着它们的环境将被重置为默认值。

Any of these reasons could hide the environment variables ssh-agent (or some other key management tool) might need to work.

任何这些原因都可以隐藏环境变量ssh-agent(或其他关键管理工具)可能需要工作。

Steps to diagnose and fix:

诊断和修复的步骤:

  1. Isolate the problem.

    隔离问题。

    • Create a minimal python script that does nothing else than runs subprocess.call(['./update.sh']). Run both update.sh and the new script.
    • 创建一个最小的python脚本,除了运行subprocess.call(['./update.sh'])之外什么都不做。运行这两个更新。sh和新剧本。
  2. Diagnose the problem and fix accordingly:

    对问题进行诊断并据此进行修复:

    a) If update.sh works, and the new script doesn't, you are probably experiencing some weird corner case of system misconfiguration. Try upgrading your system and python; if the problem persists, it probably requires additional debugging on the affected system itself.

    如果更新。sh起作用,而新脚本不起作用,您可能会遇到一些系统配置错误的奇怪情况。尝试升级您的系统和python;如果问题持续存在,可能需要对受影响的系统本身进行额外的调试。

    b) If both update.sh and the new script work, then the problem lies within the outer python script calling the shell script. Look for occurrences of sudo, su -, sh -l, env and os.environ, one of those is the most likely culprit.

    b)如果两个更新。sh和新的脚本工作,然后问题就出现在调用shell脚本的外部python脚本中。查找出现sudo、su -、sh -l、env和os的情况。环境,其中之一是最可能的罪魁祸首。

    c) If neither the update.sh nor the new script work, your problem is likely to be with ssh client configuration; a typical cause would be that you are using a non-default identity, did not configure it in ~/.ssh/config but used ssh-add instead, and after that, ssh-agent's cache expired. In this case, run ssh-add identityfile for the identity you used to authenticate to that git repo, and try again.

    c)如果没有更新。无论是sh还是新的脚本工作,您的问题都可能与ssh客户机配置有关;一个典型的原因是您正在使用一个非默认标识,没有在~/中配置它。ssh/config但是使用了ssh-add,之后,ssh-agent的缓存过期。在这种情况下,为您用来对git repo进行身份验证的标识运行ssh-add identityfile,并再次尝试。

#3


3  

I believe this answer will help you: https://serverfault.com/questions/497217/automate-git-pull-stuck-with-keychain?answertab=votes#tab-top

我相信这个答案会对你有所帮助:https://serverfault.com/questions/497217/automate-git-pull- stutwith- keychain?answer =vote # table -top

I didn't use ssh-agent and it worked: Change your script to the one that follows and try.

我没有使用ssh-agent,它是有效的:将您的脚本更改为后面的脚本并进行尝试。

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

This assumes that you have configured correctly your ssh key.

这假定您已经正确配置了ssh密钥。

#4


3  

It seems like your version control system, need the authentication for the pull so can build the python with use of pexpect,

看起来像你的版本控制系统,需要身份验证才能使用pexpect构建python,

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

#5


2  

Try using the sh package instead of using the subprocess call. https://pypi.python.org/pypi/sh I tried this snippet and it worked for me.

尝试使用sh包,而不是使用子进程调用。https://pypi.python.org/pypi/sh我尝试了这个片段,它对我很有用。

#!/usr/local/bin/python

import sh

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

Output:

输出:

Already up-to-date.

已经更新。

#6


2  

import subprocess 

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

#7


1  

With Git 1.7.9 or later, you can just use one of the following credential helpers:

使用Git 1.7.9或更高版本,您可以使用以下凭证助手之一:

With a timeout

用一个超时

git config --global credential.helper cache

... which tells Git to keep your password cached in memory for (by default) 15 minutes. You can set a longer timeout with:

…它告诉Git将密码缓存在内存中15分钟(默认情况下)。您可以设置较长的超时时间:

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

(That example was suggested in the GitHub help page for Linux.) You can also store your credentials permanently if so desired.

(这个例子在GitHub的Linux帮助页面中得到了建议。)如果需要,您还可以永久保存您的凭据。

Saving indefinitely

无限期保存

You can use the git-credential-store via

你可以通过git认证商店

git config credential.helper store

GitHub's help also suggests that if you're on Mac OS X and used Homebrew to install Git, you can use the native Mac OS X keystore with:

GitHub的帮助还建议,如果你在Mac OS X上使用Homebrew安装Git,你可以使用本地Mac OS X keystore:

git config --global credential.helper osxkeychain

For Windows, there is a helper called Git Credential Manager for Windows or wincred in msysgit.

对于Windows,有一个助手名为Git凭据管理器,用于Windows或msysgit中的wincred。

git config --global credential.helper wincred # obsolete

With Git for Windows 2.7.3+ (March 2016):

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

git config --global credential.helper manager

For Linux, you can use gnome-keyring(or other keyring implementation such as KWallet).

对于Linux,您可以使用gnome-keyring(或其他keyring实现,如KWallet)。

Finally, after executing one of the suggested command one time manually, you can execute your script without changes in it.

最后,在手动执行一个建议的命令后,您可以执行您的脚本而不需要修改。

#8


1  

I can reproduce your fault. It has nothing to do with permission, it depends how your ssh are installed on your system. To verify it's the same cause i need the diff output.

我可以重复你的错误。它与权限无关,它取决于如何在系统上安装ssh。为了验证它是同一个原因,我需要diff输出。

Save the following to a file log_shell_env.sh,

将以下内容保存到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 git@github.com="$(ssh -T git@github.com 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

set execute permission and run it twice:
1. From the console without parameter
2. From your python script with parameter '.python'
Please, run it realy from the same python script!

设置执行权限并运行两次:1。从没有参数2的控制台。从带有参数的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)

Do a diff shell_env shell_env.python > shell_env.diff The resulting shell_env.diff should show not more than the following diffs:

做一件事。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

Come back and comment, if you get more diffs update your Question with the diff output.

回来评论一下,如果你有更多的问题,用diff输出来更新你的问题。

#9


1  

Use the following python code. This will import the os module in python and make a system call with sudo permissions.

使用以下python代码。这将导入python中的os模块,并使用sudo权限进行系统调用。

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

#1


11  

sounds like you need to give your ssh command a public or private key it can access perhaps:

听起来好像需要给ssh命令一个公钥或私钥,它可以访问:

ssh -i /backup/home/user/.ssh/id_dsa user@unixserver1.nixcraft.com

-i tells it where to look for the key

-我告诉它去哪里找钥匙。

#2


5  

This problem is caused by the git repo authentication failing. You say you are using SSH, and git is complaining about publickey auth failing. Normally you can use git commands on a private repo without inputting a password. All this would imply that git is using ssh, but in the latter case it cannot find the correct private key.

这个问题是由于git repo身份验证失败引起的。您说您正在使用SSH, git正在抱怨publickey auth失败。通常,您可以在私有repo上使用git命令,而无需输入密码。所有这些都意味着git正在使用ssh,但是在后一种情况下,它无法找到正确的私钥。

Since the problem only manifests itself when run through another script, it is very likely caused by something messing with the environment variables. Subprocess.call should pass the environment as is, so there are a couple of usual suspects:

由于这个问题只在运行另一个脚本时显现出来,很可能是由于环境变量的混乱造成的。子流程。调用应该按原样通过环境,因此有几个常见的怀疑因素:

  1. sudo.
    • if you are using sudo, it will pass a mostly empty environment to the process
    • 如果您使用的是sudo,它将会传递一个主要为空的环境。
  2. sudo。如果您使用的是sudo,它将会传递一个主要为空的环境。
  3. the python script itself
    • if the python script changes its env, those changes will get propagated to the subprocess too.
    • 如果python脚本更改其env,这些更改也将传播到子进程。
  4. 如果python脚本更改其env,那么这些更改也将传播到子进程。
  5. sh -lor su -
    • these commands set up a login shell, which means their environment gets reset to defaults.
    • 这些命令设置了一个登录shell,这意味着它们的环境将被重置为默认值。
  6. 这些命令设置了一个登录shell,这意味着它们的环境将被重置为默认值。

Any of these reasons could hide the environment variables ssh-agent (or some other key management tool) might need to work.

任何这些原因都可以隐藏环境变量ssh-agent(或其他关键管理工具)可能需要工作。

Steps to diagnose and fix:

诊断和修复的步骤:

  1. Isolate the problem.

    隔离问题。

    • Create a minimal python script that does nothing else than runs subprocess.call(['./update.sh']). Run both update.sh and the new script.
    • 创建一个最小的python脚本,除了运行subprocess.call(['./update.sh'])之外什么都不做。运行这两个更新。sh和新剧本。
  2. Diagnose the problem and fix accordingly:

    对问题进行诊断并据此进行修复:

    a) If update.sh works, and the new script doesn't, you are probably experiencing some weird corner case of system misconfiguration. Try upgrading your system and python; if the problem persists, it probably requires additional debugging on the affected system itself.

    如果更新。sh起作用,而新脚本不起作用,您可能会遇到一些系统配置错误的奇怪情况。尝试升级您的系统和python;如果问题持续存在,可能需要对受影响的系统本身进行额外的调试。

    b) If both update.sh and the new script work, then the problem lies within the outer python script calling the shell script. Look for occurrences of sudo, su -, sh -l, env and os.environ, one of those is the most likely culprit.

    b)如果两个更新。sh和新的脚本工作,然后问题就出现在调用shell脚本的外部python脚本中。查找出现sudo、su -、sh -l、env和os的情况。环境,其中之一是最可能的罪魁祸首。

    c) If neither the update.sh nor the new script work, your problem is likely to be with ssh client configuration; a typical cause would be that you are using a non-default identity, did not configure it in ~/.ssh/config but used ssh-add instead, and after that, ssh-agent's cache expired. In this case, run ssh-add identityfile for the identity you used to authenticate to that git repo, and try again.

    c)如果没有更新。无论是sh还是新的脚本工作,您的问题都可能与ssh客户机配置有关;一个典型的原因是您正在使用一个非默认标识,没有在~/中配置它。ssh/config但是使用了ssh-add,之后,ssh-agent的缓存过期。在这种情况下,为您用来对git repo进行身份验证的标识运行ssh-add identityfile,并再次尝试。

#3


3  

I believe this answer will help you: https://serverfault.com/questions/497217/automate-git-pull-stuck-with-keychain?answertab=votes#tab-top

我相信这个答案会对你有所帮助:https://serverfault.com/questions/497217/automate-git-pull- stutwith- keychain?answer =vote # table -top

I didn't use ssh-agent and it worked: Change your script to the one that follows and try.

我没有使用ssh-agent,它是有效的:将您的脚本更改为后面的脚本并进行尝试。

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

This assumes that you have configured correctly your ssh key.

这假定您已经正确配置了ssh密钥。

#4


3  

It seems like your version control system, need the authentication for the pull so can build the python with use of pexpect,

看起来像你的版本控制系统,需要身份验证才能使用pexpect构建python,

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

#5


2  

Try using the sh package instead of using the subprocess call. https://pypi.python.org/pypi/sh I tried this snippet and it worked for me.

尝试使用sh包,而不是使用子进程调用。https://pypi.python.org/pypi/sh我尝试了这个片段,它对我很有用。

#!/usr/local/bin/python

import sh

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

Output:

输出:

Already up-to-date.

已经更新。

#6


2  

import subprocess 

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

#7


1  

With Git 1.7.9 or later, you can just use one of the following credential helpers:

使用Git 1.7.9或更高版本,您可以使用以下凭证助手之一:

With a timeout

用一个超时

git config --global credential.helper cache

... which tells Git to keep your password cached in memory for (by default) 15 minutes. You can set a longer timeout with:

…它告诉Git将密码缓存在内存中15分钟(默认情况下)。您可以设置较长的超时时间:

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

(That example was suggested in the GitHub help page for Linux.) You can also store your credentials permanently if so desired.

(这个例子在GitHub的Linux帮助页面中得到了建议。)如果需要,您还可以永久保存您的凭据。

Saving indefinitely

无限期保存

You can use the git-credential-store via

你可以通过git认证商店

git config credential.helper store

GitHub's help also suggests that if you're on Mac OS X and used Homebrew to install Git, you can use the native Mac OS X keystore with:

GitHub的帮助还建议,如果你在Mac OS X上使用Homebrew安装Git,你可以使用本地Mac OS X keystore:

git config --global credential.helper osxkeychain

For Windows, there is a helper called Git Credential Manager for Windows or wincred in msysgit.

对于Windows,有一个助手名为Git凭据管理器,用于Windows或msysgit中的wincred。

git config --global credential.helper wincred # obsolete

With Git for Windows 2.7.3+ (March 2016):

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

git config --global credential.helper manager

For Linux, you can use gnome-keyring(or other keyring implementation such as KWallet).

对于Linux,您可以使用gnome-keyring(或其他keyring实现,如KWallet)。

Finally, after executing one of the suggested command one time manually, you can execute your script without changes in it.

最后,在手动执行一个建议的命令后,您可以执行您的脚本而不需要修改。

#8


1  

I can reproduce your fault. It has nothing to do with permission, it depends how your ssh are installed on your system. To verify it's the same cause i need the diff output.

我可以重复你的错误。它与权限无关,它取决于如何在系统上安装ssh。为了验证它是同一个原因,我需要diff输出。

Save the following to a file log_shell_env.sh,

将以下内容保存到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 git@github.com="$(ssh -T git@github.com 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

set execute permission and run it twice:
1. From the console without parameter
2. From your python script with parameter '.python'
Please, run it realy from the same python script!

设置执行权限并运行两次:1。从没有参数2的控制台。从带有参数的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)

Do a diff shell_env shell_env.python > shell_env.diff The resulting shell_env.diff should show not more than the following diffs:

做一件事。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

Come back and comment, if you get more diffs update your Question with the diff output.

回来评论一下,如果你有更多的问题,用diff输出来更新你的问题。

#9


1  

Use the following python code. This will import the os module in python and make a system call with sudo permissions.

使用以下python代码。这将导入python中的os模块,并使用sudo权限进行系统调用。

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