以下shell函数定义在Cygwin的bash控制台(RHEL/Ubuntu)中挂起,它只是在调用时退出终端。
$ function ls { ls; }
$ ls
这种行为有什么原因吗?
您定义的ls
命令以递归方式调用自身,而不是以前的ls
命令。
如果要从重新定义的路径调用实际的ls
,只需使用which
即可获取完整路径名,例如重新定义ls
以提供长格式:
function ls { $(which ls) -l; }
这实际上与以下项相同:
function ls { /bin/ls -l; }
这不会给你的解决方案带来的递归问题。
另一种选择是使用
function ls { command ls -l; }
command
将禁止 shell 函数查找,并且只允许路径上的内置或程序。
内置(如cd
)的处理方式与程序略有不同,因为它们实际上并不位于文件系统上。在这种情况下,您可以使用builtin
而不是which
来调用内置版本。
如果你想根据可能已经是一个函数的东西来定义一个函数,那就有点棘手了。可以使用declare -f
获取当前定义,然后对其进行操作以创建新定义。
下面是一个例子(虽然是人为的)。假设您声明了一个函数来显示所有文本文件:
pax> showtxt()
...> {
...> ls *.txt
...> }
你现在想给它一个漂亮的标题。使用declare -f showtxt
,您可以看到它的定义:
pax> declare -f showtxt
showtxt ()
{
ls *.txt
}
运行可能会导致以下输出:
pax> showtxt
passwords.txt p0rnsites.txt results.txt
现在假设您想更改它以给它一个标题。您可以捕获declare -f
的输出并对其进行修改以创建一个脚本,该脚本将重新定义函数:
pax> declare -f showtxt | awk '$1=="ls"{print "echo Text files:"}{print}' >tmp.sh
pax> cat tmp.sh
showtxt ()
{
echo Text files:
ls *.txt
}
您可以看到您现在有一个修改后的函数定义,该定义在运行时将替换该函数:
pax> . ./tmp.sh
pax> declare -f showtxt
showtxt ()
{
echo Text files:;
ls *.txt
}
而且,当您运行新功能时,它的行为已更改:
pax> showtxt
Text files:
passwords.txt p0rnsites.txt results.txt
现在这个人为的例子不是那么有用,因为你可能已经输入了自己。当原始功能更复杂或您想要对其进行的更改多种多样时,这会派上用场。
您将函数命名为ls
。现在,这将覆盖之前命名ls
的任何其他函数。因此,您的函数会无限递归地调用自己......
最好的主意是为函数使用唯一的名称,即,这工作正常:
function myls { ls; }