如何通过Node的package.json运行含自定义函数的bash脚本并让函数生效
问题原因
- npm/yarn等包管理工具执行
package.json的scripts命令时,会默认启动一个独立的shell子进程运行指令,该进程的环境与你当前操作的终端父进程完全隔离,生命周期和script命令执行周期一致。 - 你直接在终端执行
source ./loadScripts.sh时,是将脚本内容加载到当前终端的shell主进程中执行,定义的函数会保存在当前进程的环境里,后续调用自然可以识别。 - 即便你在scripts中配置了
source ./loadScripts.sh,也只是在npm启动的临时子进程中加载函数,子进程在命令执行完成后会直接销毁,当前终端的主进程并没有留存这些函数定义,调用时就会提示command not found。 - 其余
sh ./loadScripts.sh/bash ./loadScripts.sh/./loadScripts.sh的配置逻辑更简单:都是启动独立子进程运行脚本,运行结束后进程直接销毁,函数完全不会暴露到当前终端环境。
解决方案
分两种场景选择对应方案:
场景1:需要在当前操作的终端中直接调用脚本内的函数
不要通过npm scripts执行,直接给source命令配置本地别名即可:
- 打开你当前shell的配置文件(Mac默认zsh对应
~/.zshrc,用bash的对应~/.bashrc) - 新增一行别名配置:
alias load-my-scripts="source /你的项目完整路径/loadScripts.sh"
- 执行
source ~/.zshrc(或对应配置文件)让配置生效,之后只要在终端执行load-my-scripts就可以加载所有函数,和手动敲source效果完全一致。
场景2:只需要在其他npm scripts命令中调用这些函数
直接在需要用到函数的script命令开头先执行source加载脚本即可,同一个script命令会在同一个子shell中执行,source后的指令可以正常识别函数:
{ "scripts": { "build": "source ./loadScripts.sh && myBuildFunction", "deploy": "source ./loadScripts.sh && myDeployFunction" } }
提示:如果配置后执行npm脚本提示
source: command not found,是因为部分系统npm默认用sh执行脚本,sh不支持source指令,改成指定bash执行即可,示例:"build": "bash -c 'source ./loadScripts.sh && myBuildFunction'"
内容的提问来源于stack exchange,提问作者vkan
相关产品推荐
相关产品推荐

