Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用python代码编写bash脚本_Python_Bash - Fatal编程技术网

如何用python代码编写bash脚本

如何用python代码编写bash脚本,python,bash,Python,Bash,为了从AndroidManifest.xml获取应用程序的版本,我要执行以下bash命令: /用户/{PATH-TO-SDK}/28.0.3/aapt转储 标记com.squareup.cash.apk | sed-n “s/.versionName='([^'])./\1/p” 我试图在使用操作系统时将其嵌入python脚本中: import os bashcommand = " /Users/{PATH-TO-SDK}/28.0.3/aapt dump badging com.squar

为了从AndroidManifest.xml获取应用程序的版本,我要执行以下bash命令:

/用户/{PATH-TO-SDK}/28.0.3/aapt转储 标记com.squareup.cash.apk | sed-n “s/.versionName='([^'])./\1/p”

我试图在使用操作系统时将其嵌入python脚本中:

import os

bashcommand = " /Users/{PATH-TO-SDK}/28.0.3/aapt dump badging 
com.squareup.cash.apk | sed -n "s/.*versionName='\([^']*\).*/\1/p" "
os.system(bashcommand)
但我有一个错误:

SyntaxError:扫描字符串文字时下线


我如何解决这个问题?

您的字符串有两个双引号,以部分结束。用三个引号将其括起来:

bashcommand = '''/Users/{PATH-TO-SDK}/28.0.3/aapt dump badging com.squareup.cash.apk | sed -n "s/.*versionName='\([^']*\).*/\1/p"'''
另外,我建议不要使用
os.system
,而是使用
子流程

import subprocess
process = subprocess.Popen(bashcommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
编辑

对于那些不想使用
Popen
,可以使用
call

res = subprocess.call(bashcommand, shell=True)

请注意,使用
shell=True
参数可能会带来安全风险(因为打开程序会受到shell注入攻击),因此只能使用经过消毒的输入。

如果您有多行语句,请用
'
三个引号括起来

阅读


不能嵌套引号;但实际上,我建议您在子流程中运行尽可能少的代码,并使用Python而不是
sed
进行清理

在最近的Python上,您应该优先使用
subprocess.run()
,而不是
subprocess.Popen()
,并且一定要避免
os.system()
,因为它根本不允许您捕获它的输出

subprocess
允许您使用
shell=True
传入shell命令(当然,您必须使用正确的引用),但是如果您可以替换
sed
调用,就没有理由需要shell,这使整个过程更易于理解和管理,并显著降低了开销。自己将命令行拆分成一个数组是一个很小的代价。(如果你真的不介意的话,也可以使用
shlex.split()


如果可以避免的话,不要使用Popen;这个命令显然应该全部在一行上。@tripleee它在我的控制台上给了我没有问题的输出。不确定你到底成功运行了什么。上面将尝试运行两个命令,后者是
com.squareup.cash.apk
。您的系统上是否安装了具有此名称的命令?它是做什么的?更多细节,请参见完美!谢谢@triplee,你能解释一下这个错误吗:回溯(最近一次调用最后一次):文件“manifestinfos.py”,第64行,在universal_newlines=True)文件“/Users/***/anaconda3/lib/python3.7/subprocess.py”,第468行,在run output=stdout,stderr=stderr)subprocess.CalledProcessError:Command'['/Users/***/Library/Android/sdk/build tools/28.0.3/aapt','dump','bading','com.squareup.cash.apk']'返回非零退出状态1。该命令未成功完成。如果您知道可以安全地忽略这一点,请取出
check=True
;但您确实需要检查该命令的文档,以了解其失败的原因。Hi@triplee,我将您的代码改编为针对多个应用程序循环,但我不理解错误。def getVersionName(pkg_name):result=run(['../aapt',dump',bading',pkg_name],stdout=PIPE,stderr=PIPE,universal_newlines=True)version=result.stdout.split(“VersionName=”)[1]。split(“””[0]当我执行函数getVersionName(“com.ubercab.apk”)时,它只对第一个应用程序有效#getVersionName(“com.bambuna.podcastainct”)我有一个索引器(列表索引超出范围)用于其他应用程序,你知道为什么吗?TY完全简单的解决方法是在
sed
脚本周围使用单引号,而不是双引号。也许可以切换到
r“原始字符串”
用于命令行,以避免Python使用反斜杠做…事情。
import os

bashcommand = ''' /Users/{PATH-TO-SDK}/28.0.3/aapt dump badging 
com.squareup.cash.apk | sed -n "s/.*versionName='\([^']*\).*/\1/p'''
os.system(bashcommand)
from subprocess import run, PIPE

result = run([
         '/Users/{PATH-TO-SDK}/28.0.3/aapt',
         'dump', 'badging', 'com.squareup.cash.apk'],
    stdout=PIPE, stderr=PIPE, check=True,
    universal_newlines=True)
version = result.stdout.split("versionName='")[1].split("'")[0]