【问题标题】:Intercept and prevent command from running in bash拦截并阻止命令在 bash 中运行
【发布时间】:2019-05-06 17:39:57
【问题描述】:

是否可以拦截 bash 中的所有命令并阻止其中一些命令执行?与 'trap' 命令一样,只是不允许进一步执行命令。

我是一名网络开发人员,目前正在开发一个小型项目/脚本,通过动态添加不同的别名来帮助网络开发人员的日常生活。例如,作为一名 Web 开发人员,在 Ubuntu 上,通常会将所有项目托管在 /var/www/ 结构中,因此可以在该 (/var/www) 文件夹中为这些文件夹起别名。我想稍微改进一下我的脚本,并根据项目构建的框架为项目添加别名。如果是 Magento 2,那么通过运行 setup:upgrade 它应该运行“bin/magento setup:upgrade”。 我试过陷阱“某事”调试,但据我所知,无法阻止前面的命令。 谢谢!

【问题讨论】:

  • 您是否考虑过编写一个脚本/函数来检查当前目录并相应地执行命令,而不是尝试拦截命令并取消它?'
  • 最初的计划是修复拼写错误,所以如果函数能够及时动态地创建,那就太酷了。如果无法进行拦截,这就是我会采用的方式。谢谢!
  • 您始终可以使用函数或别名覆盖命令,然后选择(或不)调用支持命令
  • 如果您使用 Linux,请查看SELinux
  • @thatotherguy,是否有可能在执行时以某种方式自动执行?如果我想拦截所有命令,我必须为“compgen -acb”的所有结果起别名(很多,3000+)。我试图通过在前面提到的陷阱中创建别名来做到这一点,但似乎操作系统已经考虑到它将执行什么,并且别名在第一个陷阱中不起作用。

标签: bash


【解决方案1】:

你可以通过滥用command_not_found_handle来否决命令:

# Save the PATH
realpath="$PATH"
# Set a PATH without commands (weirdly can't be empty)
PATH="/"

command_not_found_handle() (
  if [[ "$1" == *d* ]]
  then
    echo "Sorry, no commands with 'd' allowed" >&2
    return 1
  else
    PATH="$realpath" 
    unset command_not_found_handle
    "$@"
  fi
)

在您的.bashrc 中使用它,您可以运行lschown,但不能运行findchmod。请注意,它不会影响函数或内置函数。

【讨论】:

  • 聪明。这是一个重要的细节,您在子 shell 中运行所有这些,这就是为什么 unsetPATH 分配不会破坏它的原因。
【解决方案2】:

是的,这是可能的。 trap ... DEBUG 是一个好的开始,如果您想阻止某些命令,则必须将其与 shopt -s extdebug 关联。那么,如果你从陷阱中返回一个非零状态,该命令将不会被执行。

$ trap 'if [[ "$BASH_COMMAND" == "echo "* ]]; then printf "[%s]\n" ${BASH_COMMAND#echo}; false; fi' DEBUG
$ set -T              # Necessary for subshells and functions
$ shopt -s extdebug
$ echo foo bar
[foo]
[bar]
$ trap - DEBUG
$ echo foo bar
foo bar

【讨论】:

  • 正是我想要的。这可以覆盖任何内置、别名或命令,对吗?非常感谢 shopt -t 的建议!
  • 很高兴它有帮助。它可以覆盖任何 DEBUG trap 陷阱。我对此了解不多。别名已展开,因此您不会看到它们。除非您“set -T”,否则函数和子shell 内的命令不会被捕获,这可能不是您想要的。我会将此添加到我的答案中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-27
  • 2022-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多