如果我输入rm -i *
,我希望bash运行rm *
,否则运行常规rm
。重要的是,每次使用rm -i
等通配符时,我都不想运行rm part*
。这是我能想到的:
rm ()
{
if [ "$1" == "*" ]; then
rm -i *
else
rm $1
fi
}
但我知道这会失败。我知道我想要的比较是^*$
,但我不知道如何实现它。
答案 0 :(得分:7)
字面上不可能知道您的命令是否使用通配符调用而没有shell的合作。
当您调用rm *
时(与任何其他命令一样),*
将在调用之前替换为文件名列表。因此,当在命令内部时,给定通配符的信息不再存在:$1
,$2
等已被通配符扩展到的名称列表替换。
那就是说,既然我们是shell函数,我们shell的合作实际上是可用的:
rm() {
local cmd
read -r _ cmd < <(HISTTIMEFORMAT=''; history 1)
if [[ $cmd = "rm *" ]]; then
command rm -i "$@"
else
command rm "$@"
fi
}
这是如何运作的?
history 1
返回shell历史记录中的最新命令(前面有数字)。read -r _ cmd
将该数字读入变量_
,其余命令行读入变量cmd
[[ $cmd = "rm *" ]]
将命令与该精确字符串进行比较command rm ...
运行外部 rm
命令,避免再次递归到我们的函数。答案 1 :(得分:1)
由于您无法知道是否存在通配符,为什么不检查参数的数量?
例如:
#!/bin/bash
rm () {
if [ "$#" -gt 1 ]; then
echo command rm -i "$@"
else
echo command rm "$@"
fi
}
rm a b c
rm a