前几天我正在试验shell函数,目的是覆盖ls命令.目的是让shell ls首先调用我的函数然后如果第一个开关是"-y"做一件事,否则调用常规函数/bin/ls,但结果表现为我不理解的方式.
为了启用它,我决定使用"-y"作为开关,因为:
$ ls -y
ls: invalid option -- 'y'
Try `ls --help' for more information.
Run Code Online (Sandbox Code Playgroud)
所以它无法打破核心功能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 ; }
Run Code Online (Sandbox Code Playgroud)
所以我压倒一切ls,less并定义try哪个像"控制"标本:)
现在调用这种方式:
$ ls ; less ; try
Run Code Online (Sandbox Code Playgroud)
它的行为符合预期(无输出),但是:
$ ls -y ; less -y ; try -y
LESS
TRY
Run Code Online (Sandbox Code Playgroud)
将ls无法工作,但less覆盖不一样,"控制".
在stackoverflow或askubuntu的其他地方(但我已经失去了一分钟的参考)我看到一个暗示的例子ls是一个builltin,但是:
$ which ls
/bin/ls
Run Code Online (Sandbox Code Playgroud)
和:
$ builtin ls
bash: builtin: ls: not a shell builtin
Run Code Online (Sandbox Code Playgroud)
所以它似乎不在我的系统上(即使它实际上我也无法理解为什么它会像这样).
我想知道解释是什么?这并不重要,但我想了解发生了什么.
谢谢.
不要使用which,使用type.如果你有类似的东西
$ type ls
ls is aliased to `ls --color=auto'
Run Code Online (Sandbox Code Playgroud)
然后您的函数将在交互式shell中失败.在您.bashrc或其定义的任何地方删除它.你也可以使用unalias内置.
如果运行与函数中的函数同名的命令,则还需要避免递归.
ls()
if [[ $1 == -y ]]; then
shift
...
else
command ls "$@"
fi
Run Code Online (Sandbox Code Playgroud)
另外,如果您决定使用function关键字定义函数,请确保您知道自己在做什么.funcname() compound-command在撰写本文时,如果需要POSIX兼容性,请使用POSIX样式.
为 设置别名是很常见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
Run Code Online (Sandbox Code Playgroud)
下面显示了此行为的示例:
$ 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
Run Code Online (Sandbox Code Playgroud)