选择命令毫无疑问地显示选项

选择命令毫无疑问地显示选项

选择命令显示选项而不显示问题。做出选择后显示问题。

我在脚本中有一个如下所示的函数。

function start_AppNode
{
    #   Define local variables for all the inputs
    local DName_l=$1
    local ASName_l=$2
    local ANName_l=$3
    
    echo "Do you wish to start the AppNode $ANName_l on AppSpace $ASName_l in Domain $DName_l ?"
    select yn in "Yes" "No"; do
        case $yn in
            Yes ) 
                #print_log $yn
                OUTPUT="`./appadmin start -d $DName_l -as $ASName_l anode $ANName_l`"
                if [[ "$OUTPUT" == *"$SuccessMessage_AppNode_Start"* ]]; then
                    echo "Started"
                else
                    echo "Failed"
                fi
                break;;
            No ) echo "Failed"; break;;
        esac
    done
}

当我在导入该脚本的其他脚本中调用该脚本时,我首先获得选项并且不显示问题“ Do you wish to start the AppNode $ANName_l on AppSpace $ASName_l in Domain $DName_l ?

它显示做出选择后的问题。请参阅下面的输出屏幕截图。感谢是否有人可以帮助我理解如何使其首先显示问题?

在此输入图像描述

更新:该问题是由于变量分配造成的。我将函数的输出分配给一个变量。如果我执行该函数而不将返回值分配给变量,它就会起作用。如何将返回值分配给变量并仍然在选项之前显示问题部分?

答案1

我将忽略这样一个事实:代码不会生成您展示的输出,而是专注于如何与用户交互。

select语句在标准错误流上显示菜单和提示。通常在此流上与用户交互,而不是使用户交互成为程序标准输出流的一部分(这可能会混淆从函数读取输出的下游进程)。

我建议您将问题输出到标准错误流上的用户,而不是标准输出流。这是有道理的,因为您的问题与用户交互有关。

在下面某些情况,标准输出和标准错误流可能会在终端中交错出现。使用单个流与用户交互可以避免这种情况。

我还建议您使用printf而不是echo在必须输出变量数据时立即使用:

start_AppNode () {
    local DName_l="$1"
    local ASName_l="$2"
    local ANName_l="$3"

    local cmd=( ./appadmin start -d "$DName_l" -as "$ASName_l" anode "$ANName_l" )
    
    printf 'Do you wish to start the AppNode %s on AppSpace %s in Domain %s?\n' \
        "$ANName_l" "$ASName_l" "$DName_l" >&2
    
    local PS3='Start AppNode? '
    select yn in "Yes" "No"; do
        [[ $REPLY == 1 ]] && "${cmd[@]}"
        break
    done |
    if grep -q -F -e "$SuccessMessage_AppNode_Start"; then
        echo Started
    else
        echo Failed
    fi >&2
}

如果您希望该函数提供退出状态,您可以在脚本的某些主要部分中使用:

start_AppNode () {
    local DName_l="$1"
    local ASName_l="$2"
    local ANName_l="$3"

    local cmd=( ./appadmin start -d "$DName_l" -as "$ASName_l" anode "$ANName_l" )
    
    printf 'Do you wish to start the AppNode %s on AppSpace %s in Domain %s?\n' \
        "$ANName_l" "$ASName_l" "$DName_l" >&2
    
    local PS3='Start AppNode? '
    select yn in "Yes" "No"; do
        [[ $REPLY == 1 ]] && "${cmd[@]}"
        break
    done |
    grep -q -F -e "$SuccessMessage_AppNode_Start"
}

然后,后来:

if start_AppNode "$dn" "$as" "$an"; then
    echo 'Started, good'
else
    echo 'Failed, bad'
fi

if语句读取函数的退出状态并对其进行操作。函数的退出状态是函数中执行的最后一条语句的退出状态。这就是grep -q电话。这将是真的(零)如果在语句$SuccessMessage_AppNode_Start的输出中找到任何字符串select,并且错误的(非零)如果未找到该字符串。该select语句有条件地输出 的输出./appadmin,或者根本不输出任何内容,具体取决于用户做出的选择、提供给函数的参数以及影响 的输出的任何其他数量的外部因素./appadmin

答案2

作为@icarus在评论中写道

select将提示写入stderr同时echo写入 stdout。如果这些直接进入终端,它们会正确地交错,所以有些事情你没有告诉我们,例如,这个脚本的输出通过管道传输到说tee logfile

您需要确保未echo缓冲。您可以echo使用stdbuf -o0或运行您的程序,unbuffer以确保问题打印到 STDOUT 而无需任何缓冲。

stdbuf -o0 echo "Do you wish to start the AppNode $ANName_l on AppSpace $ASName_l in Domain $DName_l ?"

相关内容