Sto*_*row 2 bash environment-variables
我似乎能够创建执行命令的环境变量;像这样:
$ cat ./src
FOO="echo"
$ . ./src
$ echo $FOO
echo
$ $FOO hello
hello
$
Run Code Online (Sandbox Code Playgroud)
有没有办法可以修改该环境变量,以便它在命令之前为另一个环境变量的设置添加前缀?即有没有办法解决以下问题?
$ 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
$
Run Code Online (Sandbox Code Playgroud)
即我想要发生的是有一个环境变量,它相当于在 shell 中手动输入的以下内容:
$ MY_DIR=/tmp echo hello
hello
$
Run Code Online (Sandbox Code Playgroud)
...类似于 sans envvar-prefix,$FOO实际上与echo在 shell 中键入的效果相同。
/tmp/ 当然存在,顺便说一句:
$ ls -ld /tmp/
drwxrwxrwt. 25 root root 500 May 19 11:35 /tmp/
$
Run Code Online (Sandbox Code Playgroud)
更新:
我有一个约束,即“ FOO”必须像$FOO hello而不是一样被调用FOO hello。所以不幸的是,像@John Kugelman 的(当前)答案中的函数不能成为解决方案,即使它更合适。
最好将数据放入变量中,将代码放入函数中。函数比保存代码的变量更自然、更具表现力和灵活性。它们看起来就像任何其他命令,但可以执行任意操作,包括但不限于预先添加命令和变量赋值。
foo() {
MY_DIR=/tmp echo "$@"
}
Run Code Online (Sandbox Code Playgroud)
foo hello
Run Code Online (Sandbox Code Playgroud)
这"$@"是传递给 的参数的占位符foo()。
我有一个约束,即“
FOO”必须像$FOO hello而不是一样被调用FOO hello。
恐怕这种限制是不可能的。
我对这里发生的事情的机制很好奇:即为什么你可以创建一个与命令“别名”的环境变量(我知道真正的别名是别的东西),但这种机制并不能适应看似很小的变化为命令添加前缀“东西”?
Bash 以固定的、规定的顺序分几次扩展命令。很早就将命令拆分为单词,然后用不可见的标志标记变量赋值。它$variable在以后的过程中扩展引用。它不会查看结果以查看它们是否看起来像额外的变量扩展。等号实际上被忽略了。
如果您想了解具体细节,请打开Bash 手册页。它非常长,细节分散在各处。让我拉出关键部分和一些精选引文来帮助您消化它:
Shell 语法,简单命令
一个简单的命令是一系列可选的变量赋值,后跟以空格分隔的单词和重定向,并以控制运算符结束。
简单的命令扩展
执行简单命令时,shell 从左到右执行以下扩展、赋值和重定向。
解析器标记为变量赋值(命令名称之前的那些)和重定向的单词将被保存以供以后处理。
不是变量赋值或重定向的词被扩展。如果扩展后还有任何单词,则将第一个单词作为命令的名称,其余单词作为参数。
...
如果没有命令名称结果,变量赋值会影响当前的 shell 环境。否则,变量被添加到执行命令的环境中,不会影响当前的shell环境。
扩张
拆分成单词后在命令行上进行扩展。执行了七种扩展:花括号扩展、波浪号扩展、参数和变量扩展、命令替换、算术扩展、分词和路径名扩展。
扩展的顺序是:大括号扩展、波浪号扩展、参数、变量和算术扩展和命令替换(以从左到右的方式完成)、分词和路径名扩展。
扩展、参数扩展
该
$字符引入了参数扩展、命令替换或算术扩展。
分配在步骤 1 中标记,变量(AKA 参数)在步骤 4 中展开。
变量扩展后唯一发生的事情是:
分词。如果变量包含空格,则它可以扩展为多个单词。(或者更准确地说,如果它包含字段间分隔符变量中的任何字符$IFS。)
路径名扩展。也称为通配符或通配符。如果变量包含*, ?, 或者[它们将扩展为匹配文件的名称(如果有)。
报价删除。变扩建后该通票情况,但要注意,它不适用于任何先前的扩张步骤的结果。所以用户输入的引号被删除,但作为替换结果的引号被保留。
分词和路径名扩展都不是您所需要的,所以这就是不能将赋值存储在变量中的原因。
| 归档时间: |
|
| 查看次数: |
332 次 |
| 最近记录: |