【问题标题】:A bash function definition that doesn't seem to work似乎不起作用的 bash 函数定义
【发布时间】:2023-04-09 22:26:01
【问题描述】:

前几天我在试验 shell 函数,目的是覆盖 ls 命令。 目的是让外壳程序首先调用我的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 是一个内置的示例,但是:

$ which ls
/bin/ls

和:

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

所以它似乎不在我的系统上(即使它是我实际上也看不出它为什么会这样)。

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

谢谢。

【问题讨论】:

  • 阅读答案后,我决定添加此评论:“Doh!”
  • 您的意思是您没有立即回忆起您键入的命令不是执行命令的六种方式?新手! ;)
  • “当你这样称呼我时微笑。”:)
  • 我认为发生的事情是我专注于“内置”事物而排除任何其他解释,即使它实际上无法解释任何事情。 “当问题不在你所寻找的地方时,它就在其他地方!”重复 100 次。

标签: bash ls


【解决方案1】:

不要使用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

【讨论】:

  • @msw type 很好。我会说它是针对 Bash 的首选。不幸的是,POSIX 几乎没有说明它实际上应该做什么,因此选项和确切的输出变化很大。
  • 感谢 ormaaj。 (我的“真实”版本检查了递归:这只是简化为最简单的情况)。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    我猜

    $ alias ls
    

    会告诉你原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-20
      • 2018-08-11
      • 2015-06-29
      • 1970-01-01
      • 2022-12-03
      • 2010-11-03
      • 2013-06-19
      • 1970-01-01
      相关资源
      最近更新 更多