php - PHP shell_exec 复合命令在后台运行
问题描述
我有几个 CSV 文件,我试图通过终端中的 mysql 运行并发加载数据命令来加载到同一个数据表中。该表一开始是空的,没有索引。
当每个加载数据命令完成时,我希望命令点击一个 URL 来说明加载数据已经完成,所以我可以做一些清理工作,比如删除 csv 文件和电子邮件系统管理员等。
我可以让 mysql 命令执行(单独执行)并将其输出发送到 null,这在 PHP 中适用于跳到下一个循环。
我可以使用 && 在 mysql 命令之后执行 curl 命令
如果我通过 SSH 在服务器上的 shell 中尝试此操作,则结尾 & 使其在后台运行。
但是,在 PHP 中通过 shell_exec() 或 exec() 运行的完全相同的命令会等待整个命令完成。
我知道我可以使用 mysqlimport 一次将多个文件导入到多个表中,但是我找不到使用它将多个文件导入到一个表中的方法。
我想关闭 mysql 执行 N 加载数据命令并继续 PHPP 脚本而不等待响应。
当前使用的命令:
mysql --host=localhost --user='user' --password='pass' --database='db' --local-infile -e \"LOAD DATA LOCAL INFILE '/path/to_1.csv' INTO TABLE table FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' (field1, field2, field3)\" >/dev/null 2>&1 && curl 'http://my.url?p=1&j=2&csv=1' >/dev/null 2>&1 &
以及发出该命令的 PHP:
for($i = 1; $i <= $fileNumber; $i++){
//launch mysql passing proper details
$command = "mysql --host=localhost --user='".DB_DATA_USER."' --password='".DB_DATA_PASSWORD."' --database='".DB_DATA_NAME."' --local-infile";
//tell mysql to execute a load data query and send the results to null
$command .= " -e \"LOAD DATA LOCAL INFILE '/path/to_".$i.".csv' INTO TABLE ".$table." FIELDS TERMINATED BY ',' LINES TERMINATED BY '".PHP_EOL."' (field1, field2, field3)\" >/dev/null 2>&1 ";
//after mysql finishes, curl the update url and send curls output to null, doing the whole lot in the background (so loop continues)
$command .= " && curl 'http://my.url?p=1&j=2&csv=".$i."' >/dev/null 2>&1 &";
exec($command);
}
我尝试过的事情
我没有在命令之间使用 && ,而是尝试使用管道 | mysql 输出到 curl。不幸的是,由于某种原因,这会导致在 mysql load data 命令完成之前执行 curl 命令。
因此,为了澄清这个问题,我如何调整命令或 php 代码,以便在调用 shell_exec 或 exec 时不等待响应?
该命令以其当前形式工作。令人困惑的是,当通过终端执行命令时,它会立即返回输入,但通过 PHP 会等待结果。
非常感谢。
回答:
我最终使用每个命令对的 bash 脚本对其进行排序,并调用该脚本将总输出发送到 /dev/null。
然后唯一的限制是我的 inndb 表的表锁定超时。事实证明,让它们以并行方式运行比一次将一个加载数据运行到同一个表中要慢 - 大概将多个插入缓冲区处理到同一个表中比简单地一次从一个 CSV 中饱和插入速率需要更多的时间。
为帮助喝彩。
解决方案
推荐阅读
- azure - Luis 批量测试未显示自定义实体
- javascript - nodejs中的charAt没有按预期工作
- web-services - 访问对象私有属性
- java - Log4j2 + logback 意外导入似乎破坏了我的 Spring-boot 日志
- c++ - 如何将大型元数据文件读入 C++ 中的数组
- soap - Sabre 用于多城市搜索的 SOAP 方法
- excel - VBA - 计算 Range 对象中的列数
- javascript - React 和 Express 阻止了跨域请求
- javascript - 将 vuex 的状态传递给图表 - vue
- ios - UIButton press 不适用于 IF 语句