
質問を表示せずにオプションを表示するには、コマンドを選択します。選択後、質問が表示されます。
私のスクリプトには以下の機能があります。
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
使用または実行して、問題がバッファリングなしでSTDOUTに印刷されていることを確認できます。stdbuf -o0
unbuffer
stdbuf -o0 echo "Do you wish to start the AppNode $ANName_l on AppSpace $ASName_l in Domain $DName_l ?"