在开发中我们在特定的场合下可能需要一些脚本来批量处理我们的业务逻辑,在nodejs如何调用shell脚本呢?
项目下新建脚本文件
touch newFile.sh
修改文件权限
chmod 777 newFile.sh 修改文件为可读可写可执行
//使用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 });
}
})
}
执行成功会返回脚本执行的命令
publishAllDocs.sh 主意:此处说明的都是非window下的shell脚本 window的.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
在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字符串替换
在JS里面我们可以使用replace去做字符串的替换,那么shell里面改如何实现?
示例:
string “abc12342341”
${string/%41/bb}
//abc123423bb %以什么结尾来匹配,根php中的$有点像语法
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
注意