Python 正在执行的子进程在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\

我在一个拥有Jython2.5的系统中工作,但是我需要能够调用一些Google的API,所以我编写了一个离线脚本,我想从我的Jython环境中调用它,并返回给我一些小数据。比如一个JobID或者一个表单URL或者来自谷歌的东西

我尝试了很多方法,但是我总是从Windows返回一个错误,说它找不到指定的文件

路径有两种方式

使用字符串的第一种方法

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就是将字符串拆分为传递给OS
execv
-系列系统调用的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用于将字符串拆分为传递给OS
execv
-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
参数。