的语法subprocess.call(Win7 x64)

2024-09-27 23:21:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图使用subprocess.call()调用不在本地Python目录中的.exe文件。命令(当我把它输入命令提示符)具体如下:"C:\Program Files\R\R-2.15.2\bin\Rscript.exe" --vanilla C:\python\buyback_parse_guide.r

脚本运行,执行我需要做的事情,并且我已经确认输出是正确的。

下面是我的python代码,我认为它可以做同样的事情:

## Set Rcmd
Rcmd = r'"C:\Program Files\R\R-2.15.2\bin\Rscript.exe"'
## Set Rargs
Rargs = r'--vanilla C:\python\buyback_parse_guide.r'

retval = subprocess.call([Rcmd,Rargs],shell=True)

当我在Python控制台中调用retval时,它返回1,.R脚本不运行,但我没有得到任何错误。我很确定这是一个非常简单的语法错误。。。帮忙吗?非常感谢!


Tags: 脚本binparsefilescallprogram事情exe
2条回答

根据the docs,Rscript:

… is an alternative front end for use in #! scripts and other scripting applications.

… is convenient for writing #! scripts… (The standard Windows command line has no concept of #! scripts, but Cygwin shells do.)

… is only supported on systems with the execv system call.

因此,这不是在Windows下从另一个程序运行R脚本的方法。在

This answer说:

Rscript.exe is your friend for batch scripts… For everything else, there's R.exe

因此,除非您有充分的理由在批处理脚本之外使用Rscript,否则应该切换到R.exe。在

你可能想知道它为什么在命令提示符但不是Python的。我不知道这个问题的答案,我认为不值得通过代码挖掘或试验来找出答案,但我可以做出一些猜测。在

一种可能是,当您从命令行运行时,这是一个控制终端的cmd.exe,而当您从subprocess.call(shell=True)或{}运行时,这是一个无头cmd.exe。运行一个.bat/.cmd批处理文件会得到一个非headless cmd,但直接从另一个应用程序运行cmd则不会。历史上,R在处理Windows终端时遇到了各种各样的复杂问题,这就是为什么它们以前有单独的Rterm.exe文件以及Rcmd.exe工具。现在,它们都被合并到R.exe中,不管怎样它都可以正常工作。但是如果你试着去做医生说不该做的事情,那可能没有经过测试,这是完全合理的,它可能不起作用。在

不管怎样,在某些情况下,它为什么能起作用并不重要,即使它没有被记录下来。当然,这并不意味着它应该在其他没有文档记录的情况下工作,或者您应该尝试强制它这样做。只要做正确的事情并运行R.exe而不是Rscript.exe。在

除非你有一些信息与我在文件中找到的所有信息以及我能找到的任何地方相矛盾,否则我会把钱押在Rscript.exe这本身就是问题所在。在

您必须阅读有关Rscript.exeR.exe之间调用差异的文档,但它们并不相同。根据the intro docs,:

If you just want to run a file foo.R of R commands, the recommended way is to use R CMD BATCH foo.R

根据您的上述评论:

When I type "C:\R\R-2.15.2\bin\i386\R.exe" CMD BATCH C:\python\buyback_parse_guide.r into cmd.exe, the .R script runs successfully. What's the proper syntax for passing this into python?

那要看平台了。在Windows上,参数列表会变成字符串,因此最好只使用字符串,这样就不必调试连接;在Unix上,字符串被拆分为参数列表,因此最好使用列表,这样就不必调试连接。在

因为路径中没有空格,所以我会去掉引号。在

所以:

rcmd = r'C:\R\R-2.15.2\bin\i386\R.exe CMD BATCH C:\python\buyback_parse_guide.r'
retval = subprocess.call(rcmd)

引用the docs

If shell is True, it is recommended to pass args as a string rather than as a sequence.

将其拆分(手动或通过shlex)只是让subprocess能够重新组合它们,这样shell就可以再次拆分它们,这是愚蠢的。在

我不知道你为什么认为你需要shell=True。(如果你没有一个好的理由,你通常不会想要它…)但是即使没有shell=True

On Windows, if args is a sequence, it will be converted to a string in a manner described in Converting an argument sequence to a string on Windows. This is because the underlying CreateProcess() operates on strings.

所以,只需给shell命令行:

Rcmd = r'"C:\Program Files\R\R-2.15.2\bin\Rscript.exe"  vanilla C:\python\buyback_parse_guide.r'
retval = subprocess.call(Rcmd, shell=True)

相关问题 更多 >

    热门问题