我正在编写一个bash包装器来学习一些脚本概念.我们的想法是在bash中编写一个脚本,并在登录时将其设置为用户的shell.
我做了一个while循环reads和evals用户的输入,然后注意到,每当用户输入时CTRL + C,脚本都会中止,因此用户会话结束.
为了避免这种情况,我陷入SIGINT了陷阱,无所事事.
现在,问题在于当你输入CTRL + C一半命令时,它不会被取消,就像在bash上那样 - 它只是忽略了CTRL + C.
所以,如果我输入ping stockoverf^Cping stackoverflow.com,我得到的ping stockoverfping stackoverflow.com不是ping stackoverflow.com我想要的.
有没有办法做到这一点?
#!/bin/bash
# let's trap SIGINT (CTRL + C)
trap "" SIGINT
while true
do
    read -e -p "$USER - SHIELD: `pwd`> " command
    history -s $command
    eval $command
done
我知道这已经很老了,但我一直在努力做这样的事情并想出了这个解决方案。希望它能帮助别人!
#/usr/bin/env bash
# Works ok when it is invoked as a bash script, but not when sourced!
function reset_cursor(){
    echo
}
trap reset_cursor INT
while true; do
    command=$( if read -e -p "> " line ; then echo "$line"; else echo "quit"; fi )
    if [[ "$command" == "quit" ]] ; then
        exit
    else
        history -s $command
        eval "$command"
    fi
done
trap SIGINT
通过将读取内容放入子 shell 中,您可以确保它会被 sigint 信号杀死。如果您在该 sigint 渗透到父级时捕获该信号,则可以在那里忽略它并移至下一个 while 循环。您不必将 reset_cursor 作为其自己的函数,但我发现如果您想做更复杂的事情,它会很好。
我必须在子 shell 中添加 if 语句,因为否则它会忽略 ctrl+d - 但我们希望它能够“注销”,而无需强制用户键入 exit 或手动退出。
您可以使用像 xdotool 这样的工具来发送 Ctrl-A(行开始) Ctrl-K(删除到行尾) Return(清理行)
#!/bin/bash
trap "xdotool key Ctrl+A Ctrl+k Return" SIGINT;
unset command
while [ "$command" != "quit" ] ;do
    eval $command
    read -e -p "$USER - SHIELD: `pwd`> " command
  done
trap SIGINT
请查看 bash 的手册页,搜索“debug”关键字...
man -Pless\ +/debug bash