如果我輸入rm *
,但想以其他方式運行rm
,我想讓bash運行rm -i *
。重要的是,我不想在每次使用通配符時運行rm -i
,例如rm part*
。這裏是盡我所能:如何捕獲「*」作爲bash函數的參數並用於比較
rm()
{
if [ "$1" == "*" ]; then
rm -i *
else
rm $1
fi
}
但我知道這將失敗。我知道我想要的比較是^*$
,但我不知道如何實現它。
如果我輸入rm *
,但想以其他方式運行rm
,我想讓bash運行rm -i *
。重要的是,我不想在每次使用通配符時運行rm -i
,例如rm part*
。這裏是盡我所能:如何捕獲「*」作爲bash函數的參數並用於比較
rm()
{
if [ "$1" == "*" ]; then
rm -i *
else
rm $1
fi
}
但我知道這將失敗。我知道我想要的比較是^*$
,但我不知道如何實現它。
這是從字面上不可能知道你的命令是否在沒有你的shell的配合下用通配符調用。
當你調用rm *
(像任何其他命令),在*
被替換的文件名的調用之前的列表。因此,當在命令內部時,其被賦予通配符的信息不再存在:$1
,$2
等已被替換爲通配符擴展到的名稱列表。
這就是說,因爲我們是一個shell函數,我們殼的合作是實際可用:
rm() {
local cmd
read -r _ cmd < <(HISTTIMEFORMAT=''; history 1)
if [[ $cmd = "rm *" ]]; then
command rm -i "[email protected]"
else
command rm "[email protected]"
fi
}
這是如何工作的?
history 1
返回shell歷史記錄中最近的命令(前面有一個數字)。read -r _ cmd
讀取數入變量_
,命令行的其餘部分到所述可變cmd
[[ $cmd = "rm *" ]]
針對精確串command rm ...
運行外部rm
命令比較命令,避免遞歸回我們的功能再次。這可能對某些情況無效。我在shell中導出HISTTIMEFORMAT =「[%F%T]」',並且失敗。可能條件可以改爲'[[$ cmd == *「rm *」]]' – anubhava
不,我不是那個意思。在當前形式中,這個函數沒有運行'rm -i ...',因爲我在''.bashrc'中導出了HISTTIMEFORMAT =「[%F%T]」,導致'history 1'輸出'49370 [2016-07-29 15:42:52] rm *'。這就是爲什麼我建議'[[$ cmd == *「rm *」]]'可能會工作 – anubhava
* facepalm * - 我錯過了'*「rm *」'錨定在最後。是的,這很有道理。 –
既然你不知道是否有通配符,爲什麼不檢查參數的數量?
例如:
#!/bin/bash
rm() {
if [ "$#" -gt 1 ]; then
echo command rm -i "[email protected]"
else
echo command rm "[email protected]"
fi
}
rm a b c
rm a
...但你不知道你是否得到了'a',因爲那是'*'所評估的或'a',因爲這是用戶通過的。 –
@CharlesDuffy:的確如此。但我認爲這個用例是警告如果多個文件將被刪除,所以它可能是OP的有效選擇。 – user000001
我完全喜歡解決方案的優雅。它實際上涉及到問題的核心 - 防止我刪除多個文件(或者我輸入的任何數字)。但我認爲實際捕捉命令總體上更安全。儘管偉大的工作! – abalter
通過執行你的'rm'功能'*'已經擴大了時間。 – Paulpro
問題是'rm'沒有得到'*'作爲參數;它獲得了shell擴展'*'作爲參數的長文件列表。 – chepner
GNU'rm'有一個'-I'選項,只有在刪除超過3個文件時纔會提示你。 – chepner