SIGINT取消bash脚本中的读取?

mga*_*aia 6 bash sigint

我正在编写一个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
Run Code Online (Sandbox Code Playgroud)

CGa*_*ote 6

我知道这已经很老了,但我一直在努力做这样的事情并想出了这个解决方案。希望它能帮助别人!

#/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
Run Code Online (Sandbox Code Playgroud)

通过将读取内容放入子 shell 中,您可以确保它会被 sigint 信号杀死。如果您在该 sigint 渗透到父级时捕获该信号,则可以在那里忽略它并移至下一个 while 循环。您不必将 reset_cursor 作为其自己的函数,但我发现如果您想做更复杂的事情,它会很好。

我必须在子 shell 中添加 if 语句,因为否则它会忽略 ctrl+d - 但我们希望它能够“注销”,而无需强制用户键入 exit 或手动退出。


F. *_*uri 2

您可以使用像 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
Run Code Online (Sandbox Code Playgroud)

请查看 bash 的手册页,搜索“debug”关键字...

man -Pless\ +/debug bash
Run Code Online (Sandbox Code Playgroud)