Python 正在执行的子进程在Windows上找不到指定的文件
我在一个拥有Jython2.5的系统中工作,但是我需要能够调用一些Google的API,所以我编写了一个离线脚本,我想从我的Jython环境中调用它,并返回给我一些小数据。比如一个JobID或者一个表单URL或者来自谷歌的东西 我尝试了很多方法,但是我总是从Windows返回一个错误,说它找不到指定的文件 路径有两种方式 使用字符串的第一种方法Python 正在执行的子进程在Windows上找不到指定的文件,python,subprocess,jython-2.5,Python,Subprocess,Jython 2.5,我在一个拥有Jython2.5的系统中工作,但是我需要能够调用一些Google的API,所以我编写了一个离线脚本,我想从我的Jython环境中调用它,并返回给我一些小数据。比如一个JobID或者一个表单URL或者来自谷歌的东西 我尝试了很多方法,但是我总是从Windows返回一个错误,说它找不到指定的文件 路径有两种方式 使用字符串的第一种方法 stringPath = r"C:\GooglePipes\Scripts\filetobq.py C:\GooglePipes\Keys\
stringPath = r"C:\GooglePipes\Scripts\filetobq.py C:\GooglePipes\Keys\DEV-BigQueryKey.json nofile C:\GooglePipes\BQ_Downtime\TESTFILE.CSV dataset1 table1"
第二种方法,作为序列(根据文档,使用shell=false
提供序列)
打电话给
data, err = Popen(seqPath, shell=True, stderr=PIPE, stdout=PIPE).communicate()
#Read values back in
print data
print err
将seqPath
替换为stringPath
以尝试任何一种方法
我整个周末都在做这个,每次我运行它,我都会从Windows上看到它
The system cannot find the path specified.
从err
打印。除此之外,我无法调试更多的程序。我真的不确定发生了什么。当我将stringPath
变量直接粘贴到计算机的命令窗口时,它会执行
?C:\GooglePipes\Scripts\filetobq.py C:\GooglePipes...
我还调用了subprocess.list2cmdline(seqPath)
来查看它的输出。它给了我一个惊喜?在绳子前面,但我还没弄明白那是什么意思。我可以将字符串的其余部分粘贴到命令窗口中,从问号开始执行
?C:\GooglePipes\Scripts\filetobq.py C:\GooglePipes...
我在shell上尝试了许多不同的true和false组合,将不同的参数传递到Popen
,使用双斜杠,并且从stack overflow和其他帮助论坛打开的选项卡不少于30个。我只是不知道在这一点上做什么,任何帮助都是感激的
编辑
那个?当我做一些额外的日志记录时,sting的开头实际上是一个空字符。这似乎是我问题的根源。我不明白它为什么会出现,但它出现在我的复制粘贴中。我开始手动打字,我让它工作了。当我用Jython程序输入路径时,它再次出现。最终错误是?/NULL字符 我回到了源值,程序在那里获取路径,它就在那里。我手动重新输入后,一切都开始工作了 如果您复制并粘贴我在问题中输入的内容,您可以通过字符串->ASCII转换器在字符串中看到空字符
>C:
>NULL 67 58
真是一堆废话***.最终错误是?/NULL字符 我回到了源值,程序在那里获取路径,它就在那里。我手动重新输入后,一切都开始工作了 如果您复制并粘贴我在问题中输入的内容,您可以通过字符串->ASCII转换器在字符串中看到空字符
>C:
>NULL 67 58
一堆废话***.
shell=False
对于一个字符串有多个参数来说是非常错误的(在UNIX上;Windows有自己的规则)——shell就是将字符串拆分为传递给OSexecv
-系列系统调用的argv元素列表的工作,传递多元素列表时不得使用shell=True
,除非该列表的第一个元素是shell脚本,其余元素是该脚本的参数。但这只是一个信息性的旁白,因为这不是你手头上的实际平台。@CharlesDuffy:为什么它是一个shell脚本很重要(只要它有一个shebang)?@davishering,带有subprocess.Popen([arg1,arg2,…],shell=True)
在UNIX上,arg1
不应该是shell脚本的名称,但是shell脚本本身的实际内联文本。它扩展到['sh','-c',arg1,arg2,…]
,并且sh
要求直接跟在-c
后面的参数是要执行的脚本文本。(在执行的上下文中,ARG2变为代码>0美元< /代码>,其后的参数变为<代码> $1 < /代码>等)@ DavisHerring,如果您不遵循该规则,您的其他参数将在不被尊重的情况下简单地消失:考虑<代码>子进程。Popen([’LS’,‘/tMP’,shell=true)< /C> >;code>/tmp在$0
中传递,但是shell脚本ls
不检查$0
,因此运行的程序ls
永远不会传递/tmp
参数。shell=False
对于单个字符串具有多个参数是非常错误的(在UNIX上;Windows有自己的规则)--shell用于将字符串拆分为传递给OSexecv
-family系统调用的argv元素列表,传递多元素列表时不得使用shell=True
,除非该列表的第一个元素是shell脚本,其余元素是该脚本的参数。但这只是一个信息性的旁白,因为这不是你手头上的实际平台。@CharlesDuffy:为什么它是一个shell脚本很重要(只要它有一个shebang)?@davishering,带有subprocess.Popen([arg1,arg2,…],shell=True)
在UNIX上,arg1
不应该是shell脚本的名称,但是shell脚本本身的实际内联文本。它扩展到['sh','-c',arg1,arg2,…]
,并且sh
要求直接跟在-c
后面的参数是要执行的脚本文本。(在执行的上下文中,ARG2变为代码>0美元< /代码>,其后的参数变为<代码> $1 < /代码>等)@ DavisHerring,如果您不遵循该规则,您的其他参数将在不被尊重的情况下简单地消失:考虑<代码>子进程。Popen([’LS’,‘/tMP’,shell=true)< /C> >;code>/tmp在$0
中传递,但是shell脚本ls
不检查$0
,因此运行的程序ls
永远不会传递/tmp
参数。