Localizando seus scripts no BASH, parte 2

Esta é uma continuação do artigo Localizando seus scripts no BASH . Nele, usando arrays e referências indiretas, aprendemos como adicionar linguagens adicionais aos nossos scripts e alternar entre eles.





Neste artigo, compilaremos uma lista de idiomas embutidos e definiremos a escolha do idioma por meio do menu, construindo um menu multinível para isso. Para evitar que o artigo se transforme em um grande pedaço de código com uma descrição de cada linha, irei postar o próprio código com comentários detalhados abaixo e aqui irei abordar apenas alguns pontos principais.





Criação de menu

No último artigo, usamos um loop for



e um operador de seleção para exibir um menu na tela e selecionar o item necessário case



. Obviamente, para criar um menu multinível, essas etapas precisarão ser repetidas várias vezes, ou seja, para cada submenu. Nesse caso, você terá que recriar o cabeçalho do menu, a aparência e assim por diante.





Uma boa maneira de evitá-lo - para fazer for



, case



e read



em uma função separada (chamá-lo prints



), e então vamos simplesmente passá-lo para os parâmetros necessários. Todos os scripts que serão executados quando certos itens de menu forem selecionados também serão transferidos para as funções correspondentes.





Portanto, para adicionar uma nova ação ao script:





  • adicione palavras e frases ao conjunto de idiomas





  • na matriz com o menu principal ou adicional, insira o item correspondente e o comando para chamar a função





  • adicione uma função com o fragmento de código necessário





Primeiro, vamos criar um menu principal, que aparecerá imediatamente na tela quando o script for iniciado:





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
      
      



Esta é a aparência deste menu.

. , .





, , , . 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]}"
}
      
      



:









  1. . , 0



    ( ). : , ;



    , , languages



    .



    "English;languages set en"



    , set en



    - languages



    .









  2. prints



    . ,





Menu de seleção de idioma

. 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
      
      



Configurando o idioma

Neste artigo e no anterior , criamos um modelo que você pode usar para escrever seus próprios scripts com a capacidade de exibir menus na tela e mensagens em diferentes idiomas. Nesse caso, o script consiste em um arquivo e para adicionar um novo idioma basta soltar o array com palavras no início do script e adicionar qualquer ação - crie uma função e registre-a no menu.





Obrigado por ler até o fim.





Todo o código com comentários está anexado abaixo.





Todo o código
#!/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
      
      










All Articles