npm - npm 运行脚本中参数的 if-else

标签 npm sh package.json csh

我想调用不同的其他脚本,具体取决于是否给出了参数:

"paramtest": "if [ -z $1 ]; then echo Foo $1; else echo Bar; fi",

npm run paramtest



应该给“酒吧”。

npm run paramtest -- whatever



应该给“Foo what”。

但是在实践中我只得到: (参数是加到整行的,不是'传入')
> if [ -z $1 ]; then echo Foo; else echo Bar; fi "whatever
  sh: 1: Syntax error: word unexpected

我可以做什么更好?

基本上我是在运行完整的测试套件/只使用相同的命令进行单独测试之后......
"test" : "if [ -z $1 ]; then mocha ./test/**/*.test.js; else mocha $1

最佳答案

将它包装在 shell 函数中应该可以解决问题:

"test": "f() { if [ $# -eq 0 ]; then mocha './test/**/*.test.js'; else mocha -- \"$@\"; fi; }; f"
请注意,我稍微更改了 if 条件和 else 分支,因此您可以在必要时指定多个文件参数。
更简洁的方法:
"test": "f() { mocha -- \"${@:-./test/**/*.test.js}\"; }; f"
以这种方式使用 shell 函数可能看起来很熟悉,因为相同的技术通常用于 git aliases .

详细说明
让我们使用此脚本进行演示:
"scripts": {
    "myscript": "if [ \"$1\" = one ]; then printf %s\\\\n \"$@\"; else echo false; fi"
}
这里如果第一个参数是“one”,我们打印所有参数,否则我们打印“false”。我们当然假设 npm run-script正在使用类似 sh 的 shell ,而不是,例如,Windows 的 cmd.exe。
我在 npm documentation 中看不到任何东西特别详细说明了如何将参数传递给脚本,所以让我们看一下源代码(撰写本文时为 npm v6.14.7)。脚本似乎与其参数 here 结合在一起然后执行 here .本质上,npm run myscript -- one two three变成
sh -c 'if [ "$1" = one ]; then printf %s\\n "$@"; else echo false; fi "one" "two" "three"'
我们的论据 one two three只是引号转义并连接到脚本命令。就 shell 语法而言,这意味着它们将作为 fi 的参数结束。 . sh当然拒绝这个因为fi只是一个内置到结束 if并且不接受任何争论。
我们的目标更像是
sh -c 'if [ "$1" = one ]; then printf %s\\n "$@"; else echo false; fi' sh "one" "two" "three"
这里one , two , 和 three是 sh 本身的参数,因此成为参数变量 $1 , $2 , 和 $3在给定的脚本中。 npm 不允许我们直接这样做,但我们可以通过将我们的脚本包装在一个 shell 函数中来完成同样的事情:
"scripts": {
    "myscript": "f() { if [ \"$1\" = one ]; then printf %s\\\\n \"$@\"; else echo false; fi; }; f"
}
此处的脚本以调用函数结束,因此 npm 最终会将参数连接到此调用,最终将函数调用为 f "one" "two" "three" :
sh -c 'f() { if [ "$1" = one ]; then printf %s\\n "$@"; else echo false; fi; }; f "one" "two" "three"'

关于npm - npm 运行脚本中参数的 if-else,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51401352/

相关文章:

docker - 无法在最终Docker镜像中显示已安装npm的应用程序

node.js - Yeoman npm 在 Windows 上安装失败

javascript - 运行 packager 时 React Native 命名冲突错误,由 "lodash"和 "yeoman-generator"引起

node.js - 跨平台安装 npm 包 sqlite3

javascript - .babelrc 配置放在 package.JSON

linux - 如果没有停止,需要在 1 小时内重新启动服务器脚本

bash - 在 bash heredoc 中使用变量

bash - GNU上的GNU并行错误

node.js - -print 通过 npm 打印出字符串,但实际上通过 powershell 进行评估

npm - 无法启动 Electron 应用程序 - 缺少 package.json