不能使用 execFile 在 nodejs 中运行 curl



由于节点exec被弃用,我正在尝试将我的nodejs应用程序迁移到execFile,但是我遇到了卷曲调用的问题。

这是与 exec 合作:

const pab_state = `/usr/bin/curl -d '{"jsonrpc": "2.0", "id": 1, "method": "core.playback.get_state"}' -H 'Content-Type: application/json' http://192.168.1.59:6680/mopidy/rpc`
child = exec(pab_state, (error, stdout, stderr) => {

尝试迁移到execFile我在转义引号时遇到问题:

const pab_args = ['-d '{"jsonrpc": "2.0", "id": 1, "method": "core.playback.get_current_tl_track"}'',' -H 'Content-Type: application/json'',' http://192.168.1.59:6680/mopidy/rpc'];
child = execFile("/usr/bin/curl",pab_args, (error, stdout, stderr) => {

这是我得到的错误:

{"killed":false,"code":3,"signal":null,"cmd":"/usr/bin/curl -d '{"jsonrpc": "2.0", "id": 1, "method": "core.playback.get_current_tl_track"}'  -H 'Content-Type: application/json'  http://192.168.1.59:6680/mopidy/rpc"}

options参数中尝试指定 shell,如'/bin/bash'.

这样做的原因是execFileexec不同,默认情况下直接生成命令而不先生成 shell。这会导致curl命令由于缺少 shell 而无法正确执行。 解决此问题的方法是指定要在options参数中使用的 shell。

这里有一个例子,

const { execFile } = require("child_process");
const child = execFile(
"/usr/bin/curl",
[
"-H 'Content-Type: application/json'",
'-d '{"title":"foo","body":"bar","userId":"1"}'',
"https://jsonplaceholder.typicode.com/posts "
],
{ shell: "/bin/bash" },
function(error, stdout, stderr) {
if (error) {
throw error;
}
console.log(stdout);
}
);

我对 OP 也有类似的问题。cUrl 在终端上工作,但在 NodeJS 上我得到的是 HTTP 405。我可以看到 Exec 从此输入中生成了什么字符串。这是 ExecFile 日志中的spawnargs字段。

spawnargs:
[ '/bin/bash',
'-c',
'/usr/bin/curl -v -k -H "Content-Type: application/zip" --data-binary "@/tmp/<filename>.zip" http://<username>:<password>@<host>:8080/path/to/upload?name=<filename>.zip' ],

当我运行上面的命令时,它就可以工作了。我已经尝试过您的方法,但是看不到任何不同之处。我尝试了很多事情,甚至检查了文件权限,但不知道发生了什么。我怀疑我的 url 和参数中的字符串格式,但不确定。知道吗?

let url = `http://<username>:<password>@<host>:8080/path/to/upload?name=${filename}.zip` 
let resp = await execFile(`/usr/bin/curl`,
[
`-v -k -H "Content-Type: application/zip"`,
`--data-binary "@/tmp/${filename}.zip"`,
`${url}`
],
{shell:'/bin/bash'},
async function (error, stdout, stderr) {
if (error) {
console.log(`error: ${error.message}`);
resolve(error);
}
if (stderr) {
console.log(`stderr: ${stderr}`);
resolve(stderr);
}
});

最新更新