2013-02-15 156 views
0

我想禁止使用rm,除了在某些情況下。我在.sh文件中編寫了一個名爲remove的函數,它會在實際調用rm之前通過某些檢查來執行。但是,仍然可以進入終端,只需調用rm函數而不是使用remove。有沒有辦法來禁用rm函數,除非被remove調用?我希望它能像rm函數對登錄到終端的用戶不存在「存在」,所有「存在」都是刪除功能。禁用終端命令

甚至可能會更進一步,當用戶呼叫rm時,它會在屏幕上打印一條聲明使用remove的聲明。

作爲一個更廣泛的問題,有沒有辦法禁用終端命令,除了在某些情況下?我知道我只需要爲rm製作一個別名即可,但這是簡單且不太方便的解決方法。

#!/bin/bash 

function rm { 
    if [ $# -le 0 ]; then 
    echo "Error: no arguments specified." 
    else 
    hasDir=0 
    for arg in "[email protected]"; do 
     if [ -d "$arg" ]; then hasDir=1; fi 
    done 

    ac="Action canceled." 
    resp=("y" "n" "e") 

    sure=" " 
    while [ "$sure" != "y" ] && [ "$sure" != "n" ]; do 
     read -p "PERMANENT ACTION. Are you sure? (y/n): " sure 
    done 

    if [ "$sure" == "n" ]; then echo "$ac"; return; fi 


    if [ $hasDir -eq 1 ]; then 
     direc=" " 
     validResp=0 
     while [ $validResp -eq 0 ]; do 
     read -p "Remove all sub-directories? (y/n/e): " direc 
     for ans in "${resp[@]}"; do 
      if [ "$direc" == "$ans" ]; then validResp=1; fi 
     done 
     done 

     if [ "$direc" == "e" ]; then echo "$ac"; return; fi 
    else 
     direc="n" 
    fi 



    check=" " 
    validResp=0 
    while [ $validResp -eq 0 ]; do 
     read -p "Verify removal of each file? (y/n): " check 
     for ans in "${resp[@]}"; do 
     if [ "$check" == "$ans" ]; then validResp=1; fi 
     done 
    done 

    if [ "$check" == "e" ]; then echo "$ac"; return; fi 


    if [ "$direc" == "n" ]; then 
     if [ "$check" == "n" ]; then 
     for file in "[email protected]"; do 
      if [ ! -d "$file" ]; then command rm -f "$file"; fi 
     done 
     else 
     for file in "[email protected]"; do 
      if [ ! -d "$file" ]; then command rm -i "$file"; fi 
     done 
     fi 
    else 
     if [ "$check" == "n" ]; then 
     command rm -rf "[email protected]" 
     else 
     command rm -ir "[email protected]" 
     fi 
    fi 
    fi  
} 
+2

我擔心所有那些你不知道使用''rm''的腳本 - 從''cron''和''init *'''等等。你能不能改變PATH來讓你的''rm''首先它不會阻止人們執行''/ bin/rm''雖然。 – sotapme 2013-02-15 23:58:07

+1

'rm'是一個可執行文件,而不是一個shell命令或函數。請記住除了'bash'之外還有其他的shell。例如,運行'zsh'將會繞過您嘗試創建的任何基於shell的障礙。 – chepner 2013-02-16 00:12:07

+0

問題是我無法命名我的函數'rm',因爲它進入遞歸狀態。這就是爲什麼我必須將其命名爲其他東西,特別是「刪除」。 – nick 2013-02-16 00:14:44

回答

5

您可以覆蓋rm(或任何其他命令);內置的command可讓您在必要時訪問原始命令。

rm() { 
    # Do something in addition to removing the file 

    command rm "[email protected]" 
} 

command禁用shell函數查找。

+0

「命令」+1 +1 – 2013-02-16 01:21:47

+0

我在原文中添加了我的代碼。當我添加'command'時,我得到錯誤信息「rm:missing operand」 – nick 2013-02-16 02:37:21

0

下面是一個解決方案,它有點怪異的方式,但是完全按照你想要的方式工作。

個人文件夾創建一個directory

$~ mkdir ~/myrm

$~ cd ~/myrm

創建符號鏈接rmremove二進制

$~ ln -s /path/to/remove rm

現在上面的命令創建一個鏈接rm其中指向remove基本上,您通過調用rm調用remove。確保可執行權限上rm給其他人使用

$~ chmod 0777 rm

現在就要把路徑在$PATH變量。

$~ PATH=~/myrm/:$PATH

確保其~/myrm:$PATH$PATH:myrm。所以,現在只要您撥打rm,它就會在~/myrm目錄中搜索rm並調用它。

+0

chmod'0777'非常不好的建議!這允許*任何人*修改您的腳本。如果要使其可執行,請改用'chmod a + x rm'。 – 2013-02-16 15:15:53

+0

雅0777是一個壞主意。 0644在這裏完美.. – 2013-02-19 06:26:35

1

如果要捕獲rm的所有用法,則有一種方法。但是,我必須提到這是一種骯髒的,不被推薦的方式。

mv /bin/rm /bin/rm.bak 
cp my_rm_script /bin/rm 

my_rm_script應該包含調用/bin/rm.bak而不是/ bin/rm。

這將捕獲所有呼叫命令rm

但是,這不適用於busybox類型的體系結構,其中二進制的名稱也很重要。

+0

這聽起來對我來說很髒。不知道我是否應該改變這樣的事情。 – nick 2013-02-16 16:05:26