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

时间:2014-02-05 06:08:42

标签: bash shell

以下shell函数定义在Cygwin的bash控制台(RHEL / Ubuntu)中挂起,它只是在调用它时退出终端。

$ function ls { ls; }
$ ls

出现这种行为的原因是什么?

2 个答案:

答案 0 :(得分:4)

您定义的ls命令以递归方式调用本身而不是之前的 ls命令。

如果您想从重新定义的版本中调用实际ls,只需使用which获取完整路径名称,例如重新定义ls即可获得长格式:

function ls { $(which ls) -l; }

这实际上与:

相同
function ls { /bin/ls -l; }

它不会解决您的解决方案在递归时遇到的问题。

另一种选择是使用

function ls { command ls -l; }

command将禁止shell函数查找,并且只允许路径上的内置函数或程序。


Builtins(如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

现在那个人为的例子并不是 这方面派上用场的原因是原始功能更复杂,或者您希望对其进行的更改是多种多样的。

答案 1 :(得分:1)

您将自己的职能命名为ls。现在,这将覆盖之前命名为ls的任何其他函数。所以,结果,你的函数无限地递归调用自己......

最好的想法是为您的函数使用唯一的名称,即,这样可以正常工作:

function myls { ls; }