Nodejs 命令行調用 exec 與 spawn 差異
比如在前端工程項目中 Nodejs 要調用命令行命令如:
yarn electron:build
exec 調用 yarn 命令,爲了能使命令行能實時打印輸出正在編譯的命令
以異步形式調用 exec 使用 stdout.on 方式監聽標準輸出,並打印
// 打包 electron
const buildElectron = () => {
return new Promise((resolve, reject)=> {
console.log(`yarn electron:build`)
const buildExec = exec(`yarn electron:build`, (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
reject()
return;
}
resolve()
});
buildExec.stdout.on('data', function(data) {
// 此處會實時打印輸出
console.log(data.toString())
});
})
}
// 啓動調用
buildElectron();
對於普通的命令行來說這足夠了,但當你的命令行輸出內容較大時,exec 命令就不行了
此時需要更換 spawn 命令
const command = spawn('yarn', ['command']);
spawn 使用 child_process 模塊的方法,但與 exec 不同的是,命令行的參數需要以數組的形式傳遞進去:
const { spawn } = require('child_process');
const command = spawn('yarn', ['command']);
command.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
command.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
command.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
然後就在我的 PC 電腦上報錯了
spawn yarn enoent
問一下 chatgpt 這是啥錯誤:
大至意思是 spawn 命令在執行時找不到 yarn 命令, 執行命令時需要帶上具體路徑
spawn('C:\Program Files\nodejs\yarn', ['command']);
按以上提示後運行以命令
還是報錯
繼續問 chatgpt
然後答案是,需要用 yarn.cmd 如下:
const { spawn } = require('child_process');
const command = spawn('C:\\Program Files\\nodejs\\yarn.cmd', ['command']);
寫死路徑,太不科學了,如果其它前端小夥伴接取代碼行動的話說不定會報錯。。。
最後發現直接用 yarm.cmd 即可,不用完整路徑
const { spawn } = require('child_process');
const command = spawn('yarn.cmd', ['command']);
問題又解決了
兩者不同
-
輸入輸出處理:
-
spawn: 提供了輸入輸出的流式接口。它返回了一個 ChildProcess 對象允許你流式讀寫
-
exec: 整個輸出都存到了 buffers 緩衝區,然後傳遞給回調。它使用起來雖然比較簡單,但當命令輸出的結果太大時就可能出錯。
-
-
指令執行
-
spawn: 使用新的進程啓動命令行,允許獨立運行。它允許長時間運行或可執行繼續交互命令
-
exec: 命令在 shell 中執行,輸出結果在緩存區。它使用方便,但輸出複雜結果是會有問題或無法在未中斷命令的情況下繼續進行交互命令
-
-
Shell 使用:
-
spawn: 默認不使用 Shell. 參數需要數組方式傳遞.
-
exec: 使用 Shell. 允許你使用 Shell 的一些特徵 pipes, input/output 重定向, 和命令的置換.
-
-
錯誤處理:
-
spawn: 在 ChildProcess 對象上發送錯誤事件。可以監聽並處理它
-
exec: 錯誤通過回調內第一個參數傳遞。可以據此處理
-
博客園: http://cnblogs.com/willian/
github: https://github.com/willian12345/