fly*_*ire 883 linux bash shell
什么是export?
有什么区别:
export name=value
Run Code Online (Sandbox Code Playgroud)
和
name=value
Run Code Online (Sandbox Code Playgroud)
Bri*_*new 972
export 使变量可用于子流程.
那是,
export name=value
Run Code Online (Sandbox Code Playgroud)
表示变量名称可用于从该shell进程运行的任何进程.如果您希望进程使用此变量,请使用export该shell并从该shell运行该进程.
name=value
Run Code Online (Sandbox Code Playgroud)
表示变量作用域仅限于shell,并且不可用于任何其他进程.您可以将此用于(例如)循环变量,临时变量等.
重要的是要注意,导出变量不会使父进程可用.也就是说,在生成的进程中指定和导出变量不会使其在启动它的过程中可用.
alx*_*lxp 238
为了说明其他答案所说的内容:
$ foo="Hello, World"
$ echo $foo
Hello, World
$ bar="Goodbye"
$ export foo
$ bash
bash-3.2$ echo $foo
Hello, World
bash-3.2$ echo $bar
bash-3.2$
Run Code Online (Sandbox Code Playgroud)
Wil*_*ell 70
其他人已经回答说,导出使变量可用于子壳,这是正确的,但仅仅是副作用.导出变量时,它会将该变量放在当前shell的环境中(即shell调用putenv(3)或setenv(3)).进程的环境在exec中继承,使变量在子shell中可见.
编辑(5年的观点):这是一个愚蠢的答案."导出"的目的是使变量"处于随后执行的命令的环境中",无论这些命令是子单元还是子进程.一个简单的实现是简单地将变量放在shell的环境中,但这将使其无法实现export -p.
小智 59
有人说,在产生子壳时没有必要以bash出口,而其他人则说完全相反.需要注意的子shell之间的区别是很重要的(那些被创建(),``,$()或回路)和子(即通过名称调用,如流程文字bash出现在你的脚本).
这两个结构中常见的是,两者都不能将变量传递回父shell.
$ noexport=noexport; export export=export; (echo subshell: $noexport $export; subshell=subshell); bash -c 'echo subprocess: $noexport $export; subprocess=subprocess'; echo parent: $subshell $subprocess
subshell: noexport export
subprocess: export
parent:
Run Code Online (Sandbox Code Playgroud)
还有一个混淆源:有些人认为'分叉'子进程是那些看不到非导出变量的子进程.通常fork()后跟exec()s,这就是为什么看起来fork()是要查找的东西,而实际上它是exec().您可以先使用exec命令运行没有fork()的命令,此方法启动的进程也无法访问未导出的变量:
$ noexport=noexport; export export=export; exec bash -c 'echo execd process: $noexport $export; execd=execd'; echo parent: $execd
execd process: export
Run Code Online (Sandbox Code Playgroud)
请注意,这次我们没有看到这一parent:行,因为我们已经用exec命令替换了父shell ,因此没有什么可以执行该命令.
Cha*_*iam 30
export NAME=value 对于对子流程有意义的设置和变量.
NAME=value 对于当前shell进程专用的临时或循环变量.
更详细地,export标记环境中的变量名称,该名称在创建时复制到子进程及其子进程.从子进程中没有复制任何名称或值.
常见的错误是在等号周围放置一个空格:
$ export FOO = "bar"
bash: export: `=': not a valid identifier
Run Code Online (Sandbox Code Playgroud)B子进程只能看到导出的变量():
$ A="Alice"; export B="Bob"; echo "echo A is \$A. B is \$B" | bash
A is . B is Bob
Run Code Online (Sandbox Code Playgroud)子进程中的更改不会更改主shell:
$ export B="Bob"; echo 'B="Banana"' | bash; echo $B
Bob
Run Code Online (Sandbox Code Playgroud)标记为导出的变量具有在创建子流程时复制的值:
$ export B="Bob"; echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash &
[1] 3306
$ B="Banana"; echo '(sleep 30; echo "Subprocess 2 has B=$B")' | bash
Subprocess 1 has B=Bob
Subprocess 2 has B=Banana
[1]+ Done echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash
Run Code Online (Sandbox Code Playgroud)只有导出的变量才会成为环境的一部分(man environ):
$ ALICE="Alice"; export BOB="Bob"; env | grep "ALICE\|BOB"
BOB=Bob
Run Code Online (Sandbox Code Playgroud)那么,现在它应该像夏天的太阳一样清晰!感谢Brain Agnew,alexp和William Prusell.
Bri*_*son 11
应该注意的是,您可以导出变量,然后更改该值.变量的更改值将可用于子进程.为变量设置导出后,必须执行export -n <var>删除属性的操作.
$ K=1
$ export K
$ K=2
$ bash -c 'echo ${K-unset}'
2
$ export -n K
$ bash -c 'echo ${K-unset}'
unset
Run Code Online (Sandbox Code Playgroud)
您可能已经知道,UNIX允许进程拥有一组环境变量,这些变量是键/值对,键和值都是字符串.操作系统负责分别为每个进程保留这些对.
程序可以通过此UNIX API访问其环境变量:
char *getenv(const char *name);int setenv(const char *name, const char *value, int override);int unsetenv(const char *name);进程还从父进程继承环境变量.操作系统负责在创建子进程时创建所有"envars"的副本.
Bash和其他shell一样,能够根据用户请求设置其环境变量.这是export存在的.
export是一个Bash命令,用于为Bash设置环境变量.使用此命令设置的所有变量都将由此Bash将创建的所有进程继承.
更多关于Bash中的环境
Bash中的另一种变量是内部变量.由于Bash不仅仅是交互式shell,它实际上是一个脚本解释器,与任何其他解释器(例如Python)一样,它能够保留自己的变量集.应该提到的是,Bash(与Python不同)仅支持字符串变量.
定义Bash变量的表示法是name=value.这些变量保留在Bash中,与操作系统保留的环境变量无关.
有关Shell参数的更多信息(包括变量)
另外值得注意的是,根据Bash参考手册:
任何简单命令或函数的环境都可以通过在参数赋值前添加前缀来临时扩充,如Shell参数中所述.这些赋值语句仅影响该命令所见的环境.
总结一下:
export用于在操作系统中设置环境变量.此变量将可用于当前Bash进程创建的所有子进程.该接受的答案意味着这一点,但我想作出明确到shell内建的连接:
如前所述,export将使shell和子系统都可以使用变量.如果export在不使用时,变量将只提供在壳,只有壳内建可以访问它.
那是,
tango=3
env | grep tango # prints nothing, since env is a child process
set | grep tango # prints tango=3 - "type set" shows `set` is a shell builtin
Run Code Online (Sandbox Code Playgroud)
UNIX 的两位创建者 Brian Kernighan 和 Rob Pike 在他们的“UNIX 编程环境”一书中解释了这一点。谷歌搜索标题,你会很容易找到一个 pdf 版本。
它们在第 3.6 节中解决了 shell 变量,并在该export节末尾重点介绍了命令的使用:
当您想要在子 shell 中访问变量的值时,应该使用 shell 的 export 命令。(您可能会想为什么无法将变量的值从子外壳导出到其父外壳)。