为什么函数 ls { ls; } 挂在那里?



以下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; }

相关内容

  • 没有找到相关文章

最新更新