以下shell函数定义在Cygwin的bash控制台(RHEL / Ubuntu)中挂起,它只是在调用它时退出终端。
$ function ls { ls; }
$ ls
出现这种行为的原因是什么?
答案 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; }