![选择命令毫无疑问地显示选项](https://linux22.com/image/199311/%E9%80%89%E6%8B%A9%E5%91%BD%E4%BB%A4%E6%AF%AB%E6%97%A0%E7%96%91%E9%97%AE%E5%9C%B0%E6%98%BE%E7%A4%BA%E9%80%89%E9%A1%B9.png)
选择命令显示选项而不显示问题。做出选择后显示问题。
我在脚本中有一个如下所示的函数。
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 ?"