ルモーリン

シェル用メニューキット

投稿:2022-05-21

スクリプトを起動時に引数でパラメタを渡すのが面白くない。 起動してしまうと止まらないし、間違いのまま実行してしまうと復旧が面倒な場合、スクリプト内でのチェックを厳重にする必要がある。 メニュー形式でパラメタを設定、妥当性確認後に実行する仕組みが欲しい。

こんな感じの画面が出ます。 キーのjやkの他に矢印でも上下できてenterでメニュー選択できます。 面倒な画面制御をメニューキットが一手に引き受けます。 また、メニュー選択時にプロンプトを出してパラメタの設定や検証ができます。

#!/bin/bash

function custom_status() {
	echo "(ここに状態を表示)"
}

function custom_menu() {
	menu_item=()
	menu_item+=("アイテム1")
	menu_item+=("アイテム2")
	menu_item+=("アイテム3")
	menu_item+=("アイテム4")
}

function custom_exec() {
	local item=$1

	local line
	if [ 0 -eq $item ]; then
		echo -n "アイテム1> "
		read line
	elif [ 1 -eq $item ]; then
		echo -n "アイテム2> "
		read line
	elif [ 2 -eq $item ]; then
		echo -n "アイテム3> "
		read line
	elif [ 3 -eq $item ]; then
		echo -n "アイテム4> "
		read line
	fi
}

# メニュー処理を読み込む
. menu_kit.sh

menu_init

echo -e ${menu_green}メニュー処理のサンプル$menu_reset

menu_loop

exit 0
#!/bin/bash

function menu_init() {
	menu_red=$(tput setaf 9)
	menu_green=$(tput setaf 10)
	menu_reset=$(tput op)

	key_up=$'\e[A'
	key_down=$'\e[B'

	menu_sel=-1

	tput cvvis
}

function menu_indicator() {
	local pos=$1
	local disp=$2

	# インジケータ表示
	tput cr
	tput cuu $((${#menu_item[@]} + 2 - $pos))
	if [ 1 -eq $disp ]; then
		echo -n "$menu_green>$menu_reset"
	else
		echo -n " "
	fi

	tput rc
}

function menu_select() {
	# 初期表示
	if [ $menu_sel -lt 0 ]; then
		menu_sel=0
	else
		# 表示済のメニュー上端へ
		tput cr
		tput cuu $((${#menu_item[@]} + 3))
	fi

	echo メニュー
	custom_menu

	local line
	for line in "${menu_item[@]}"
	do
		tput el
		echo -e " $line"
	done

	echo " 終了";

	custom_status

	echo -n -e "入力:j<↓>/k<↑>/<enter>"

	# カーソル位置記録
	tput sc

	menu_indicator $menu_sel 1

	local key=.
	while [ "$key" != "" ]
	do
		local key0
		local key12
		read -s -n 1 key0
		if [ "$key0" = $'\e' ]; then
			read -s -n 2 key12
			key=$key0$key12
		elif [ "$key0" != "" ]; then
			key=$key0
		else
			key=
		fi

		menu_indicator $menu_sel 0

		if [ "$key" = "j" -o "$key" = $key_down ]; then
			if [ $menu_sel -lt ${#menu_item[@]} ]; then
				menu_sel=$(($menu_sel + 1))
			fi
		elif [ "$key" = "k" -o "$key" = $key_up ]; then
			if [ 0 -lt $menu_sel ]; then
				menu_sel=$(($menu_sel - 1))
			fi
		fi

		menu_indicator $menu_sel 1
	done

	menu_clear
}

function menu_clear() {
	tput rc
	tput cr
	tput el
	tput cuu 1
	tput el
}

function menu_loop() {
	tput civis

	while [ $menu_sel -lt ${#menu_item[@]} ]
	do
		menu_select
		if [ $menu_sel -lt ${#menu_item[@]} ]; then
			menu_clear
			tput cvvis
			custom_exec $menu_sel
			tput civis
			menu_clear
			tput rc
		fi
	done

	echo -e ${menu_green}終了$menu_reset

	tput cnorm
}

function menu_quit() {
	menu_sel=${#menu_item[@]}
}