一个似乎不起作用的bash函数定义

时间:2012-06-30 06:49:03

标签: bash ls

前几天我正在尝试使用shell函数,目的是覆盖ls命令。 目的是让shell首先调用我的ls函数然后如果第一个开关是“-y”做一件事,否则调用常规/bin/ls,但结果表现的方式我不会理解。

为了启用它,我决定使用“-y”作为开关,因为:

$ ls -y
ls: invalid option -- 'y'
Try `ls --help' for more information.

因此它无法打破ls的核心功能。 无论如何,将问题简化为最简单的问题,并通过其他几个例子来帮助突出问题:

$ function ls() { [[ "y$1" == "y-y" ]] && echo LS ; } 
$ function less() { [[ "y$1" == "y-y" ]] && echo LESS ; }
$ function try() { [[ "y$1" == "y-y" ]] && echo TRY ; }

所以我压倒lsless并定义try,就像“控制”样本一样:)

现在以这种方式调用:

$ ls ; less ; try 

它的行为符合预期(无输出),但是:

$ ls -y ; less -y ; try -y
LESS
TRY

ls无效,但less覆盖与“控件”一样。

在stackoverflow或askubuntu的其他地方(但我已经失去了一分钟的参考)我看到一个暗示ls是一个builltin的例子,但是:

$ which ls
/bin/ls

$ builtin ls
bash: builtin: ls: not a shell builtin

所以它似乎不在我的系统上(即使它实际上我也无法理解为什么它会像这样)。

我想知道解释是什么?这并不重要,但我想了解发生了什么。

感谢。

3 个答案:

答案 0 :(得分:6)

请勿使用which,请使用type。如果您有类似

的内容
$ type ls
ls is aliased to `ls --color=auto'

然后您的函数将在交互式shell中失败。在.bashrc或其定义的任何位置删除此项。您也可以使用内置的unalias

如果在函数中运行与函数同名的命令,则还需要避免递归。

ls()
    if [[ $1 == -y ]]; then
        shift
        ...
    else
        command ls "$@"
    fi

另外,如果您决定使用function关键字定义函数,请确保知道自己在做什么。在撰写本文时,如果需要POSIX兼容性,请使用POSIX风格的funcname() compound-command

答案 1 :(得分:4)

ls设置别名很常见,您可能就是这种情况。首先处理别名,这是文本的简单替换。你的例子中发生了什么:

A) `ls` is replaced with `ls --color=auto` 
B) Your `ls` function is called with the replaced text and your -y option 
C) Your function checks "$1", which is --color=auto

下面显示了此行为的示例:

$ function ls() { [[ "y$1" == "y-y" ]] && echo LS ; }
$ ls -y
$ type ls
ls is aliased to `ls --color=auto'
$ unalias ls
$ type ls
ls is a function
ls ()
{
    [[ "y$1" == "y-y" ]] && echo LS
}
$ function ls() { [[ "y$1" == "y-y" ]] && echo LS ; }
$ ls -y
LS
$ alias ls="ls --color=auto"
$ ls -y
--color=auto -y

答案 2 :(得分:1)

我猜那个

$ alias ls

会告诉你原因。