【问题标题】:Disable terminal commands [closed]禁用终端命令[关闭]
【发布时间】:2013-02-15 23:54:51
【问题描述】:

我想禁用rm,除非在某些情况下。我在.sh 文件中编写了一个名为remove 的函数,它通过了我在实际调用rm 之前想要强加的某些检查。但是,仍然可以进入终端并简单地调用rm 函数而不是使用remove。有没有办法禁用rm函数,除非被remove调用?我希望它就像rm 功能对登录终端的用户不“存在”一样,所有“存在”都是删除功能。

甚至可能更进一步,当用户调用rm 时,它会在屏幕上打印一条声明说使用remove

作为一个更广泛的问题,有没有办法在某些情况下禁用终端命令?我知道我可以为 rm 创建一个别名来要求 root,但这是一种简单且不太方便的方法。

#!/bin/bash

function rm {
  if [ $# -le 0 ]; then
    echo "Error: no arguments specified."
  else
    hasDir=0
    for arg in "$@"; 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 "$@"; do
          if [ ! -d "$file" ]; then command rm -f "$file"; fi
        done
      else 
        for file in "$@"; do
          if [ ! -d "$file" ]; then command rm -i "$file"; fi
        done
      fi
    else
      if [ "$check" == "n" ]; then
        command rm -rf "$@"
      else
        command rm -ir "$@"
      fi
    fi
  fi    
}

【问题讨论】:

  • 我会担心所有那些你不知道使用 rm 的脚本 - 来自 croninit* 等。你能不能只是改变 PATH 让你的 @987654337 @ 首先它不会阻止人们做/bin/rmthough.
  • rm 是可执行文件,而不是 shell 命令或函数。请记住,除了bash 之外,还有其他 shell。例如,运行 zsh 将绕过您尝试创建的任何基于 shell 的障碍。
  • 问题是我无法命名我的函数rm,因为它进入了递归状态。这就是为什么我必须给它取个别的名字,特别是remove
  • 我想这样做的原因不是出于安全原因或类似的原因,而只是为了能够做到这一点的知识。为了防止我不小心使用rm哈哈。
  • 在清理缩进时,我注意到您的脚本中似乎缺少 fi

标签: linux bash ubuntu-12.04 rm


【解决方案1】:

您可以覆盖rm(或任何其他命令);内置的command 允许您在必要时访问原始命令。

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

    command rm "$@"
}

command 禁用 shell 函数查找。

【讨论】:

  • 我在原始帖子中添加了我的代码。当我添加 command 时,我收到错误消息“rm:缺少操作数”
【解决方案2】:

如果您想捕获rm 的所有用途,那么有一种方法。但是,我必须提到这是一种肮脏的、不推荐的方式。

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

my_rm_script 应该包含对 /bin/rm.bak 的调用,而不是 /bin/rm。

这将捕获对命令rm 的所有调用。

但是,这不适用于busybox 类型的架构,其中二进制文件的名称也很重要。

【讨论】:

  • 这对我来说听起来很脏。不知道我是否应该改变这样的事情。
【解决方案3】:

您可以使用dpkg-divert 在您的系统上安装不同的rm

有关使用 shell 脚本的示例,另请参阅这篇文章 Replacing binaries with dpkg-divert

【讨论】:

    【解决方案4】:

    这是一个解决方案,它有点奇怪,但完全按照你想要的方式工作。

    在您的主文件夹中创建一个directory

    $~ mkdir ~/myrm

    $~ cd ~/myrm

    创建一个符号链接 rm 到您的 remove 二进制文件

    $~ 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 并调用它。

    【讨论】:

    • chmod 0777 是非常糟糕的建议!这允许 任何人 修改您的脚本。如果要使其可执行,请改用chmod a+x rm
    • ya 0777 是个坏主意。 0644在这里会很完美..
    猜你喜欢
    • 2013-03-10
    • 2020-10-09
    • 2013-06-01
    • 2013-07-03
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    相关资源
    最近更新 更多