Node.js 调用 Shell 脚本的完整指南:从 execFile 到参数处理

作者:后端茶话

时间:2026-10-24

浏览:646

本文详细介绍如何在 Node.js 中通过 child_process 模块的 execFile 方法调用 Shell 脚本。涵盖文件权限设置、参数数组传递、脚本内 $1 等参数接收、for 循环处理空格分隔字符串、字符串替换语法以及 if 条件判断的完整实现步骤。

文章目录

背景

在开发过程中,有时需要借助脚本来批量处理业务逻辑。本文将探讨如何在 Node.js 环境中调用 Shell 脚本。

新建

在项目目录下创建一个新的脚本文件。


touch newFile.sh

修改文件权限


chmod 777 newFile.sh 修改文件为可读可写可执行

nodejs调用

读取文件


//使用nodejs的子进程里面的文件读取方法

const { execFile } = require(‘child_process');

示例


DocsService.publishAllDocs = (req, res) => {
 req.session.touch();
 const { docName, pathName, saveDocsList, docType } = req.body;
 var docText = req.body.docText;
 var newGit = req.body.newGit;
 //获取文件路径
 var filepath = path.join(__dirname, '../../bin/rnsource/publishAllDocs.sh');
 var fileArr, fileName, spath, dirnameBack, docbackList = [], docbackPath, docPath = "";
 var username = req.session.user_name;
 var str = docName+'/'+ pathName + '|'+ username;
 var reg = new RegExp(`^(${str})`);
 saveDocsList.map((item, index)=>{
   fileArr = item.pathName.split("/");
   fileName = fileArr[fileArr.length-1];
   if(docType == "docsify"){
     dirnameBack = fileName != "" ? `../../gitlib/docBackup/${docName}/docs/${item.pathName}`:`../../gitlib/docBackup/${docName}/docs/README.md`
   }else{
     spath = item.pathName.split(fileName)[0];
     dirnameBack = spath != "" ?'../../gitlib/docBackup/'+ docName+'/'+ spath +'/'+fileName:'../../gitlib/docBackup/'+ docName+'/' + fileName; 
   }

   docbackPath = path.join(__dirname, dirnameBack);
   docbackList.push(docbackPath);
   docPath += docbackPath + " ";
 })
 docPath += ""
 //cwd设置当前路径 我这边设置的就是nodejs代码js当前的位置
 execFile(filepath, [docName, docPath, docType], { cwd: '.' }, function(err, stdout, stderr){
   logger.info(stdout);
   if(err){
     loggerFileError({user:username,docName:docName,pathName:'all',operate:"gitbook文件一键发布",err});
     res.json({
       respCode: -1,
       errMsg: "一键发布失败"
     })
   }else{
     res.json({
       respCode: 0,
       msg: "一键发布成功"
     })
     gitPush({ docName, fileName, docbackPath: docbackList, username, pathName, docType })
     unblockFile({ docName, username, pathName, reg });
   }
 }) 
}

回调

脚本执行成功后,会返回相应的命令执行结果。

背景

execFile

  • 第一个参数指定要调用的外部程序,此处即为需要读取的文件路径。
  • 第二个参数用于向外部程序传递参数,必须封装在数组中。
  • 第三个参数是回调函数,用于获取外部程序的执行结果。

shell

以 publishAllDocs.sh 为例,本文讨论的内容仅适用于非 Windows 环境下的 Shell 脚本,Windows 的 .bat 脚本不在本文讲解范围内。


#$1文档最外层目录 $2当前修改的文件名 $3当前修改文件的目录
cd $(pwd)/gitlib/docs/$1
echo "come in"
for item in $2; do
  echo "${item}"
  cp -f ${item} ${item/docBackup/docs}
done
# echo "初始化进入"
echo "$(pwd)/gitlib/docs/$1"
if [ "$3" == "docsify" ];then
  #拷贝指定目录下的文件 如: $1/$3/$2 docs/cst/7e4ce1de04621e0b/
  #如 cp -rf ../../docBackup/wireless/docs/cst/7e4ce1de04621e0b/10708d589eedfffd.md ./docs/cst/7e4ce1de04621e0b/
  cp -rf ./docs ../../../public/docs/$1
else
  # 处理gitbook类型文档
  gitbook build
  echo "复制文档"
  cp -rf ./_book/* ../../../public/docs/$1
fi

参数接收

  • 根据业务调用时传入的数据来获取相应参数。
  • 直接使用 "$" 符号来获取参数值。
  • 获取参数的顺序与数据传入的顺序一致。
  • 需要注意的是,这里不是通过数组角标取值,数组中的第一个参数对应的是 $1。

for循环的使用

在 Shell 脚本中使用 for...in 的形式进行循环。

需要循环处理的循环体数据示例如下。

/Users/Desktop/work/docManager/docServer/gitlib/docBackup/mygitbook/docs/d09985fc67088b35/d09985fc67088b35.md /Users/Desktop/work/docManager/docServer/gitlib/docBackup/mygitbook/docs/d09985fc67088b35/d09985fc67088b35/6f7a2c61c9bac0a3.md /Users/Desktop/work/docManager/docServer/gitlib/docBackup/mygitbook/README.md /Users/Desktop/work/docManager/docServer/gitlib/docBackup/mygitbook/docs/d09985fc67088b35/d09985fc67088b35/6f7a2c61c9bac0a3.md

Shell 脚本中循环体的数据格式较为特殊,并非常规的数组或 JSON 结构。

它直接是以空格隔开的字符串,例如:“a b c d e”。


## $2就是脚本里面接收的业务的传参 按格式拼接好的数据 如上面数据示例
## 循环使用 for...in 记得;后面一定要加上do去执行循环体 最后使用done结束循环
## item循环体的每个子项 如:/Users/Desktop/work/docManager/docServer/gitlib/docBackup/mygitbook/docs/d09985fc67088b35/d09985fc67088b35.md
for item in $2; do
  echo "${item}"
  cp -f ${item} ${item/docBackup/docs}
done
## ${item/docBackup/docs} 字符串替换
## 此处是吧item路径里面的docBackup替换成docs 详细解释请看下面的shell字符串替换

shell指定字符串替换

在 JavaScript 中可以使用 replace 方法进行字符串替换,那么在 Shell 中该如何实现呢?

示例:

字符串 “abc12342341”

  • echo ${string/23/bb} //输出 abc1bb42341,仅替换第一次匹配。
  • echo ${string//23/bb} //输出 abc1bb4bb41,双斜杠表示替换所有匹配项。
  • echo ${string/#abc/bb} //输出 bb12342341,# 表示以指定内容开头进行匹配,类似于 PHP 中的 ^。
  • echo ${string/%41/bb} //输出 abc123423bb,% 表示以指定内容结尾进行匹配,类似于 PHP 中的 $。

if条件判断的使用

语法


if[];then
 ...
else
 ...
fi

示例


## 条件判断是使用[]而不是()
## []后面要加;
if [ "$3" == "docsify" ];then
  #拷贝指定目录下的文件 如: $1/$3/$2 docs/cst/7e4ce1de04621e0b/
  #如 cp -rf ../../docBackup/wireless/docs/cst/7e4ce1de04621e0b/10708d589eedfffd.md ./docs/cst/7e4ce1de04621e0b/
  cp -rf ./docs ../../../public/docs/$1
else
  # 处理gitbook类型文档
  gitbook build
  echo "复制文档"
  cp -rf ./_book/* ../../../public/docs/$1
fi

注意

  • 在条件判断中,字符串必须使用双引号 "" 包裹。
  • 如果条件判断中包含变量(字符串),变量也必须添加双引号 ""。
  • 条件判断的 [] 后面必须加上分号 ;,并且一定要使用 then 才能继续执行后续逻辑。
  • 条件判断语句最后必须以 fi 结尾。

到此这篇关于 node 中使用 shell 脚本的方法步骤的文章就介绍到这了,更多相关 node 使用 shell 脚本内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章