别名和导出(和函数!)[BASH] 之间有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23172982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between alias and export (and a function!)[BASH]?
提问by Alex Gray
I'm surprised hasn't been asked before, but…
我很惊讶以前没有被问过,但是......
What is the difference between
之间有什么区别
alias? alias EXPORT='alias'
别名?alias EXPORT='alias'
function? function exporter() { echo $EXPORT }
功能?function exporter() { echo $EXPORT }
and
和
export? export ALIAS='export'
出口? export ALIAS='export'
and for that matter...
就此而言……
alias export=$(function)
(j/k)
alias export=$(function)
(j/k)
in bash
(zsh
, et al.)
在bash
( zsh
, et al.)
Specifically, I'd be most interested in knowing the lexical/practical difference between
具体来说,我最感兴趣的是了解两者之间的词汇/实际差异
alias this=that
and
和
export that=this
I have both forms... all over the place- and would prefer to stop arbitrarily choosing one, over the other.
我有两种形式……到处都是——并且宁愿停止随意选择一种,而不是另一种。
I'm sure there is a great reference to a "scopes and use-cases for unix shells", somewhere... but thought I'd post the question here, in the name of righteous-canonicalicism.
我确信在某处有一个很好的参考“unix shell 的范围和用例”……但我想我会以righteous-canonicicism的名义在这里发布这个问题。
回答by Gordon Davisson
You're asking about two very different categories of things: aliases and functions define things that act like commands; export
marks a variable to be exported to child processes. Let me go through the command-like things first:
你问的是两种截然不同的事物:别名和函数定义了像命令一样的事物;export
标记要导出到子进程的变量。让我先看一下类似命令的事情:
An alias (alias ll='ls -l'
) defines a shorthand for a command. They're intended for interactive use (they're actually disabled by default in shell scripts), and are simple but inflexible. For example, any arguments you specify after the alias simply get tacked onto the end of the command; if you wanted something like alias findservice='grep "$1" /etc/services'
, you can't do it, because $1
doesn't do anything useful here.
别名 ( alias ll='ls -l'
) 定义命令的简写。它们旨在用于交互式使用(它们实际上在 shell 脚本中默认被禁用),并且简单但不灵活。例如,您在别名之后指定的任何参数都会简单地添加到命令的末尾;如果你想要类似的东西alias findservice='grep "$1" /etc/services'
,你不能这样做,因为$1
在这里没有做任何有用的事情。
A function is like a more flexible, more powerful version of an alias. Functions can take & process arguments, contain loops, conditionals, here-documents, etc... Basically, anything you could do with a shell script can be done in a function. Note that the standard way to define a function doesn't actually use the keyword function
, just parentheses after the name. For example: findservice() { grep "$1" /etc/services; }
函数就像别名的更灵活、更强大的版本。函数可以接受和处理参数,包含循环、条件、here-documents 等......基本上,你可以用 shell 脚本做的任何事情都可以在函数中完成。请注意,定义函数的标准方法实际上并不使用关键字function
,只是名称后面的括号。例如:findservice() { grep "$1" /etc/services; }
Ok, now on to shell variables. Before I get to export
, I need to talk about unexported variables. Basically, you can define a variable to have some (text) value, and then if you refer to the variable by $variablename
it'll be substituted into the command. This differs from an alias or function in two ways: an alias or function can only occur as the first word in the command (e.g. ll filename
will use the alias ll
, but echo ll
will not), and variables must be explicitly invoked with $
(echo $foo
will use the variable foo, but echo foo
will not). More fundamentally, aliases and functions are intended to contain executable code (commands, shell syntax, etc), while variables are intended to store non-executable data.
好的,现在到 shell 变量。在我开始之前export
,我需要谈谈未导出的变量。基本上,您可以定义一个变量以具有一些(文本)值,然后如果您通过$variablename
它引用该变量,它将被替换到命令中。这在两个方面与别名或函数不同:别名或函数只能作为命令中的第一个词出现(例如ll filename
将使用别名ll
,但echo ll
不会),并且必须显式调用变量$
(echo $foo
将使用变量 foo ,但echo foo
不会)。更根本的是,别名和函数旨在包含可执行代码(命令、shell 语法等),而变量旨在存储不可执行的数据。
(BTW, you should almost always put variable references inside double-quotes -- that is, use echo "$foo"
instead of just echo $foo
. Without double-quotes the variable's contents get parsed in a somewhat weird way that tends to cause bugs.)
(顺便说一句,你应该几乎总是将变量引用放在双引号内——也就是说,使用echo "$foo"
而不是仅仅使用echo $foo
。没有双引号,变量的内容会以一种有点奇怪的方式解析,这往往会导致错误。)
There are also some "special" shell variables, that are automatically set by the shell (e.g. $HOME
), or influence how the shell behaves (e.g. $PATH
controls where it looks for executable commands), or both.
还有一些“特殊”的 shell 变量,它们由 shell 自动设置(例如$HOME
),或者影响 shell 的行为方式(例如$PATH
控制它在哪里查找可执行命令),或者两者兼而有之。
An export
ed variable is available both in the current shell, and also passed to any subprocesses (subshells, other commands, whatever). For example, if I do LC_ALL=en_US.UTF-8
, that tells my current shell use the "en_US.UTF-8" locale settings. On the other hand, if I did export LC_ALL=en_US.UTF-8
that would tell the current shell and all subprocesses and commands it executesto use that locale setting.
的export
ED变量是可用的既在当前外壳,并且还传递到任何的子过程(子shell,其他命令,等等)。例如,如果我这样做了LC_ALL=en_US.UTF-8
,这会告诉我当前的 shell 使用“en_US.UTF-8”语言环境设置。另一方面,如果我这样做export LC_ALL=en_US.UTF-8
会告诉当前的 shell和它执行的所有子进程和命令使用该语言环境设置。
Note that a shell variable can be marked as exported separately from defining it, and once exported it stays exported. For example, $PATH
is (as far as I know) alwaysexported, so PATH=/foo:/bar
has the same effect as export PATH=/foo:/bar
(although the latter may be preferred just in case $PATH somehow wasn't already exported).
请注意,shell 变量可以与定义它分开标记为导出,并且一旦导出,它就保持导出状态。例如,$PATH
is (据我所知)总是导出,所以PATH=/foo:/bar
具有相同的效果export PATH=/foo:/bar
(尽管后者可能是首选,以防万一 $PATH 不知何故尚未导出)。
It's also possible to export a variable to a particular command withoutdefining it in the current shell, by using the assignment as a prefix for the command. For example LC_ALL=en_US.UTF-8 sort filename
will tell the sort
command to use the "en_US.UTF-8" locale settings, but not apply that to the current shell (or any other commands).
通过使用赋值作为命令的前缀,还可以将变量导出到特定命令而不在当前 shell 中定义它。例如,LC_ALL=en_US.UTF-8 sort filename
将告诉sort
命令使用“en_US.UTF-8”语言环境设置,但不将其应用于当前 shell(或任何其他命令)。