由于节点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'
.
这样做的原因是execFile
与exec
不同,默认情况下直接生成命令而不先生成 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);
}
});