【问题标题】:Handle EOF in RLWrap在 RLWrap 中处理 EOF
【发布时间】:2019-09-21 17:54:03
【问题描述】:

我正在使用 RLWrap 来“驯服”一个非常好的 REPL,即 Dyalog APL,不幸的是,它起源于 Windows 领域,因此不符合 UNIX 约定。此外,作为一个封闭源代码的产品,它不能被修改为这样做。

我设法实现了我的大部分目标,但 Ctrl-D 仍然会导致它发出错误并继续运行, 而我希望它像任何其他 REPL 一样优雅地退出。

我查看了 rlwrap 选项以及它的过滤器 API,以寻找一种拦截来自用户的 EOF 并将其转换为自定义退出命令的方法,在我的情况下是 )off,但我不能想办法去做。

我现在的别名:

alias dyalog='rlwrap -a -H ~/.dyalog_history /opt/mdyalog/17.0/64/unicode/dyalog -b -s'

相关选项有:

  • -s 告诉 Dyalog 以简单的 REPL 模式启动,而不控制屏幕;
  • -a 告诉 RLWrap 始终保持在 readline 模式,忽略 Dyalog 逐个字符读取输入的尝试。

【问题讨论】:

    标签: exit eof rlwrap


    【解决方案1】:

    诀窍是从读取中捕获返回码。鉴于它的嵌套程度,我发现在主目录的隐藏文件中执行此操作最容易。

    为了了解它是如何完全工作的,我包含了一个更大的代码块,但核心位于那一行,其中包含“读取”。

    sCommand=""
    while [ ! "$sCommand" == "exit" ]
    do
    
        sHistory=~/.promptHistory
        sCommand=$(rlwrap -H $sHistory sh -c 'read -p "> " REPLY && echo $REPLY'; echo $? > ~/.hold)
    
        if [[ "$(cat ~/.hold)" -eq 1 ]]; then sCommand="exit"; fi
    
        if [ "$sCommand" == "exit" ]; then return; fi # Bail out if the user asked for exit.
    
        case $sCommand in
    
            # All useful commands intercepted here.  Let 'exit' flow through.
    
        esac
    
    done
    

    神奇之处在于使用 $? 获取返回码?并将其放入 ~/.hold 以确保安全。从那里开始,剩下的只是代码。

    【讨论】:

      【解决方案2】:

      假设“裸”dyalog 通过优雅退出来响应 CTRL+D,您可以通过将接下来的几行添加到您的~/.inputrc:

      $if dyalog 
       "\C-d": rlwrap-direct-keypress
      $endif
      

      您可能(或可能不必)发布

       $ stty eof undef
      

      预先在您使用的终端中(以防止 CTRL+D 关闭您的stdin

      【讨论】:

        猜你喜欢
        • 2012-06-25
        • 2015-07-25
        • 2016-08-24
        • 2016-08-26
        • 1970-01-01
        • 1970-01-01
        • 2013-03-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多