在Windows上从Python执行bash脚本

ezykj2lf  于 2023-09-29  发布在  Python
关注(0)|答案(3)|浏览(152)

我正在尝试编写一个Python脚本,它将执行我在Windows机器上的Bash脚本。到目前为止,我一直在使用Cygwin终端,所以执行bash脚本RunModels.scr就像执行./RunModels.scr一样简单。现在我希望能够利用Python的subprocess,但是因为Windows没有内置的功能来处理bash,所以我不知道该怎么做。
我正在尝试模拟./RunModels.scr < validationInput > validationOutput
我最初是这样写的:

os.chdir(atm)
vin = open("validationInput", 'r')
vout = open("validationOutput", 'w')
subprocess.call(['./RunModels.scr'], stdin=vin, stdout=vout, shell=True)
vin.close()
vout.close()
os.chdir(home)

但在花了一段时间试图弄清楚为什么我的访问被拒绝后,我意识到我的问题不是文件权限,而是我试图在Windows上执行bash文件的事实。有人能解释一下如何使用python脚本在windows上执行带有定向输入/输出的bash脚本吗?
编辑**(跟进问题)**:
谢谢你的回复,我需要我的bash.exe的完整路径作为第一个参数。但是现在,RunModels.scr中的命令行调用在python输出中以command not found的形式返回。例如,lscpmake。对此有什么建议吗?

  • 跟进#2*:我更新了我的呼叫:

subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'], stdin=vin, stdout=vout, cwd='C:\\path\\dir_where_RunModels\\')
我现在得到的错误是/usr/bin/bash: RunModels.scr: No such file or directory。使用cwd似乎对这个错误没有任何影响,无论如何,子进程都在/usr/bin/bash中查找RunModels.scr

  • 自我回答 * 我需要在调用中指定RunModels.scr的路径,并使用cwd

subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'C:\\path\\dir_where_RunModels\\RunModels.scr'], stdin=vin, stdout=vout, cwd='C:\\path\\dir_where_RunModels\\')
但另一个问题...
无论指定cwd如何,RunModels.scr执行的命令都会抛出错误,就好像RunModels.scr在错误的目录中一样。脚本执行,但cpcd抛出错误no such file or directory。如果我通过命令行导航到RunModels.scr所在的位置,并以老式的方式执行它,我不会得到这些错误。

mi7gmzs6

mi7gmzs61#

Python 3.4及以下

只需将bash.exe放在subprocess.call参数列表的第一位。您可以删除shell=True,在这种情况下没有必要。

subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'], 
                 stdin=vin, stdout=vout,
                 cwd='C:\\path\\dir_where_RunModels\\')

根据bash的安装方式(是否在PATH中),您可能必须使用bash可执行文件的完整路径。

Python 3.5及以上版本

subprocess.call()已被subprocess.run()有效地取代。

subprocess.run(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'], 
                 stdin=vin, stdout=vout,
                 cwd='C:\\path\\dir_where_RunModels\\')

编辑:

关于第二个问题,您可能需要向shell调用添加-l选项,以确保它读取所有重启命令文件,如/etc/profile。我假设这些文件包含bash中$PATH的设置。

编辑二:

RunModels.scr的开头添加类似pwd的内容,这样您就可以验证您是否真的在正确的目录中。检查rc-files中是否没有cd命令!

编辑3:

如果bash找不到脚本中调用的某个命令,也会生成错误/usr/bin/bash: RunModels.scr: No such file or directory。尝试将-v选项添加到bash,看看是否会提供更多信息。

bt1cpqcv

bt1cpqcv2#

比公认的答案更好的解决方案是使用executable关键字参数来指定shell的路径。在幕后,Python做了一些类似于

exec([executable, '-c`, subprocess_arg_string])

具体来说,在这个例子中

subprocess.call(
    './RunModels.scr',
    stdin=vin, stdout=vout,
    shell=True,
    executable="C:/cygwin64/bin/bash.exe")

(值得庆幸的是,Windows允许您使用正斜杠而不是反斜杠,这样您就可以避免使用双反斜杠或使用原始字符串的要求。

zsbz8rwp

zsbz8rwp3#

以下是我在Windows上的工作

result = subprocess.run(
    ["bash", "-c", "./mysql2sqlite.sh temp.sql"],
    capture_output=True,
).stdout.decode("utf-8")

在Windows系统路径中使用git-for-Windows的bash

相关问题