【问题标题】:How to trap input to control the screenshot function?如何捕获输入来控制截图功能?
【发布时间】:2020-05-15 14:27:49
【问题描述】:

我想捕获输入来控制截图功能。

vim myscreenshot.sh
screenshot(){
    ffmpeg -video_size 1920x1080 -framerate 25 -f x11grab -i :0.0+0,0   /tmp/out.mp4  
}
close(){
    echo "screenshot is over"
    exit
}    
trap 'screenshot'  ctrl+a #how to fix it?
trap 'close'  ctrl+b #how to fix it?

命令trap 'screenshot' SIGINT可以捕获ctrl+c
我的要求:输入ctrl+a启动截图功能,ctrl+b停止截图功能并在后台运行bash myscreenshot.sh &后退出。

【问题讨论】:

  • Ctrl+A 不会产生信号,因此您不能“捕获”它。您可能能够在 bash/zsh/whateversh 中绑定该组合来调用 ffmpeg。参见例如this answer
  • 尝试运行help bind
  • @coder_view 是仅在运行后台脚本的控制台内激活或全局注册的陷阱?

标签: bash bash-trap


【解决方案1】:

Bash 陷阱不是处理键盘输入的方法;他们处理signals。它适用于 Ctrl+C 因为您的终端(不是 Bash)被配置为在按下该组合键时发送 SIGINT 信号 to Bash (运行stty -a 以查看所有此类绑定)。但是信号并非设计用于以这种方式使用。 trap ... SIGINT 应该是almost always be used to interrupt and terminate the program

正如@MarkSetchell 建议的那样,bind 是配置键绑定的正确工具,例如 Ctrl+A(符号:C-a)。该手册有更多关于existing bindings you can configure 的详细信息(特别是参见“杂项命令”,它提供了一些有用的行为,例如 Esc Ctrl+A (M-C-e) 其中expands all variables in the current pending command)。请注意,C-abound to beginning-of-line by default,而 C-b 绑定到 backward-charReadline manual 更详细,因为这实际上是造成所有这些行为的原因。网上也有很多关于让bind 做不同事情的文章和示例,所以只需搜索“bind”而不是“trap”就足够了:)

您可以尝试以下几个示例:

  • bind "\C-a":display-shell-version 将导致 Ctrl+A 调用 readline 函数 display-shell-version 打印当前 Bash 版本,而不是将光标跳转到行首。
  • bind -x '"\C-b":"echo Hello World"'(注意 -x)将导致 Ctrl+B 调用 shell 命令 echo Hello World,而不是将光标移回一个字符。

听起来您想配置任意键绑定,由于涉及的层不同,您可能会发现这是一场艰苦的战斗。用“正确”编程语言编写的专用 GUI 感知程序可以监视您的键盘,这将更适合您所描述的内容。显然,这比与 Bash 摔跤更费力,所以希望你能从 bind 中得到足够好的东西:)

【讨论】:

    【解决方案2】:

    作为在 shell 提示符下使用 readline 的替代方法,请考虑以下 bash 解决方案。解决方案紧密匹配要求。基本上:

    永远循环:

    • 等待 Ctrl/A
    • 在后台开始截图
    • 等待 Ctrl/B
    • 停止屏幕截图,运行外部 screenshot.sh

    它使用 bash 在需要行分隔符的时间读取一个字符。

    旁注:给定程序在具有专用终端的窗口中运行,Ctrl/A 和 Ctrl/B 可以替换为更简单的内容 - 只需 'A' 和 'B'。

    #! /bin/bash
    
    screenshot(){
        rm -f /tmp/out.mp4
        exec ffmpeg -video_size 1920x1080 -framerate 25 -f x11grab -i :0.0+0,0   /tmp/out.mp4
    }
    
    while true ; do
        a=""
        echo "Type CTRL/A to start"
        while [ "$a" != $'\x01' ] ; do
            read -N1 a
        done
        screenshot &
        sleep 3
        echo
        echo "Type CTRL/B to start"
        while [ "$a" != $'\x02' ] ; do
                read -N1 a
        done
        echo "Processing ..."
        kill $!
        bash myscreenshot.sh &
    done
    

    【讨论】:

      【解决方案3】:

      Ctrl+A 不会产生信号,Bash 陷阱不是处理键盘输入的方法;他们处理信号。它适用于 Ctrl+C,因为不是 Bash,但您的终端配置为在按下组合键时向 Bash 发送 SIGINT 信号,您可以通过 stty -a 进行检查.所以用最简单的方式你不能困住它。

      你也可以看看这个例子:

      bind "\C-a":display-shell-version 将导致 Ctrl+A 打印当前的 Bash 版本,而不是将光标跳转到行首。 bind -x '"\C-b":"echo Hello World"'(注意 -x)会导致 Ctrl+B 调用 shell 命令 echo Hello World。

      还可以考虑运行 help bind

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-05
        • 1970-01-01
        • 2011-04-21
        • 2018-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多