これは、BASHでのスクリプトのローカライズに関する記事の続きです。その中で、配列と間接参照を使用して、スクリプトに言語を追加し、それらを切り替える方法を学びました。
この記事では、組み込み言語のリストをコンパイルし、メニューから言語の選択を設定して、このためのマルチレベルメニューを構築します。記事が各行の説明を含む1つの大きなコードに変わるのを防ぐために、以下に詳細なコメントを付けてコード自体を投稿します。ここでは、いくつかの主要なポイントについてのみ触れます。
メニューの作成
前回の記事では、ループfor
と選択演算子を使用して画面にメニューを表示し、必要な項目を選択しましたcase
。明らかに、マルチレベルメニューを作成するには、これらの手順を数回、つまりサブメニューごとに繰り返す必要があります。この場合、メニューヘッダー、外観などを再作成する必要があります。
良い、それを回避する方法-作るためにfor
、case
そしてread
別の関数(それを呼び出すでprints
)、その後、我々は、単に必要なパラメータに渡します。特定のメニュー項目が選択されたときに実行されるすべてのスクリプトも、対応する機能に転送されます。
したがって、スクリプトに新しいアクションを追加するには、次のようにします。
言語配列に単語やフレーズを追加する
メインメニューまたは追加メニューのある配列に、対応する項目と関数を呼び出すコマンドを挿入します
必要なコードフラグメントを含む関数を追加します
まず、メインメニューを作成しましょう。このメニューは、スクリプトを起動するとすぐに画面に表示されます。
menu0=("${lng[3]};main" "${lng[4]};gitadd" "${lng[5]};gitinit" "${lng[2]};options" "${lng[1]};exit")
: , ;
- , . , . , , .
main
:
main() {
#
local menu0=("${lng[3]};main" "${lng[4]};gitadd" "${lng[5]};gitinit" "${lng[2]};options" "${lng[1]};exit")
while true ; do
#
# ,
prints "menu0[@]" "${msg[1]}"
done
}
main
, options
:
options() {
local menu1=("${lng[2]};options" "${lng[7]} [$langset];langmenu" "${lng[1]};exit")
prints "menu1[@]" "${msg[1]}"
prints
, . , . cut
:
if [[ "$1" == "text" ]] ; then
#
echo "$2" | cut -d ";" -f 1
return
elif [[ "$1" == "command" ]] ; then
#
echo "$2" | cut -d ";" -f 2
return
fi
, , ${prints "text" "${menu[0]}"}
, - .
, : . colors
. ANSI escape ( echo -e
) 256 .
, , pwds
, . , .
, .
prints
. , :
local menu=("${!1}")
- . , , 1 :
pwds
colors "title" "---$(prints "text" "${menu[0]}")---"
for
,
, read
case
:
for (( op=1; op < "${#menu[@]}"; op++ )); do
colors "item" "$op ) $(prints "text" "${menu[$op]}")"
done
echo ----------
read -s -n1 -p "$(colors "item" "$2: ")" item
case $item in
[1-$((${#menu[@]}-1))] )
#
colors "ok" "[$item]->: $(prints "text" "${menu[$item]}")"
#
$(prints "command" "${menu[$item]}") ;;
# [q]
"q" ) echo; exit;;
#
* ) colors "err" "[$item]->: ${msg[2]}"; sleep 2 ;;
esac
. , .
, , , . langmenu
.
, . . , sed
language_
. language_ru
ru
:
# [-r] -
# [-n] - ,
local lng_sfx=($(sed -r -n "s/^\s?+language_(\w+)=.*/\1/p" "${0}"))
, , prints
. . langmenu
:
langmenu(){
local lng_sfx=($(sed -r -n "s/^\s?+language_(\w+)=.*/\1/p" "${0}"))
local menu2=("${lng[7]};langmenu")
for a in ${lng_sfx[@]} ; do
local d="language_$a[@]"; d=("${!d}")
menu2+=("$d;languages set $a")
done
menu2+=("${lng[1]};exit")
prints "menu2[@]" "${msg[6]}"
}
:
. ,
0
( ). : ,;
, ,languages
.
"English;languages set en"
,set en
-languages
.
prints
. ,
. sed
-i
-r
, -i
- () , -r
- .
: , langset=
langset=
:
sed -i -r "0,/^\s?+langset=/s/langset=[\"\']?\w*[\"\']?/langset=\"$langset\"/" "${0}"
exit
prints
. , , case
languages
, set
. languages
, . :
languages
if [ "$1" == "set" ] ; then
#
langset="$2"
local df="language_$langset"
echo
# ,
colors "ok" "${msg[7]} ${!df}. ${msg[8]}"
#
languages
# ,
colors "ok" "${msg[7]} ${lng[0]}. ${msg[8]}"
echo
# langset=
sed -i -r "0,/^\s?+langset=/s/langset=[\"\']?\w*[\"\']?/langset=\"$langset\"/" "${0}"
exit
fi
今回と前回の記事では、画面上のメニューとメッセージをさまざまな言語で表示する機能を備えた独自のスクリプトを作成するために使用できるテンプレートを作成しました。この場合、スクリプトは1つのファイルで構成され、新しい言語を追加するには、スクリプトの先頭に単語を含む配列を削除し、アクションを追加するだけで十分です。関数を作成してメニューに登録します。
最後まで読んでくれてありがとう。
コメント付きのすべてのコードは以下に添付されています。
コード全体
#!/bin/bash
#
langset="ru"
#
language_en=( "English" "Quit" "Options" "Main menu" "Git: add ALL files/commit" "Git init" "Change language" "Language selection" )
message_en=( "English" "Select item" "Wrong! This item does not exist" "Added all files" "Enter you commit" "Changes recorded" "Select a language" "The language has been changed to" "Start the program again" "Repository not found\nPlease, select Git init pepository" )
language_ru=( "" "" "" " " "Git: /" "" "" " " )
message_ru=( "" " " "! " " " " " " " " " " " " " " \n, , Git init" )
language_de=( "Deutsch" )
message_de=( "Deutsch" "" "" "" "" "" "" "" "Starten Sie das Programm neu" )
language_cn=( "中文" "出口" "设置" "主菜单")
message_cn=( "中文" "选择项目" "" "" "" "" "选择语言" "语言已改为" "重新启动程序" )
# Settings section
languages() {
#
#
lng="language_$langset[@]"; lng=("${!lng}")
msg="message_$langset[@]"; msg=("${!msg}")
#
for b in ${!language_en[@]} ${!message_en[@]} ; do
if [[ ! ${lng[$b]} ]] ; then
lng[$b]=${language_en[$b]}
fi
if [[ ! ${msg[$b]} ]] ; then
msg[$b]=${message_en[$b]}
fi
done
#
if [ "$1" == "set" ] ; then
#
langset="$2"
local df="language_$langset"
# ,
# ,
echo
colors "ok" "${msg[7]} ${!df}. ${msg[8]}"
#
languages
#
# ,
colors "ok" "${msg[7]} ${lng[0]}. ${msg[8]}"
echo
#
# langset=
# [-r] -
# [-i] -
# [0,] -
sed -i -r "0,/^\s?+langset=/s/langset=[\"\']?\w*[\"\']?/langset=\"$langset\"/" "${0}"
exit
fi
}
#
languages
colors() {
# . ,
# ,
# [48] - , [38] -
# [5] - 8- (0-255), [1] - ,
# [22] - , [0] -
case "$1" in
# : - ()
"tm" ) echo -e "\e[48;5;256;38;5;34;22m$2\e[0m" ;;
# : -, : ( )
"pt" ) echo -e "\e[48;5;24;38;5;15;1m$2\e[0m" ;;
# : - ( )
"cf" ) echo -e "\e[48;5;256;38;5;226;1m$2\e[0m" ;;
# : - ( )
"ok" ) echo -e "\e[48;5;256;38;5;34;1m$2\e[0m" ;;
# : ( )
"err" ) echo -e "\e[48;5;256;38;5;160;1m$2\e[0m" ;;
# : - ( )
"title" ) echo -e "\e[48;5;256;38;5;226;22m$2\e[0m" ;;
# : ( )
"item" ) echo -e "\e[48;5;256;38;5;15;22m$2\e[0m" ;;
esac
}
pwds() {
#
echo
echo ----------
echo "$(colors 'tm' "[$(date +"%T")]") $(colors 'pt' "${PWD%/*}"/)$(colors 'cf' "$(basename "$PWD")")"
echo ----------
}
prints() {
#
# , [;]
if [[ "$1" == "text" ]] ; then
echo "$2" | cut -d ";" -f 1
return
elif [[ "$1" == "command" ]] ; then
echo "$2" | cut -d ";" -f 2
return
fi
# ,
local menu=("${!1}")
#
pwds
# ,
# 1
colors "title" "---$(prints "text" "${menu[0]}")---"
#
for (( op=1; op < "${#menu[@]}"; op++ )); do
# ,
#
colors "item" "$op ) $(prints "text" "${menu[$op]}")"
done
echo ----------
# ,
read -s -n1 -p "$(colors "item" "$2: ")" item
#
case $item in
# 1 1 ( 0)
#
#
[1-$((${#menu[@]}-1))] ) colors "ok" "[$item]->: $(prints "text" "${menu[$item]}")"
# ,
#
$(prints "command" "${menu[$item]}") ;;
# [q]
"q" ) echo; exit;;
#
* ) colors "err" "[$item]->: ${msg[2]}"; sleep 2 ;;
esac
}
# Application section
gitinit() {
# : [git init]
git init
}
gitadd() {
# : [git add] -
git add .
# . [0]
#
if [[ "$?" != "0" ]] ; then
colors "err" "${msg[9]}"
sleep 1
return 1
fi
echo "${msg[3]} ..."
#
read -p "$(colors "item" "${msg[4]}: ")" comm
git commit -m "$comm"
#
colors "ok" "${msg[5]}"
}
# Menu section
langmenu() {
#
# ,
# [language_*]
# [-r] -
# [-n] - ,
local lng_sfx=($(sed -r -n "s/^\s?+language_(\w+)=.*/\1/p" "${0}"))
#
local menu2=("${lng[7]};langmenu")
# , ,
# 0 ( )
for a in ${lng_sfx[@]} ; do
local d="language_$a[@]"; d=("${!d}")
#
# ,
# [;], ,
# [languages] .
# ["English;languages set en"], [set en] - [languages]
menu2+=("$d;languages set $a")
done
#
menu2+=("${lng[1]};exit")
#
# ,
prints "menu2[@]" "${msg[6]}"
}
options() {
#
# ,
# [;], ,
local menu1=("${lng[2]};options" "${lng[7]} [$langset];langmenu" "${lng[1]};exit")
#
# ,
prints "menu1[@]" "${msg[1]}"
}
main() {
#
# ,
# [;], ,
# , , -
# ,
local menu0=("${lng[3]};main" "${lng[4]};gitadd" "${lng[5]};gitinit" "${lng[2]};options" "${lng[1]};exit")
while true ; do
#
# ,
prints "menu0[@]" "${msg[1]}"
done
}
main
exit 0