我如何用python代码编写bash脚本

时间:2018-12-18 19:52:41

标签: python bash

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

  

/ Users / {PATH-TO-SDK} /28.0.3/aapt转储   徽章com.squareup.cash.apk | sed -n   “ s /。 versionName ='([^'] )。* / \ 1 / p”

我正在尝试使用os时将其嵌入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:扫描字符串文字时会停工

我该如何解决?

3 个答案:

答案 0 :(得分:1)

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

在相当新近的Python上,您应该优先使用subprocess.run()而不是subprocess.Popen(),并且绝对要避免使用os.system(),这根本不允许您捕获其输出。

subprocess允许您使用shell=True传递shell命令(当然,您必须使用正确的引号),但是如果您可以替换sed调用,则不会需要外壳的原因,这使得整个事情变得更易于理解和管理,并显着减少了开销。自己将命令行拆分成一个数组需要付出很小的代价。 (或者,如果您真的不打扰,请使用shlex.split()。)

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]

答案 1 :(得分:0)

您的字符串带有双引号,以双引号结尾。而是用三引号引起来:

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

此外,我建议不要使用os.system,而应使用subprocess

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注入攻击来打开程序),因此只有在经过清理的输入下才能这样做。

答案 2 :(得分:-1)

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

阅读python: SyntaxError: EOL while scanning string literal

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)