通过 QProcess 运行 .sh 脚本时出错

Posted

技术标签:

【中文标题】通过 QProcess 运行 .sh 脚本时出错【英文标题】:Error while running a .sh script via QProcess 【发布时间】:2014-12-09 08:36:08 【问题描述】:

我编写了一个 QT GUI 程序,按下按钮将执行 .sh 脚本。脚本的内容是-

echo -e 'attach database 'testdatabase.db' as 'aj';\n.separator ","\n.import ora_exported.csv qt_ora_exported' | sqlite3 testdatabase.db

基本上,该脚本会将 .csv 文件导入 sqlite 数据库。当脚本文件 (script.sh) 从 linux 终端 ($./script.sh) 手动运行时,它成功地将 .csv 文件导入到数据库表中。

但是,当我从我的 QT 程序中调用脚本时

void MainWindow::on_importButton_clicked()
    
    QProcess process;
    process.startDetached("/bin/sh",QStringList()<<"/home/aj/script.sh");

它编译成功,但在运行时按下按钮时会在控制台中显示错误消息。

错误:第 1 行附近:“-”附近:语法错误 错误:无法打开“ora_exported.csv”

这可能是什么原因???

已编辑

我现在已将 .sh 脚本更改为--

echo -e 'attach database 'testdatabase.db' as 'aj';\n.separator ","\n.import /home/aj/ora_exported.csv qt_ora_exported' | sqlite3 testdatabase.db

因此提供了我的 ora_exported.csv 的路径。结果运行时错误[错误:无法打开“ora_exported.csv”]已经消失,但另一个消息[错误:靠近第1行:靠近“-”:语法错误]仍然出现。

与之前的情况相同,使用 ./script.sh 成功将数据导入 sqlite3 db 表文件,但 QProcess 无法。

【问题讨论】:

脚本从该文件ora_exported.csv 不存在的目录运行和/或path 变量不包含该文件所在的目录。只需添加third argument: workingDirectory,并具有适当的值。 我已经注意到您的建议,并在脚本文件中包含了 .csv 的目录路径。情况还是一样。您能否指导我了解workingDirectory 在我的上下文中将是什么。我无法从 QT 文档链接中获得它。 @MarekR 正在讨论调用QProcess 的目录。只需将该目录添加到startDetached() 调用或在process 实例上调用setWorkingDirectory(),然后再调用startDetacjed() 【参考方案1】:

echo 是一个 shell 的内置命令,可能会有不同的行为。

例如拿这个测试脚本:echotest.sh

echo -e "123"

现在我们可以比较不同的结果:

$ bash echotest.sh
123
$ zsh echotest.sh
123
$ dash echotest.sh
-e 123

您可能在某些类似 Ubuntu 的操作系统上,/bin/sh 重定向到 dash。这将解释围绕“-”的错误。因此,如果您使用 echo,请专门设置您的 shell 或确保您的脚本适用于所有常见的 shell。


另外,你搞砸了你的报价

echo -e 'attach database 'testdatabase.db' as 'aj';\n.separator ","\n.import /home/aj/ora_exported.csv qt_ora_exported'

结果(第一行没有引号)

attach database testdatabase.db as aj;
.separator ","
.import /home/aj/ora_exported.csv qt_ora_exported

但你可能想要

echo -e "attach database 'testdatabase.db' as 'aj';\n.separator ','\n.import /home/aj/ora_exported.csv qt_ora_exported"

【讨论】:

好的,所以我在 QProcess 期间使用了 /bin/bash 并且没有出现错误,但它仍然没有触发 .sh 文件,我使用“附加数据库 'testdatabase.db' 作为 'aj'; \n.separator ','\n.import /home/aj/ora_exported.csv qt_ora_exported" 但 .sh 脚本仍然从终端执行,而不是从我的 QT 应用程序执行 目前没有运行时错误(使用/bin/bash后) 添加日志以获得更多见解(更新了我答案的中间部分)。 感谢提示,但没有观察到错误,因此未创建日志记录文件。 尝试对不同的输出类型使用附加模式和不同的文件。 (见编辑代码)【参考方案2】:
    您使用外部脚本更新数据库看起来很奇怪! 为什么不将“ora_exported.csv”文件名作为脚本参数传递?这将有助于解决问题。 我在谈论(打字)这个解决方案:
void MainWindow::on_importButton_clicked()
    
    QProcess::startDetached("/bin/sh",
                            QStringList()<<"/home/aj/script.sh",
                            "<location of: 'ora_exported.csv' file>");

【讨论】:

出于测试/学习目的,我正在使用外部脚本。一旦我取得一点进展,我将直接进行 db 到 db 通信。目前看来,您将 .csv 的位置作为 QProcess 中的参数的建议实际上解决了我的问题。非常感谢。对此的一个小行解释也受到高度赞赏。

以上是关于通过 QProcess 运行 .sh 脚本时出错的主要内容,如果未能解决你的问题,请参考以下文章

QProcess 附加到从脚本运行的可执行文件

Qt QProcess startDetached 无法结束进程(bash 会话)

QProcess 无法通过 QPushButton 执行终端行命令

如何使用 QProcess 同时运行多个 python 脚本

使用 QProcess 通过 PyQt 运行和监控系统进程

冻结后使用 QProcess 运行 Python 脚本