如何创建一个bash环境变量,该变量在命令之前作为环境变量的前缀?

如何创建一个bash环境变量,该变量在命令之前作为环境变量的前缀?,bash,environment-variables,Bash,Environment Variables,我似乎能够创建执行命令的环境变量;像这样: $ cat ./src FOO="echo" $ . ./src $ echo $FOO echo $ $FOO hello hello $ 有没有办法修改该环境变量,使其在命令之前作为另一个环境变量设置的前缀?也就是说,有没有办法解决以下问题 $ cat ./src FOO="MY_DIR=/tmp echo" $ . ./src $ echo $FOO MY_DIR=/tmp echo $ $FOO hello -bash: MY_DIR=/tm

我似乎能够创建执行命令的环境变量;像这样:

$ cat ./src
FOO="echo"
$ . ./src
$ echo $FOO
echo
$ $FOO hello
hello
$
有没有办法修改该环境变量,使其在命令之前作为另一个环境变量设置的前缀?也就是说,有没有办法解决以下问题

$ cat ./src
FOO="MY_DIR=/tmp echo"
$ . ./src
$ echo $FOO
MY_DIR=/tmp echo
$ $FOO hello
-bash: MY_DIR=/tmp: No such file or directory
$
也就是说,我希望在shell中手动键入一个环境变量,该变量执行以下操作:

$ MY_DIR=/tmp echo hello
hello
$
…与sans envvar prefix类似,
$FOO
有效地具有与在shell中键入
echo
相同的效果


/tmp/
当然存在,顺便说一句:

$ ls -ld /tmp/
drwxrwxrwt. 25 root root 500 May 19 11:35 /tmp/
$

更新:


我有一个约束,即“
FOO
”必须像
$FOO hello
那样调用,而不是
FOO hello
。所以不幸的是,像@John Kugelman(当前)答案中的函数不可能是解决方案,即使它更合适。

最好将数据放入变量,将代码放入函数。函数比包含代码的变量更自然、更具表现力和灵活性。它们看起来与任何其他命令一样,但可以执行任意操作,包括但不限于预编命令和变量赋值

foo() {
    MY_DIR=/tmp echo "$@"
}
这里,
“$@”
是传递给
foo()
的参数的占位符

我有一个约束,即“
FOO
”必须像
$FOO hello
那样调用,而不是
FOO hello

恐怕这种限制是不可能的

我对这里发生的事情的机制很好奇:例如,为什么你能让一个环境变量有点“别名”到一个命令(我知道真正的别名是另一回事),但是这个机制不能适应对命令前缀“stuff”的看似很小的改变

Bash以固定的、规定的顺序在多个过程中扩展命令。它很早就将命令拆分为单词,然后用不可见的标志标记变量赋值。它在以后的过程中展开
$variable
引用。它不会查看结果,看它们是否像附加的变量扩展。等号实际上被忽略了

如果你想知道细节,打开网页。这是难以置信的长,细节分散在整个。让我拿出关键部分和一些精选语录来帮助您理解:

  • Shell语法,简单命令

    一个简单的命令是一系列可选变量赋值,后跟空白分隔的字和重定向,并由控制运算符终止

  • 简单命令扩展

    当执行一个简单的命令时,shell从左到右执行以下扩展、分配和重定向

  • 解析器标记为变量赋值(命令名之前的赋值)和重定向的单词将保存以供以后处理

  • 非变量赋值或重定向的单词将展开。如果展开后仍有任何单词,则第一个单词将作为命令名,其余单词将作为参数

  • 如果没有生成命令名,则变量指定会影响当前的shell环境。否则,变量将添加到已执行命令的环境中,并且不会影响当前shell环境

  • 扩展

    将命令行拆分为单词后,将在命令行上执行展开。执行的扩展有七种:大括号扩展、平铺扩展、参数和变量扩展、命令替换、算术扩展、分词和路径名扩展

    展开顺序为:大括号展开、平铺展开、参数展开、变量和算术展开以及命令替换(以从左到右的方式完成)、分词和路径名展开

  • 展开,参数展开

    $
    字符引入参数扩展、命令替换或算术扩展

  • 赋值在步骤1中标记,变量(AKA参数)在步骤4中展开

    变量展开后发生的唯一事情是:

  • 分词。如果变量包含空格,则它可以扩展为多个单词。(或者更准确地说,如果它包含字段间分隔符变量
    $IFS
    中的任何字符)

  • 路径名扩展。也称为通配符或通配符。如果变量包含
    *
    [
    它们将展开为匹配文件的名称(如果有)

  • 引号删除。此过程发生在变量展开之后,但它不适用于任何先前展开步骤的结果。因此,用户键入的引号将被删除,但替换结果的引号将保留


  • 您既不需要分词也不需要扩展路径名,因此无法将赋值存储在变量中。

    Re:“我有一个约束,即必须像调用
    $FOO hello
    那样调用“
    $FOO hello
    ”,而不是
    FOO hello
    ”:如果这确实是唯一的问题,那么不要担心,这个约束是微不足道的:您可以只编写
    FOO=FOO
    ,然后
    $FOO hello
    将扩展到
    FOO hello
    ,并调用您可能定义的任何
    FOO
    函数。设置必须是
    FOO
    的赋值吗,在调用
    FOO=“MY_DIR=/tmp echo”
    ?比如
    .bashrc
    文件或等效文件之前,您是否可以获得设置代码?@root?事实证明,我认为您的建议是可以的;如果这些是我应该提及的详细信息,那么很抱歉
    foo hello