如何使 bash 输入菜单对话框开始时自动单击重命名?

如何解决如何使 bash 输入菜单对话框开始时自动单击重命名?

我正在尝试让 bash inputmenu dialog 处理不同的类型,例如文件、日期、常规文本。单击编辑按钮,将简单地将用户发送到正确的对话框以检索输入。对于常规文本,我只想使用 inputmenu 的重命名功能。我不能让用户手动选择重命名,因为我只想将重命名操作用于文本输入。加载一个外观相同的对话框并自动选择重命名操作,这样我就可以解决这个问题。

What I'm trying to do

我尝试通过更改文件描述符并传入 \n\r 字符作为输入来实现这一点,但没有成功。

#!/bin/bash

list=(aaa bbb ccc)
selected=1

function menu1()
{
    count=0
    declare -a items
    for item in "${list[@]}"; do
        items+=($((++count)) "$item")
    done
    echo -n '2 ' > tmp.txt
    exec 4<tmp.txt
    cmd=(dialog
        --input-fd 4
        --print-size
        --print-maxsize
        --extra-button --extra-label "Edit"
        --default-button extra
        --default-item "$selected"
        --inputmenu "Select action:" 22 76 20)
    exec 3>&1
    #choices=$("${cmd[@]}" "${items[@]}" <<< ' ' 2>&1 1>&3)
    choices=$("${cmd[@]}" "${items[@]}" 2>&1 1>&3)
    retVal=$?
    exec 3>&-
    readarray -t choices <<< "${choices}"
    choices="${choices[2]}"
    echo "choices=$choices"
    echo "retVal=$retVal"
    menuAction "$retVal" "${choices[0]}"
}

function menu()
{
    count=0
    declare -a items
    for item in "${list[@]}"; do
        items+=($((++count)) "$item")
    done
    cmd=(dialog
        --print-size
        --print-maxsize
        --extra-button --extra-label "Edit"
        --default-button extra
        --default-item "$selected"
        --inputmenu "Select action:" 22 76 20)
    exec 3>&1
    choices=$("${cmd[@]}" "${items[@]}" 2>&1 1>&3)
    retVal=$?
    exec 3>&-
    readarray -t choices <<< "${choices}"
    choices="${choices[2]}"
    echo "choices=$choices"
    echo "retVal=$retVal"
    menuAction "$retVal" "${choices[0]}"
}

function menuAction()
{
    retVal="$1"
    choice="$2"
    declare -a choice="${choice[0]}"
    if [[ "$retVal" -eq 3 ]]; then
        choice=(${choice[0]})
        if [[ "${choice[0]}" == "RENAMED" ]]; then
            let selected=choice[1]
            let index=choice[1]-1
            unset choice[0]
            unset choice[1]
            list[$index]="${choice[@]}"
        fi
    fi
    [[ "$retVal" -ne 1 ]] && menu
}

menu1

编辑

我几乎已经使用 expect 让它工作了。不幸的是,在expect 将输入发送到对话框后,它返回到终端:

#!/bin/bash

/usr/bin/expect <<EOD
    set timeout 30
    spawn ./dialog1 >/dev/tty
    sleep 1
    send " "
    expect eof
EOD

注意

我完全意识到我正在尝试规避 dialogs 限制,这通常是一件坏事,因为它会导致更糟糕的代码,更难维护并且可能具有不必要的依赖项。这个问题应该被视为更多的学习练习。实际上,它仅在特殊情况下或作为可选的附加项才值得。我正在创建一个 api 制造商,我将让客户选择可选的增强功能,例如需要黑客解决方案。

解决方法

我同意其他评论者的看法,即这可能是一个非常糟糕的主意,但您可以这样做:

我还没想好如何用 expect 做到这一点,但它的替代方案可以称为 empty(在 ubuntu/debian 中为 sudo apt install empty-expect

也可以检测或忽略 Ctrl+C,但不能同时检测或忽略两者 - 请参阅注释。

#!/bin/bash

#temporary files
export MYTMP=/tmp/dialog_$RANDOM$RANDOM$RANDOM$RANDOM$RANDOM$RANDOM$RANDOM$RANDOM
export MYPID=${MYTMP}_pid.tmp
export MYOUT=${MYTMP}_out.tmp
export MYINP=${MYTMP}_inp.tmp
export MYRSL=${MYTMP}_rsl.tmp

#record "real" TTY just in case (this should not be necessary in most cases)
export MYTTY=`tty`

#replace command between `dialog` and `;` with your desired command or shell script
empty -f -i ${MYINP} -o ${MYOUT} /bin/bash -c 'dialog --extra-button --extra-label "Edit" --default-button extra --inputmenu "Select action:" 22 76 20 x "xx" y "yy" >${MYTTY} 2>${MYRSL} ; kill -SIGINT `cat ${MYPID}`'

#send "ENTER" key
sleep 0.1
echo -n -e '\n' >${MYINP}

# How to input keystrokes:
# \n - enter
# \e\e - ESC
# \t - tab (next button)
# \x0e - up     (or \e[A on some terminals)
# \x10 - down   (or \e[B on some terminals)

##optional: delete whatever was in the input box by pressing "DEL" a bunch of times
#echo -n -e '\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~\e[3~' >${MYINP}

## to detect Ctrl+C uncomment next line of code
#trap "export CTRL_C_PRESSED=1" INT
## ...and replace -SIGINT with -SIGTERM on line that starts with:   empty -f ...
##(you cannot both detect and ignore the signal)
## you could then test if ${CTRL_C_PRESSED} is equal to 1

#save PID to a file and redirect user input into 'dialog'
/bin/bash -c 'echo $$ >${MYPID} ; exec cat >${MYINP}'
## to ignore Ctrl+C insert:   ; trap "" INT ;   in place of semicolon (;) on previous line
## ...and replace -SIGINT with -SIGTERM on line that starts with:   empty -f ...

##If you trap/ignore Ctrl+C the script may screw up the terminal
##in that case please run    reset    command to fix,it also clears the screen


# check result in the file as you normally do
echo "----Result: `cat ${MYRSL}` "


#remove temporary files/pipes
sleep 0.1
if [ -e ${MYPID} ]; then rm ${MYPID}; fi;
if [ -e ${MYINP} ]; then rm ${MYINP}; fi;
if [ -e ${MYOUT} ]; then rm ${MYOUT}; fi;
if [ -e ${MYRSL} ]; then rm ${MYRSL}; fi;

工作原理:

  • 实际命令在另一个 shell 中执行,但输出直接通过管道传输到 tty
  • empty 拦截输入和输出并将它们附加到管道
  • 必要的命令输出到“输入”管道
  • 然后 TTY 的实际 STDIN 被重定向到同一个管道
  • 命令结果保存在临时文件中
  • 当命令完成执行时,它会发送 Ctrl+C 到 cat 以停止重定向
    • (否则 cat 不会意识到管道不再存在,因此用户必须再按一次 ENTER)

可以避免使用临时文件,但这会使代码更加复杂

,

使用--inputbox

var=$(dialog --output-fd 1 --inputbox test 10 10)

它会立即打开输入菜单,而不是随意使用 $var 中的数据。

还要考虑这个:

list=(
    1 aaa
    2 bbb
    3 ccc
)

selected=1

first() {
    cmd=$(
        dialog \
        --output-fd 1 \
        --default-button extra    \
        --default-item "$selected" \
        --extra-button --extra-label "Edit"  \
        --inputmenu "Select action:" 22 76 20 "${list[@]}"
    )
}

first

运行 $cmd 函数后,您将在 first 中得到类似的内容:

$ echo $cmd
RENAMED 2 123

解析并使用这些数据,例如:

sub=($cmd)
index=${sub[1]}
value=${sub[2]}

还要检查我如何管理我的 sshto 项目中的对话框

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res