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

Bash 为什么函数ls{ls;}挂在那里?,bash,shell,Bash,Shell,下面的shell函数定义挂在Cygwin中的bash控制台(RHEL/Ubuntu)中,它只是在调用时退出终端 $ function ls { ls; } $ ls 这种行为的原因是什么?您将函数命名为ls。现在,这将覆盖以前命名为ls的任何其他函数。因此,结果是,函数无限递归地调用自己 最好的办法是为函数使用唯一的名称,也就是说,这很好: function myls { ls; } 您定义的ls命令正在递归调用自身,而不是先前的ls命令 如果要从重新定义的路径调用实际的ls,只需使用whi

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

$ function ls { ls; }
$ ls

这种行为的原因是什么?

您将函数命名为
ls
。现在,这将覆盖以前命名为
ls
的任何其他函数。因此,结果是,函数无限递归地调用自己

最好的办法是为函数使用唯一的名称,也就是说,这很好:

function myls { ls; }

您定义的
ls
命令正在递归调用自身,而不是先前的
ls
命令

如果要从重新定义的路径调用实际的
ls
,只需使用
which
获取完整的路径名,例如重新定义
ls
以获得长格式:

function ls { $(which ls) -l; }
这实际上与:

function ls { /bin/ls -l; }
这不会给你解决方案在递归方面的问题

另一个选择是使用

function ls { command ls -l; }
命令
将禁止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
的函数,shell将不会搜索路径并找到
/bin/ls
。您(出于某种原因)想要
函数ls{/bin/ls;}
?为什么?是的,我打算在我的函数中调用/bin/ls。因此,我推断shell函数重写或优先于内置函数。
它不是(至少在bash中)内置命令,而且运行起来可能有点昂贵(可能不是很明显)。您可以使用内置的
命令
绕过任何shell函数:
函数ls{command ls-l;}
不知道这个,Keith。为完整性增加了答案。Ta.很好的解释,但无法理解您的上一句话,即,“
如果您想用可能已经是函数的东西定义函数,这有点麻烦。您可以使用declare-f获取当前定义,然后处理该定义以创建新定义
”你能提供一个例子来清楚地说明这一点吗?@Ibrahim,我(希望)补充了一些额外的东西。通常,您只需要在复杂的情况下使用它,但底线是,
declare
可以以您可以修改的形式为您提供函数,以更改所述函数。谢谢您的启发!!