【问题标题】:I'm trying to prevent the execution of a command in BASH.. Doesn't work always我试图阻止在 BASH 中执行命令.. 并不总是有效
【发布时间】:2018-02-07 19:50:45
【问题描述】:

这是基于another question of mine。我试图阻止使用脚本执行某些命令。我让脚本在交互式 shell 中完美运行,但对于非交互式 shell,它不会阻止它的执行。

/home/user/stop.sh(来源于.bashrc)

#!/usr/bin/env bash
shopt -s extdebug; stop_cmd () {
    [ -n "$COMP_LINE" ] && return  # not needed for completion
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # not needed for prompt
    local this_command=$BASH_COMMAND;
    echo $this_command" Not Allowed";
    return 1
};
trap 'stop_cmd' DEBUG

/home/user/temp.sh

#!/usr/bin/env bash
ls

我使用@Inian 建议的 BASH_ENV 变量将我的脚本放入使用非交互式 shell 的脚本文件中。

在新的外壳中

#:export BASH_ENV=/home/user/stop.sh
#:ls
ls Not Allowed --> This is because of the source in .bashrc
#:             --> Prompt appears. ls did not run
#:./temp.sh
./temp.sh: /usr/share/bashdb/bashdb-main.inc: No such file or directory
./temp.sh: warning: cannot start debugger; debugging mode disabled
ls Not Allowed  --> Because of the $BASH_ENV
Directory contents displayed  --> ls ended up running
#:             --> Prompt appears after executing temp.sh

但是如果我直接在temp.shsource stop.sh 不会显示这种行为,它就像一个魅力。

【问题讨论】:

  • 我没有这样做!但是你能解释一下你是如何在上面的代码中使用BASH_ENV 的吗?以及传递给它的文件内容
  • @Inian 对不起,如果不是很明显......让我编辑这个问题。我知道你没有这样做????
  • 抱怨反对票是吸引更多人的好方法。这不是它应有的工作方式,但考虑到您正在寻求帮助并且显然仍在学习该网站的规则的情况,这并不引人注目。
  • 顺便说一句,echo $this_command" Not Allowed"; 看起来很奇怪。没有特别的理由将静态字符串放在双引号内,但有很多理由将 $this_command 放在引号内。另见stackoverflow.com/questions/10067266/…
  • 我没有尝试复制,但看起来trap 'stop_cmd' DEBUG 没有被继承。我推测env 是这里的罪魁祸首。

标签: linux bash


【解决方案1】:
  1. 防止用户运行任何命令的最简单方法 就是不给他们账。 (你说你想“阻止某些命令的执行”, 但是您的 stop.sh 会阻止所有命令。 这让您的问题有点难以理解。)
  2. 阻止用户运行某些程序的最简单方法 是将它们更改为 700。 如果要求指定用户能够运行该程序, 使用 ACL 授予他们访问权限。 (如果只需要屏蔽少数用户, 您也许可以使用 ACL 来做到这一点,但这可能不可靠。)

    您的方法将很难正确。 假设你真的想阻止人们运行ls(真的吗?), 你打算处理类似的事情吗

    cp /bin/ls ls_copy
    ./ls_copy
    

    ln -s /bin/ls ls_link
    ./ls_link
    

    ?

  3. 我今天了解到 bash 有调试模式。 我对此了解不多,但我通过实验发现, 当 bash 进程启动并读取设置 extdebug 的 BASH_ENV 文件时, 它(bash shell)试图读取/usr/share/bashdb/bashdb-main.inc。 (这条路径显然是硬编码在/bin/bash 中的。) 这对你来说应该不足为奇, 当您收到命名该文件的错误消息时。 显然读取该文件时出现问题。

    如果您设置extdebug,则不会发生这种情况 和/或做trap <i>some_command</i> DEBUG 在脚本中(直接或通过source);我不知道为什么。 (Herehere 是几个参考 关于 bash 调试器。)

    建议:

    • 如果/usr/share/bashdb 目录不存在, 或者确实存在,但bashdb-main.inc 文件不存在, 创建它们(空文件)。
    • 如果存在/usr/share/bashdb/bashdb-main.inc, 将其重命名为备份名称。 特别是,这将是有用的 如果bashdb-main.inc 是指向不存在文件的符号链接。
    • 如果存在/usr/share/bashdb/bashdb-main.inc, 然后您尝试上面的第二个项目符号(重命名文件) 这不起作用,请尝试第一个项目符号(创建一个空文件)。
  4. 通过上述操作(重命名/usr/share/bashdb/bashdb-main.inc), 我能够让你的命令执行预防技巧发挥作用。

【讨论】:

  • 嗨@G-Man,我正在处理这个问题,并在途中与 Chet Ramey 进行了交谈,因此花了一段时间。抱歉回复晚了。 1(我的代码只是一个例子)和 2 不符合我的目的,因为我希望防止允许使用该命令但不将某些参数传递给该命令的情况。例如:允许使用 ls 但不允许使用 ls -al。让我们谈谈您对 3 的建议。该文件由包 bashdb 使用,并且按照您的方式执行此操作会阻止人们实际使用 bashdb。此外,当 bashdb 就位时,所有陷阱都将被删除。
  • 如果陷阱被移除,那对我来说绝对没问题,因为他们将无法调试我的陷阱!哈哈
【解决方案2】:

根据 Chet Ramey 的说法,shopt -s extdebug 在内部等同于 — debugger。如果 bash 在初始化过程中没有找到调试器,它会取消设置这个选项,基本上使我的return 1 无用。上述仅在非交互模式下发生,因为无法调试交互式 shell(因此未设置标志)。这清楚地解释了我的问题中所述的行为。因此,在应该使用我的陷阱的脚本中,需要在最顶部重置 shopt - s extdebug

【讨论】:

    猜你喜欢
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 2016-03-26
    • 2019-06-22
    相关资源
    最近更新 更多