为什么 QProcess 转换 '='在我对空间的争论中

发布于 2024-09-05 07:29:17 字数 2466 浏览 7 评论 0原文

我在 Windows 上运行 Qt 程序时遇到了一个奇怪的错误。该程序使用 QProcess 生成一个带有两个参数的子进程。传递给 QProcess::start() 方法的程序和参数的形式如下:

"batchfile.bat" "--option1=some_value" "--option2=some_other_value\with_a\path"

由于某种原因,当这些选项到达批处理文件进行处理时,等号已转换为空格,现在看起来像:

"batchfile.bat" "--option1 some_value" "--option2 some_other_value\with_a\path"

因为这个,处理失败。有什么想法可能导致等号被空格代替吗?我正在使用 Qt 下载页面上找到的 QT 4.6.3 框架的 mingw 版本。

编辑: 这是实际的代码。它不是我写的(我是一个十足的 Qt 菜鸟),但我必须尝试让它工作。它是在两个版本的 RHEL(4 和 5)、OS X 和 Windows 上运行的自动构建系统的一部分。除了 Windows 之外,它在任何地方都可以正常工作。

QProcess sconsProcess;
sconsProcess.setWorkingDirectory(build.getBuildLocation());
sconsProcess.setProcessChannelMode(QProcess::MergedChannels);

qDebug()<<"Starting scons process:"<<build.getSconsLocation()<<QString("--variant=%1-%2").arg(build.getOs()).arg(build.getVariant())<<
          QString("--source-release=%1").arg(build.getSettings().getSetting("sourceReleaseLocation", QStringList()<<"BUILDLOCATION"<<"VERSION",
                    QStringList()<<build.getBuildLocation()<<build.getBuildPackage().getVersion()).toString());
sconsProcess.start(build.getSconsLocation(), QStringList()<<QString("--variant=%1-%2").arg(build.getOs()).arg(build.getVariant())<<
          QString("--source-release=%1").arg(build.getSettings().getSetting("sourceReleaseLocation", QStringList()"BUILDLOCATION"<<"VERSION",
                    QStringList()<<build.getBuildLocation()<<build.getBuildPackage().getVersion()).toString()));
qDebug()<<"Source release build process started";

在 Windows 中转换为的实际值(在第一个 qDebug() 打印调用中打印出来的位)是:

DEBUG: 启动 scons 进程: "V:\Glast_Software\Toaster\tools\Python2.5\Scripts\scons- 1.3.0.bat""--variant=Windows-i386-32bit-vc71-Debug""--source-release=V:\Glast_Software\Toaster\ReleaseManagerBuild\Windows-i386-32bit-vc71\Debug\ScienceTools\LATEST -1-3163\ScienceTools-LATEST-1-3163-source.zip”

但是在 scons-1.3.0.bat 内部(我让它回显所有执行的命令)传递的参数如下所示:

“--​​variant Windows-i386 -32bit-vc71-Debug" "--source-release V:\Glast_Software\Toaster\ReleaseManagerBuild\Windows-i386-32bit-vc71\Debug\ScienceTools\LATEST-1-3163\ScienceTools-LATEST-1-3163-source。 zip”

缺少等号。

编辑(2010 年 6 月 29 日): 我应该补充一点,该系统设计为使用 LSF 批处理排队系统在小型 Windows 批处理场上运行。仅当进程作为批处理作业运行时才会失败。当我在其中一台批处理机上从命令行运行该程序时,它运行良好并且完全按照预期执行操作。所以可能是环境问题。

I've run into a weird error with a Qt program running on Windows. The program uses QProcess to spawn a child process wit two arguments. The program and arguments passed to the QProcess::start() method are of the form:

"batchfile.bat" "--option1=some_value" "--option2=some_other_value\with_a\path"

For some reason by the time those options get to the batchfile for processing the equals signs have been converted to spaces and it now looks like:

"batchfile.bat" "--option1 some_value" "--option2 some_other_value\with_a\path"

because of this, the processing fails. Any ideas what could be causing the equal signs to be replaced by spaces? I'm using the mingw build of the QT 4.6.3 framework found on the Qt download page.

EDIT:
Here's the actual code. I didn't write it (I'm a complete Qt noob) but I've got to try to get it working. It's part of an automated build system that runs on two versions of RHEL (4 and 5), OS X, and Windows. And it works fine everywhere but Windows.

QProcess sconsProcess;
sconsProcess.setWorkingDirectory(build.getBuildLocation());
sconsProcess.setProcessChannelMode(QProcess::MergedChannels);

qDebug()<<"Starting scons process:"<<build.getSconsLocation()<<QString("--variant=%1-%2").arg(build.getOs()).arg(build.getVariant())<<
          QString("--source-release=%1").arg(build.getSettings().getSetting("sourceReleaseLocation", QStringList()<<"BUILDLOCATION"<<"VERSION",
                    QStringList()<<build.getBuildLocation()<<build.getBuildPackage().getVersion()).toString());
sconsProcess.start(build.getSconsLocation(), QStringList()<<QString("--variant=%1-%2").arg(build.getOs()).arg(build.getVariant())<<
          QString("--source-release=%1").arg(build.getSettings().getSetting("sourceReleaseLocation", QStringList()"BUILDLOCATION"<<"VERSION",
                    QStringList()<<build.getBuildLocation()<<build.getBuildPackage().getVersion()).toString()));
qDebug()<<"Source release build process started";

The actaul values that translates into in Windows (the bit that gets printed out in the first qDebug() print call) is:

DEBUG: Starting scons process: "V:\Glast_Software\Toaster\tools\Python2.5\Scripts\scons-1.3.0.bat" "--variant=Windows-i386-32bit-vc71-Debug" "--source-release=V:\Glast_Software\Toaster\ReleaseManagerBuild\Windows-i386-32bit-vc71\Debug\ScienceTools\LATEST-1-3163\ScienceTools-LATEST-1-3163-source.zip"

However inside the scons-1.3.0.bat (I had it echo all the commands executed) the passed parameters look like:

"--variant Windows-i386-32bit-vc71-Debug" "--source-release V:\Glast_Software\Toaster\ReleaseManagerBuild\Windows-i386-32bit-vc71\Debug\ScienceTools\LATEST-1-3163\ScienceTools-LATEST-1-3163-source.zip"

with the equal signs missing.

EDIT (6/29/10):
I should add that this system is designed to run on a small Windows batch farm using the LSF batch queuing system. It only fails when the process is running as a batch job. When I run this program from the command line on one of the batch machines, it works perfectly and does exactly what it is supposed to do. So maybe it is an environment problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

叶落知秋 2024-09-12 07:29:17

这很可能是因为引号没有通过(它们可能需要转义,请参阅 QProcess::start() 的文档)。

cmd.exe 将命令行选项中未引用的等号视为参数之间的分隔符,类似于空格或制表符。这只是 Windows cmd 脚本中众多奇怪之处之一:

C:\test>type c:\util\cmdechoargs.cmd
@echo off
setlocal
set /a i=0
echo args[*]: %*
:loop
if {%1} == {} goto :eof
echo argv[%i%]: %1
set /a i=%i% + 1
shift
goto :loop


C:\test>cmdechoargs testing=123
args[*]: testing=123
argv[0]: testing
argv[1]: 123

C:\test>cmdechoargs "testing=123"
args[*]: "testing=123"
argv[0]: "testing=123"

我遇到的关于如何在 Windows cmd 脚本中处理命令行参数的最佳文档是 Tim Hill 的“Windows NT Shell 脚本” - 只需一分钱即可使用!

根据更新中给出的示例,我认为您可能希望其中包含等号的选项在其中嵌入引号:

"\"--variant=%1-%2\""
"\"--source-release=%1\""

编辑-新材料

以下脚本有一个例程,它将从传递的参数中删除引号到一个cmd脚本。该例程使用我上面提到的 Tim Hill 书中的习惯用法/技术,在名为 RET 的环境变量中返回“取消引用”的参数。我从这里的示例中窃取了一些取消引用代码: http://ss64.com/nt/ syntax-esc.html,但使其处理空引号更加健壮。

@echo off
setlocal
set /a i=0
echo args[*]: %*
:loop
if {%1} == {} goto :eof
echo.
echo argv[%i%]: %1

call :dequote %1
set dequoted_arg=%RET%
echo argv[%i%] ^(dequoted^): %dequoted_arg%

set /a i=%i% + 1
shift
goto :loop


:dequote
setlocal
SET _string=###%1###
if {%_string%} == {######} goto :dequote_empty
if {%_string%} == {###""###} goto :dequote_empty
SET _string=%_string:"###=%
SET _string=%_string:###"=%
SET _string=%_string:###=%
goto :dequote_done

:dequote_empty
set _string=

:dequote_done
endlocal & (set RET=%_string%) & goto :eof

这种事情就是为什么你想要避免(在我看来)除了最简单的任务之外的 cmd 脚本。但是,我希望这可以帮助您通过批处理文件将未加引号的参数传递给 scons 进程。

There's a good chance that this is because the quotes aren't making it through (they may need to be escaped, see the docs for QProcess::start()).

cmd.exe treats equals signs in command line options that aren't quoted as a separator between arguments similar to a space or tab. Just one of very many bits of oddness in Windows cmd scripting:

C:\test>type c:\util\cmdechoargs.cmd
@echo off
setlocal
set /a i=0
echo args[*]: %*
:loop
if {%1} == {} goto :eof
echo argv[%i%]: %1
set /a i=%i% + 1
shift
goto :loop


C:\test>cmdechoargs testing=123
args[*]: testing=123
argv[0]: testing
argv[1]: 123

C:\test>cmdechoargs "testing=123"
args[*]: "testing=123"
argv[0]: "testing=123"

The best documentation I've come across for how to handle command line arguments in Windows cmd scripts is Tim Hill's "Windows NT Shell Scripting" - get one used for only a penny!

Based on the examples given in your update, I think you might want your options that have equals signs in them to have quotes embedded inside them:

"\"--variant=%1-%2\""
"\"--source-release=%1\""

Edit -- new material

The following script has a routine that will strip the quotes off of an argument passed to a cmd script. The routine returns the 'dequoted' argument in an environment variable named RET using an idiom/technique from Tim Hill's book I mentioned above. I stole some of the dequoting code from an example here: http://ss64.com/nt/syntax-esc.html, but made it a bit more robust to handle empty quotes.

@echo off
setlocal
set /a i=0
echo args[*]: %*
:loop
if {%1} == {} goto :eof
echo.
echo argv[%i%]: %1

call :dequote %1
set dequoted_arg=%RET%
echo argv[%i%] ^(dequoted^): %dequoted_arg%

set /a i=%i% + 1
shift
goto :loop


:dequote
setlocal
SET _string=###%1###
if {%_string%} == {######} goto :dequote_empty
if {%_string%} == {###""###} goto :dequote_empty
SET _string=%_string:"###=%
SET _string=%_string:###"=%
SET _string=%_string:###=%
goto :dequote_done

:dequote_empty
set _string=

:dequote_done
endlocal & (set RET=%_string%) & goto :eof

This kind of thing is why you want to avoid (in my opinion) cmd scripts except for the simplest of tasks. But, I hope this helps you pass unquoted arguments to your scons process through your batch file.

疯了 2024-09-12 07:29:17

您是否尝试过转义 = 符号?此外,示例中的路径肯定需要转义 \ 字符。

Have you tried escaping the = signs? Also, the paths in your example surely need escaping of the \ character.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文