Linuxのコマンド登録可能なメニュー処理シェルスクリプト
近頃Linux関連の書籍を少し読んでいるが、コマンドとオプションを覚えきれないで、困っていた。
そこで試みに、メニュー形式でコマンド実行できるシェルスクリプトを組んでみた。
だが、まだ完成していない。
機能は以下。
・メニューリストから番号を入力してコマンド実行。
・コマンドはメニューに別の表題をつけて表示される。(日本語メニュー)
・コマンド実行時、そのコマンド出力の内容のヘルプテキスト表示可能。
・コマンドとメニュー表題を追加・削除可能。
・サブメニュー選択可能。(まだサブメニューは追加編集はできない)
・サブメニューはまだ1階層しか実現できない。
例えば、上記プロンプトに「1」と番号を入力すると、
「sar -u」が実行される。
shのスクリプトソースは以下。
#!/bin/sh CONFDIR="menu.sh.conf" MAINMENU="${CONFDIR}/menutext.txt" MAINCMD="${CONFDIR}/menucmd.txt" SUBMENUTEXT="${CONFDIR}/menusubtext" SUBMENUCMD="${CONFDIR}/menusubcmd" HELPFN="${CONFDIR}/menuhelp" SUBHELPFN="${CONFDIR}/menusubhelp" #メニュー描画 #menutext.txtを読み込んで加工し表示する #$1 : メニューテキスト(行頭#行はコメント) #$2 : ヘッダー表示フラグ(メインメニュー=""、サブメニュー="Snn") function drawmenu() { #ヘッダー表示 if [ -n "$2" ]; then #サブメニュー T=`cat $MAINMENU | grep -i $2 | cut -d : -f 2 -` echo "2=$2" echo "T=$T" echo "+++ [Sub] $T +++" else echo "*** メインメニュー ***" fi #menutext.txt の各行をxargsで引数に変換し、Lに1行ずつ代入。 #このとき、スペースはに変換している。(xargsに1行を1つの引数と認識させるため) for L in `cat $1 | sort | grep -iv "^[#0-9]" | sed "s/[ ]/ /g" | sort | xargs`; do #L中の を半角スペースに戻す。 L=`echo $L | sed "s/ / /g"` #Lに入っている行文字列の先頭に*を加え表示 echo "* $L" done for L in `cat $1 | grep -iv "^[#sSnN]" | sed "s/[ ]/ /g" | sort | xargs`; do #L中の を半角スペースに戻す。 L=`echo $L | sed "s/ / /g"` #Lに入っている行文字列の先頭に*を加え表示 echo "* $L" done if [ $1 = $MAINMENU ]; then echo "* 999:終了" else echo "* 999:メインメニューへ戻る" fi } #Y/Nチェック function yesno() { read -n 1 -p $1 A echo if [ $A = 'Y' -o $A = 'y' ]; then return 0 fi if [ $A = 'N' -o $A = 'n' ]; then return 1 fi return 2 } #pause function anykey() { read -n 1 -p '何かキーを押してください。' } #メニューのコマンドを実行 #$1 : コマンド番号(001〜) #$2 : コマンド登録テキストファイル(タブ区切り2列、先頭#行はコメント) function docommand() { #echo $1 $2 #コマンド抽出 C=`grep -v "^#" $2 | grep $1 | cut -f 2 -` echo "C=$C" #コマンドが存在した場合のみ実行 if [ -n "$C" ]; then eval $C fi } #コマンド作成 function makecmd() { while : do read -p '実行コマンドの表題を入力してください。(C[キャンセル])> ' T if [ "$T" = "C" ]; then echo "キャンセルしました。" return 1; else break fi done while : do read -p '実行コマンドを入力してください。(C[キャンセル])> ' C if [ "$C" = "C" ]; then echo "キャンセルしました。" return 1; else break fi done echo "コマンドのヘルプを入力してください。(Ctrl+D[入力完了],C+CtrlD[キャンセル])" TMPFN="/tmp/menu.sh.tmp.$$" cat - > $TMPFN H=`cat $TMPFN` if [ "$H" = "C" ]; then echo "キャンセルしました。" return 1; fi CUR=`cat $MAINMENU | grep "^[0-9]" | sort -r | head -1 | cut -d : -f 1 -` NEXT=`expr $CUR + 1` NEXT=`echo $NEXT | awk '{ printf("%03d",$0);}'` echo "$NEXT:$T" >> $MAINMENU echo -e $NEXT \\t $C >> $MAINCMD echo $H > ${HELPFN}_${NEXT}.txt } function removecmd() { read -p '削除するコマンド番号を入力してください。(C[キャンセル])> ' A if [ "$A" = "C" -o "$A" = "c" ]; then echo "キャンセルしました。" return 1 fi if echo $A | grep "^[^0-9]"; then echo "キャンセルしました。" return 1 fi S=`echo $A | awk '{printf("%03d",$0);}'` echo "S=$S" TEMPFN="/tmp/menu.sh.removefile.tmp.$$" cat $MAINMENU | grep -v "^$S" > $TEMPFN cat $TEMPFN > $MAINMENU cat $MAINCMD | grep -v "^$S" > $TEMPFN cat $TEMPFN > $MAINCMD } #ヘルプの表示 #$1 : コマンド番号 #$2 : MENUFLAG function printhelp() { if [ -n "$2" ]; then #サブメニュー FN="${SUBHELPFN}_$2_$1.txt" else FN="${HELPFN}_$1.txt" fi if [ -f "$FN" ]; then cat $FN fi } function Nproc() { if [ "$1" = "00" ]; then echo "新規メニューを作成します。" anykey makecmd anykey fi #N9 : サブメニューを削除 if [ "$1" = "09" ]; then echo "メニューを削除します。" anykey removecmd anykey fi } ER=1 CMENU=$MAINMENU CCMD=$MAINCMD MENUFLAG="" while [ $ER = 1 ]; do clear drawmenu $CMENU $MENUFLAG read -p '番号入力> ' A # echo "A=$A" #999番は終了か、サブメニューからメインメニューに戻る if [ $A = 999 ]; then if [ $CMENU = $MAINMENU ]; then echo "終了します。" exit 0; else MENUFLAG="" CMENU=$MAINMENU CCMD=$MAINCD continue fi fi #Nnn番はコマンドを新規作成など特殊メニュー if echo $A | grep -i "^n"; then #echo "サブメニュー" #N0 : サブメニュー番号をSに取得 S=`echo $A | sed -e "s/n\([0-9]*\)/\1/i" | awk '{printf("%02d",$0);}'` Nproc $S continue fi if echo $A | grep -i "^s"; then #echo "サブメニュー" #サブメニュー番号をSに取得 S=`echo $A | sed -e "s/s\([0-9]*\)/\1/i" | awk '{printf("%02d",$0);}'` #サブメニューのテキストファイル名を取得 SUBTEXTFN="${SUBMENUTEXT}_${S}.txt" #echo "S=${SUBMENUTEXT}_${S}.txt" #サブメニューファイルが存在するか? if [ -f $SUBTEXTFN ]; then #存在する #メニューをサブメニューに切り替え MENUFLAG="S$S" CMENU="${SUBMENUTEXT}_${S}.txt" CCMD="${SUBMENUCMD}_${S}.txt" else # echo "SUBTEXTFN=$SUBTEXTFN" echo "指定されたサブメニューは存在しません。" fi anykey continue fi #コマンド番号をAに取得 A=`echo $A | awk '{printf("%03d",$0);}'` #echo $A #ヘルプ表示 printhelp $A $MENUFLAG #コマンド実行 echo docommand $A $CCMD docommand $A $CCMD anykey done
以下、メニュー用テキストファイルの内容。(menutext.txt)
N00:新規メニュー作成 N09:メニュー削除 001:CPUの使用率や使用時間帯を調べたい(sar -u) #bb 002:キューの長さと使用された時間の割合を調べたい(sar -q) 003:発行されたシステムコールの回数を調べたい(sar -c) S01:サブメニュー1
以下、コマンド用テキストファイルの内容(menucmd.txt)
001 sar -u 1 5 002 sar -q 1 5 003 sar -c 1 5