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

时间:2018-07-18 11:52:56

标签: npm sh package.json csh

我想调用其他其他脚本,具体取决于是否指定了参数:

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

npm运行参数

应输入“ Bar”。

  

npm运行paramtest-随便

应该给“ 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

1 个答案:

答案 0 :(得分: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"
}

如果第一个参数为“一个”,则打印所有参数,否则为“ false”。当然,我们假设npm run-script使用的是类似sh的外壳,而不是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只是用引号引起来,并连接到脚本命令。就外壳语法而言,这意味着它们最终将作为fi的参数。 sh当然会拒绝这样做,因为fi只是结束if的内置对象,没有参数。

我们的目标更像是

sh -c 'if [ "$1" = one ]; then printf %s\\n "$@"; else echo false; fi' sh "one" "two" "three"

这里onetwothree是sh本身的参数,因此成为参数变量$1$2和{{1} }。 npm不允许我们直接执行此操作,但是我们可以通过将脚本包装在shell函数中来完成相同的事情:

$3

此处的脚本以该函数的调用结束,因此npm最终将对该调用的参数进行连接,最终将该函数调用为"scripts": { "myscript": "f() { if [ \"$1\" = one ]; then printf %s\\\\n \"$@\"; else echo false; fi; }; f" }

f "one" "two" "three"