如何创建bash环境变量,在命令前添加环境变量前缀? [英] How can I create a bash environment variable that prefixes an environment variable before a command?

查看:114
本文介绍了如何创建bash环境变量,在命令前添加环境变量前缀?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I seem to be able to create environment variables that execute commands; like this:

$ cat ./src
FOO="echo"
$ . ./src
$ echo $FOO
echo
$ $FOO hello
hello
$

有没有一种方法可以修改该环境变量,使其在命令之前在另一个环境变量的设置之前加上前缀?有没有办法解决以下问题?

Is there a way I can modify that environment variable so that it prefixes the setting of another environment variable before the command? I.e. is there a way to work around the following problem?

$ 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中手动键入以下命令等效:

I.e. what I'd like to happen is to have an environment variable that does the equivalent of the following manually typed in the shell:

$ MY_DIR=/tmp echo hello
hello
$

...类似于没有envvar前缀的方式, $ FOO 与在外壳上键入 echo 的效果相同.

...similar to how sans envvar-prefix, $FOO effectively had the same effect as typing echo at the shell.

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

/tmp/ exists of course, btw:

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


更新:

我有一个约束,必须像 $ FOO hello 那样调用" FOO ",而不要像 FOO hello 那样调用.因此,不幸的是,像@John Kugelman的(当前)答案中那样的函数不能解决,即使它更合适.

I have a constraint that "FOO" must be invoked like $FOO hello and not FOO hello. So unfortunately a function like in @John Kugelman's (current) answer can't be a solution, even if it's more proper.

推荐答案

最好将数据放入变量中,将代码放入函数中.与保存代码的变量相比,函数更自然,更具表现力,更灵活.它们看起来与其他任何命令一样,但是可以采取任意操作,包括但不限于前置命令和变量分配.

It's best to put data into variables, code into functions. Functions are more natural, expressive, and flexible than variables holding code. They look just like any other command but can take arbitrary actions, including but not limited to prepending commands and variable assignments.

foo() {
    MY_DIR=/tmp echo "$@"
}

foo hello

此处"$ @" 是传递给 foo()的参数的占位符.

Here "$@" is a placeholder for the arguments passed to foo().

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

I have a constraint that "FOO" must be invoked like $FOO hello and not FOO hello.

恐怕这种约束是不可能的.

That constraint is impossible, I'm afraid.

我很好奇这里发生的事情的机制:例如,为什么您可以创建一个环境变量,该变量对命令是别名"的(我知道真正的别名是别的东西),但是这种机制不能适应在命令前添加"stuff"前缀看似很小的更改?

I am curious about the mechanics of what's going on here: i.e. why can you make an environment variable that's sort of "aliased" to a command (I know true aliasing is something else), but that mechanism doesn't accommodate the seemingly small change to prefix "stuff" to the command?

Bash会以固定的规定顺序分几步扩展命令.在很早的时候,它将命令分解为单词,然后用不可见的标志标记变量分配.它将在以后的过程中扩展 $ variable 引用.它不会查看结果,以查看它们是否看起来像其他变量扩展.等号有效地被忽略了.

Bash expands commands in several passes in a fixed, prescribed order. Very early on it splits the command into words and then marks the variable assignments with invisible flags. It expands $variable references in a later pass. It doesn't look at the results to see if they look like additional variable expansions. The equal signs are effectively ignored.

如果您想了解具体细节,请打开 Bash手册页.它长得令人难以置信,而且细节分散在各处.让我拉出关键部分和一些引号来帮助您进行消化:

If you want to know the nitty gritty details, open up the Bash man page. It's incredibly long and the details are scattered throughout. Let me pull out the key sections and some choice quotes to help you digest it:

  1. Shell语法,简单命令

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

A simple command is a sequence of optional variable assignments followed by blank-separated words and redirections, and terminated by a control operator.

简单命令扩展

执行简单命令时,shell从左到右执行以下扩展,分配和重定向.

When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right.

  1. 解析器标记为变量分配(在命令名称之前的变量)和重定向的单词将被保存以供以后处理.

  1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

不是变量分配或重定向的单词将被扩展.如果扩展后还剩下任何单词,则将第一个单词作为命令的名称,其余的单词作为自变量.

The words that are not variable assignments or redirections are expanded. If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.

...

如果未生成命令名称,则变量分配会影响当前的Shell环境.否则,变量将添加到已执行命令的环境中,并且不会影响当前的shell环境.

If no command name results, the variable assignments affect the current shell environment. Otherwise, the variables are added to the environment of the executed command and do not affect the current shell environment.

扩展

在将其拆分为单词后,在命令行上执行扩展.执行了七种扩展:括号扩展波浪号扩展参数和变量扩展命令替换算术扩展分词路径名扩展.

Expansion is performed on the command line after it has been split into words. There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion.

扩展顺序为:大括号扩展,代字号扩展,参数,变量和算术扩展以及命令替换(以从左到右的方式完成),单词拆分和路径名扩展.

The order of expansions is: brace expansion, tilde expansion, parameter, variable and arithmetic expansion and command substitution (done in a left-to-right fashion), word splitting, and pathname expansion.

扩展,参数扩展

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

The $ character introduces parameter expansion, command substitution, or arithmetic expansion.

在步骤1中标记分配,并在步骤4中扩展变量(AKA参数).

Assignments are marked in step 1 and variables (AKA parameters) are expanded in step 4.

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

The only things that happen after variable expansion are:

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

  1. Word splitting. A variable can expand to multiple words if it contains whitespace. (Or to be more precise, if it contains any of the characters in the inter-field separator variable $IFS.)

路径扩展.也称为通配符或通配符.如果变量包含 * ? [](如果有),它们将被扩展为匹配文件的名称.

Pathname expansion. Also known as globbing, or wildcards. If a variable contains *, ?, or [ they'll be expanded to the names of matching files, if there are any.

报价删除.此遍历发生在变量扩展之后,但是 not 不适用于任何先前扩展步骤的结果.因此,删除了用户键入的引号,但保留了替换结果引号.

Quote removal. This pass happens after variable expansion, but it specifically does not apply to the results of any previous expansion step. So quotes the user typed are removed, but quotes that were the results of a substitution are retained.

分词和路径名扩展都不是您所需要的,因此这就是为什么无法将赋值存储在变量中的原因.

Neither word splitting nor pathname expansion are what you need, so that's why it's not possible to store an assignment in a variable.

这篇关于如何创建bash环境变量,在命令前添加环境变量前缀?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆