我希望能够执行所有内容,而不是运行程序,而是运行一个以可执行文件作为参数的 shell 脚本。如果能够做到这一点而无需单独选择系统上的所有可执行文件,那就太好了。
答案1
更改路径,然后将所有可执行文件复制到其中,其中每个可执行文件只是脚本的另一个名称。就像是 :
$ mkdir ${HOME}/shell
$ OLDPATH=$PATH
$ PATH=${HOME}/shell:$PATH
$ echo $PATH | tr : \\n \
| while read P; do (mkdir -p $(echo $P | sed s':/::'); ls $P/* ) \
| while read F; do ln master_script $(echo $F | sed s':/::'); done \
done
现在写master_script
。让它从 PATH 中删除 ${HOME}/shell,使用command -v
在真实路径中定位其名称,并exec
以 $@ 作为参数。
答案2
我不知道有什么方法可以将命令完全发送到脚本,但在 bash 或 zsh 中,您可以使用 DEBUG 陷阱添加一个钩子,该陷阱在每个命令之前调用。
详情请参阅https://superuser.com/questions/175799/does-bash-have-a-hook-that-is-run-before-executing-a-command
编辑:要停止命令,您可以通过更改 PATH 变量使其失败。例如:
preexec() {
if [ "$1" = "ls" ] ; then echo STOP; SAVEDPATH="$PATH"; export PATH=/DoesNotExist;
fi
}
preexec_invoke_exec () {
if [ "$SAVEDPATH" != "" ] ; then export PATH="$SAVEDPATH" ; unset SAVEDPATH ; fi;
[ -n "$COMP_LINE" ] && return # do nothing if completing
[ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
preexec "$this_command"
}
trap 'preexec_invoke_exec' DEBUG
您将看到类似的命令date
正常工作,但ls
失败并显示“找不到命令”。但这种方式不适用于 shell 内置命令,如echo
.