【问题标题】:bash set environment variable before command in scriptbash 在脚本中的命令之前设置环境变量
【发布时间】:2018-02-04 21:57:59
【问题描述】:

我编译我的项目:

debug=yes make -j4debug=no make -j4

调试变量更改了 Makefile 中的一些编译器标志

我没有在 shell 中重复输入这个,而是编写了这个脚本(我们称之为daemon):

#!/bin/bash

inotifywait -q -m -e close_write `ls *.c* *.h*` |
while read; do
    make -j4
done

所以我只做./daemon,它会在写入文件时自动构建。

但是,我希望能够像这样将debug=no make -j4 传递给./daemon 脚​​本:

./daemon debug=no make -j4

所以我修改了脚本:

#!/bin/bash

if [ $# -lt 1 ]; then
    echo "Usage `basename $0` [COMMAND]"
    exit 1;
fi
inotifywait -q -m -e close_write `ls *.c* *.h*` |
while read; do
    "$@"
done

这适用于./daemon make -j4,但是当我说daemon debug=no make -j4 时出现以下错误:

./daemon: line 9: debug=no: command not found

我怎样才能使debug=no 被识别为变量而不是daemon 脚本中的命令?

谢谢

【问题讨论】:

  • 不要这样使用ls;只需直接使用 glob,如 inotifywait -q -m -e close_write *.c* *.h* | ...

标签: bash shell makefile environment-variables gnu-make


【解决方案1】:

"$@" 的扩展在任何预命令分配被识别之后被解析。您需要做的就是确保debug=... 在运行make 的命令的环境中,这是您的daemon 脚本。

debug=no ./daemon make -j4

【讨论】:

    【解决方案2】:

    变量扩展只会成为参数(包括第零个参数:命令名称)。

    他们永远不会:

    • 重定向,所以你不能var='> file'; cmd $var
    • Shell 关键字或运算符,所以你不能var='&'; mydaemon $var
    • 分配,包括前缀分配,所以你不能像你发现的那样var='debug=yes'; $var make
    • 命令扩展、循环、进程替换、&&/||、转义序列或其他任何内容。

    如果您想这样做,那么您很幸运:有一个标准的 POSIX 工具可以将前导 key=value 对转换为环境变量并运行您想要的程序。

    它叫做env。这是一个例子:

    run() {
      env "$@"
    }
    
    run debug=yes make -j 4
    

    虽然 TBH 我会使用 chepner's solution

    【讨论】:

      【解决方案3】:

      您总是需要将 (env) 变量设置放在命令的开头,即“daemon”之前。

      【讨论】:

        猜你喜欢
        • 2015-12-24
        • 1970-01-01
        • 2013-11-15
        • 2016-10-07
        • 1970-01-01
        • 1970-01-01
        • 2012-06-07
        • 1970-01-01
        • 2011-03-05
        相关资源
        最近更新 更多