您正在询问两个非常不同的事物:别名和函数定义类似命令的行为;
export
将变量标记为要导出到子进程。让我先介绍类似命令的东西:
别名(
alias ll='ls -l'
)定义了一个命令的缩写。它们旨在供交互式使用(实际上在shell脚本中默认禁用),并且简单但不灵活。例如,您在别名之后指定的任何参数都会被添加到命令的末尾;如果您想要像这样的东西
alias findservice='grep "$1" /etc/services'
,则无法做到,因为
$1
在这里没有任何有用的作用。
函数类似于别名的更灵活、更强大的版本。函数可以接受和处理参数,包含循环、条件语句、here-documents等等...基本上,您可以在函数中执行shell脚本可以做的任何事情。请注意,定义函数的标准方法实际上不使用关键字
function
,只是在名称后面加括号。例如:
findservice() { grep "$1" /etc/services; }
现在让我们谈谈shell变量。在我讲解
export
之前,我需要谈论未导出变量。基本上,您可以定义一个变量,使其具有某些(文本)值,然后如果您按
$variablename
引用该变量,则它将被替换为命令。这与别名或函数有两个不同之处:别名或函数只能出现在命令的第一个单词中(例如,
ll filename
将使用别名
ll
,但
echo ll
不会),必须使用
$
显式调用变量(
echo $foo
将使用变量foo,但
echo foo
不会)。更根本地说,别名和函数旨在包含可执行代码(命令、shell语法等),而变量旨在存储非可执行数据。
顺便提一下,你几乎总是应该将变量引用放在双引号内 - 也就是说,使用 echo "$foo"
而不是只有 echo $foo
。如果没有双引号,变量的内容会以一种有点奇怪的方式解析,容易导致错误。
还有一些“特殊”shell变量,它们由shell自动设置(例如$HOME
),或者影响shell的行为(例如$PATH
控制shell在哪里查找可执行命令),或两者都有。
一个被导出的变量在当前shell中和任何子进程(子shell、其他命令等)中都可用。例如,如果我输入LC_ALL=en_US.UTF-8
,那么我的当前shell就会使用“en_US.UTF-8”语言环境设置。另一方面,如果我输入export LC_ALL=en_US.UTF-8
,那么当前shell和它执行的所有子进程和命令都将使用这个语言环境设置。
请注意,可以将shell变量标记为导出,而不必定义它,并且一旦导出,它就会一直保持导出状态。例如,$PATH
(据我所知)总是被导出的,因此PATH=/foo:/bar
的效果和export PATH=/foo:/bar
相同(尽管后者可能更好,以防万一$PATH某些情况下没有被导出)。
还可以通过将赋值作为命令的前缀来将变量导出到特定命令中,而不需要在当前shell中定义它。例如,LC_ALL=en_US.UTF-8 sort filename
会告诉sort
命令使用“en_US.UTF-8”语言环境设置,但不应用于当前shell(或任何其他命令)。
#define
,而函数则像是函数本身。 - devnullmy_alias() { my_command "$@"; }
来模拟导出别名。 - André Willik Valenti