【问题标题】:Bash how to return value from subscript to main script?Bash如何将值从下标返回到主脚本?
【发布时间】:2022-10-14 02:25:34
【问题描述】:

我将以下脚本保存到 menu.sh 文件中。

declare -a menu=("Option 1" "Option 2" "Option 3" "Option 4" "Option 5" "Option 6")
cur=0

draw_menu() {
    for i in "${menu[@]}"; do
        if [[ ${menu[$cur]} == $i ]]; then
            tput setaf 2; echo " > $i"; tput sgr0
        else
            echo "   $i";
        fi
    done
}

clear_menu()  {
    for i in "${menu[@]}"; do tput cuu1; done
    tput ed
}

# Draw initial Menu
draw_menu
while read -sn1 key; do # 1 char (not delimiter), silent
    # Check for enter/space
    if [[ "$key" == "" ]]; then break; fi

    # catch multi-char special key sequences
    read -sn1 -t 0.001 k1; read -sn1 -t 0.001 k2; read -sn1 -t 0.001 k3
    key+=${k1}${k2}${k3}

    case "$key" in
        # cursor up, left: previous item
        i|j|$'\e[A'|$'\e0A'|$'\e[D'|$'\e0D') ((cur > 0)) && ((cur--));;
        # cursor down, right: next item
        k|l|$'\e[B'|$'\e0B'|$'\e[C'|$'\e0C') ((cur < ${#menu[@]}-1)) && ((cur++));;
        # home: first item
        $'\e[1~'|$'\e0H'|$'\e[H')  cur=0;;
        # end: last item
        $'\e[4~'|$'\e0F'|$'\e[F') ((cur=${#menu[@]}-1));;
         # q, carriage return: quit
        q|''|$'\e')echo "Aborted." && exit;;
    esac
    # Redraw menu
    clear_menu
    draw_menu
done

echo "Selected item $cur: ${menu[$cur]}";

我现在有第二个main.sh,我在其中调用menu.sh 文件,如下所示:./menu.sh(它们在同一个目录中)。如何从main.sh 获得menu.sh 的输出? 由于某种原因,我无法通过管道或重定向将回显到标准输出。通过 $() 访问它也不起作用。我究竟做错了什么?

提前感谢所有帮助!

【问题讨论】:

  • “获取输出”是什么意思?您是否尝试将menu.sh 输出捕获到变量中?别的东西? fwiw,假设main.sh 的唯一内容是./menu.sh ...该脚本适用于我,即从命令行运行main.sh 在我的窗口中显示菜单(又名标准输出)
  • tput 和关键阅读魔法中的任何一个是否相关,或者您可以删除它并仍然显示您遇到的问题 (minimal reproducible example)?
  • @BenjaminW.我实际上从这里复制了代码:bughunter2k.de/blog/cursor-controlled-selectmenu-in-bash
  • val=$(./menu.sh) (显然)将标准输出重定向到 ariable val 因此您的标准输出“消失”(“Duh,Mark!”?);虽然可能有一种方法可以将“一些”标准输出重定向到变量,但添加 tput 调用和专门的光标代码将增加混合的复杂性;在这一点上,提供的脚本(有点)复杂并且(imo)有损于真正的问题是......??什么?? ...您想访问显示菜单的最后一行吗?在这一点上,我不确定你想要完成什么......
  • 我建议查看Hot to create a minimal, reproducible example 然后回来更新问题;特别是将menu.sh 减少到生成所需输出的最小代码集,然后告诉我们您希望将此输出的哪一部分“重定向”到main.sh;对重定向数据的一些想法也会有所帮助(例如,存储在变量中?存储在数组中?其他)?一旦你得到了适用于最小情况的东西,那么你可以继续弄清楚如何应用于你的实际代码

标签: bash shell


【解决方案1】:

一种方法是使用另一个文件来存储结果。

  1. 在您的 main.sh 中,提供一个临时文件名。 将此临时文件名提供给 menu.sh

  2. 在 menu.sh 中添加一些处理以确保在继续之前提供此文件。 更改 menu.sh 的结果以写入临时文件

  3. 回到 main.sh,从临时文件中读取结果。 然后摆脱文件

    所以,这里是 main.sh

    RESULTS_FILE=results.`date +%s`.txt
    ./menu.sh $RESULTS_FILE
    RESULTS=`cat $RESULTS_FILE`
    echo "Got results:"
    echo $RESULTS
    rm $RESULTS_FILE
    
    

    然后这里是你如何修改 menu.sh

    在顶部

    if [ "$1" == "" ] ; then 
        exit "You need to supply a temp file path"
    fi
    RESULTS_FILE=$1
    

    在 menu.sh 的底部,将最后一行更改为写入文件:

    echo "Selected item $cur: ${menu[$cur]}" > $RESULTS_FILE
    
    

【讨论】:

  • 谢谢你的帮助,工作就像一个魅力
猜你喜欢
  • 2018-04-20
  • 2018-06-25
  • 2011-04-09
  • 2018-07-02
  • 1970-01-01
  • 1970-01-01
  • 2012-04-22
  • 2017-02-07
  • 2012-08-07
相关资源
最近更新 更多