Administração de VirtualBox com ShellScript
Publicado por Ricardo Lino Olonca (última atualização em 25/08/2012)
[ Hits: 8.532 ]
Homepage: ricardoolonca.blogspot.com.br
Administração de máquina virtuais através de Shell Script usando Dialog. Inclui criação, manutenção, importação e exportação de máquinas virtuais; criação, manutenção e importação de discos e dvd virtuais; administração de snapshot; administração de até quatro interfaces de rede, número de cpus, quantidade de memória ram e de video, entre outros. Possui uma interface de menus.
Esse script foi feito para demonstrar como um script bash combinado com Dailog pode ser muito útil e conter uma aparência bem amigável.
#!/bin/bash
# Administra um servidor VirtualBox através da linha de comando
# Feito por Ricardo Lino Olonca em 22/08/2012
# Versao 0
# Checa se todas as dependências estão satisfeitas
function depend(){
erro=0
which dialog 2>/dev/null >/dev/null
if [ $? -ne 0 ]
then
echo O programa dialog não está instalado.
echo 'Tente instalar o pacote dialog através do gerenciador de pacotes da tua distribuição Linux.'
return 1
else
which VBoxManage 2>/dev/null >/dev/null
if [ $? -ne 0 ]
then
dialog \
--title 'Falta de dependência' \
--msgbox 'O programa VBoxManager não está instalado.\nTente instalar o pacote virtualbox-ose através do gerenciador de pacotes da tua distribuição Linux.'\
6 40
return 2
else
if [ ! -e /dev/vboxdrv ]
then
dialog \
--title 'Falta de dependência' \
--msgbox 'Está faltando o módulo do kernel para o VirtualBox.\nTente instalar o pacote virtualbox-ose-dkms através do gerenciador de pacotes da tua distribuição Linux.'\
6 40
return 3
fi
fi
fi
}
# Lista as máquinas virtuais
function listarvm(){
echo 'dialog --stdout \' > $$.listar.tmp
echo '--title "Listagem das máquina virtuais" \' >> $$.listar.tmp
echo '--menu "Escolha a máquina virtual:" \' >> $$.listar.tmp
echo '0 0 0 \' >> $$.listar.tmp
rodando=$(VBoxManage list runningvms | grep ^\" | cut -d"\"" -f2)
for i in `VBoxManage list vms | grep ^\" | cut -d"\"" -f2`
do
echo $rodando | grep $i > /dev/null
if [ $? == 0 ]
then
echo "$i" "Executando..." \\ >> $$.listar.tmp
else
echo "$i" "Desligada" \\ >> $$.listar.tmp
fi
done
chmod +x $$.listar.tmp >> /dev/null
}
# Configura o acesso via vnc na máquina virtual que sobe em segundo plano
function segundo_plano(){
while true
do
porta=$( dialog --stdout \
--inputbox 'Porta de conexão remota ("0" para desabilitar o recurso):' 0 0 5900 )
if [ -z $porta ]
then
break
elif [ $porta -eq 0 ]
then
VBoxHeadless -s $1 >> /dev/null 2>>/dev/null &
break
elif [ $porta -gt 1023 ] && [ $porta -lt 65536 ]
then
netstat -na | grep 0.0.0.0:$porta >> /dev/null
if [ $? -eq 0 ]
then
dialog \
--title 'Porta em uso' \
--msgbox 'A porta está em uso. Escolha outra porta.'\
6 40
else
senha=$(dialog --stdout \
--title 'Senha de acesso' \
--passwordbox 'Digite a senha de acesso (deixe em branco ou cancele se não quiser senha):' \
0 0 )
if [ -z $senha ]
then
VBoxHeadless -s $1 -n -m $porta >> /dev/null 2>>/dev/null &
else
VBoxHeadless -s $1 -n -m $porta -o $senha >> /dev/null 2>>/dev/null &
fi
break
fi
else
dialog \
--title 'Porta inválida' \
--msgbox 'A porta deve ser um número entre 1024 e 65535.'\
6 40
fi
done
}
# Para, pausa e desliga a máquina virtual
function parar(){
while true
do
case "$2" in
"running")
parar=$( dialog --stdout \
--title "Administração da máquina $1" \
--menu "Opções: " \
0 0 0 \
Pausa 'Congela a VM' \
Reset 'Reinicia a VM "a força"' \
Desligar 'Desliga a VM "a força"' \
Salvar 'Faz a VM hibernar' \
Acpi 'Tenta desligar a VM de modo seguro')
case $parar in
"Pausa")
VBoxManage controlvm $1 pause >> /dev/null
sleep 3
return
;;
"Reset")
VBoxManage controlvm $1 reset >> /dev/null
return
;;
"Desligar")
VBoxManage controlvm $1 poweroff >> /dev/null
sleep 3
return
;;
"Salvar")
VBoxManage controlvm $1 savestate >> /dev/null 2 >>/dev/null
sleep 3
return
;;
"Acpi")
VBoxManage controlvm $1 acpipowerbutton >> /dev/null 2 >>/dev/null
dialog \
--sleep 5 \
--title "Aguarde a VM $1 desligar" \
--infobox 'Dependendo a máquina, isso pode demorar um pouco...' \
0 0
return
;;
*)
return
;;
esac
;;
"paused" | "stopping")
parar=$( dialog --stdout \
--title "Administração da máquina $1" \
--menu "Opções: " \
0 0 0 \
Continuar 'Continuar a VM' \
Desligar 'Desliga a VM "a força"')
case $parar in
"Continuar")
VBoxManage controlvm $1 resume >> /dev/null
sleep 3
return
;;
"Desligar")
VBoxManage controlvm $1 poweroff >> /dev/null
sleep 3
return
;;
*)
return
;;
esac
;;
"powered" | "saved" | "aborted")
parar=$( dialog --stdout \
--title "Administração da máquina $1" \
--menu "Opções: " \
0 0 0 \
Backgroud "Iniciar a VM $1 em segundo plano" \
Gui "Inicia a VM $1 em uma janela normal" \
Sdl "Iniciar a VM $1 em uma janela minimalista" )
case $parar in
"Backgroud")
segundo_plano $1
sleep 3
;;
"Gui")
VBoxManage startvm $1 --type gui >>/dev/null 2>>/dev/null &
sleep 3
return
;;
"Sdl")
VBoxManage startvm $1 --type sdl >>/dev/null 2>>/dev/null &
sleep 3
return
;;
*)
return
;;
esac
;;
*)
break
;;
esac
done
}
# Exporta uma máquina virtual
function exportarvm(){
while true
do
arquivo=$(dialog --stdout \
--title 'Escolha o nome do arquivo (sem a extensão)' \
--inputbox 'Nome:' 0 0 "vm_exportada" )
if [ -z $arquivo ]
then
break
elif [ -f $arquivo.ovf ]
then
dialog \
--title 'Arquivo existe' \
--msgbox "O arquivo $arquivo já existe." \
6 40
else
touch $$.out
echo 'VBoxManage export ' $1 '-o ' $arquivo.ovf '> '$$.out > $$.export.tmp
echo "rm $$.out" >> $$.export.tmp
bash $$.export.tmp &
sleep 3
while true
do
if [ -f $$.out ]
then
dialog \
--title 'Exportanto a vm' \
--sleep 1 \
--infobox `tail -1 $$.out | grep ^0` \
0 0
else
break
rm $$.export.sh
fi
done
fi
done
}
# Cria um snapshot da máquina virtual
function criarsnapshot(){
nome=$(dialog --stdout \
--title 'Escolha o nome do snapshot' \
--inputbox 'Nome:' 0 0 "Snapshot1" )
if [ -z $nome ]
then
echo > /dev/null
else
grep ^Snapshot $$.detalhes.tmp | grep $nome
if [ $? -eq 0 ]
then
dialog \
--title 'Snapshot já existe' \
--msgbox 'Já existe um snapshot com esse nome' \
16 40
else
VBoxManage snapshot $1 take $nome
if [ $? -ne 0 ]
then
dialog \
--title 'Erro!' \
--msgbox 'Houve um erro na criação do snapshot' \
16 40
fi
fi
fi
break
}
# Administração de snapshot
function snapshot(){
while true
do
echo 'dialog --stdout \' > $$.snap.tmp
echo '--title "Snapshot" \' >> $$.snap.tmp
echo '--menu "Escolha a ação" \' >> $$.snap.tmp
echo '0 0 0 \' >> $$.snap.tmp
for i in $snap
do
echo $i Snapshot \\ >> $$.snap.tmp
done
echo 'Novo "Criar um novo snapshot"' >> $$.snap.tmp
chmod +x $$.snap.tmp
opcao=$(./$$.snap.tmp)
if [ -z $opcao ]
then
break
elif [ $opcao == "Novo" ]
then
criarsnapshot $1
else
manutsnapshot=$( dialog --stdout \
--title "Administração do snapshot $opcao" \
--menu "Opções: " \
0 0 0 \
Apagar 'Apagar este snapshot' \
Restaurar 'Restaurar este snapshot')
case $manutsnapshot in
"Apagar")
if [ "${valor[5]}" = "powered" ]
then
VBoxManage snapshot $1 delete $opcao 2>/dev/null >/dev/null
else
dialog \
--title 'Desligue o servidor' \
--msgbox 'É necessário desligar o servidor virtual antes de apagar o snapshot' \
10 40
fi
break
;;
"Restaurar")
if [ "${valor[5]}" = "powered" ]
then
VBoxManage snapshot $1 restore $opcao 2>/dev/null >/dev/null
else
dialog \
--title 'Desligue o servidor' \
--msgbox 'É necessário desligar o servidor virtual antes de efetuar o restore do snapshot' \
10 40
fi
;;
*)
break
;;
esac
fi
done
}
# Escolhendo a interface que fará bridge
function lanbridged(){
echo 'dialog --stdout \' > $$.lanbridged.tmp
echo '--title "Lan real ' "$1" '" \' >> $$.lanbridged.tmp
echo '--menu "Escolha a interface de rede real:" \' >> $$.lanbridged.tmp
echo '0 0 0 \' >> $$.lanbridged.tmp
for i in `ifconfig -a | grep Link\ encap | awk '{print $1}'`
do
ip=`ifconfig $i | grep Bcast | awk '{print $4}' | cut -d":" -f2`
if [ -z $ip ]
then
echo
else
echo $i `ifconfig $i | grep Bcast | awk '{print $4}' | cut -d":" -f2` ' \'>> $$.lanbridged.tmp
fi
done
chmod +x $$.lanbridged.tmp
lanreal=$( ./$$.lanbridged.tmp )
# if [ -z $lanreal ]
# then
echo $lanreal
# else
# VBoxManage modifyvm $1 --nic$lan bridged --bridgeadapter$2 $lanreal >> /dev/null 2>>/dev/null
# fi
}
# Configuração do cd na máquina virtual
function confcddvd(){
listarcddvd
echo Nenhum \'Retirar o Cd/Dvd\' '\' >> $$.cdv.tmp
cdv=$( ./$$.cdv.tmp )
if [ -z $cdv ]
then
break
elif [ $cdv == "Nenhum" ]
then
VBoxManage storageattach $1 --storagectl "Controladora IDE" --port 1 --device 0 --type dvddrive --medium emptydrive > /dev/null 2>/dev/null
elif [ $cdv == "Cd_local" ]
then
VBoxManage storageattach $1 --storagectl "Controladora IDE" --port 1 --device 0 --type dvddrive --medium host:/dev/cdrom > /dev/null 2>/dev/null
elif [ $cdv == "Novo" ]
then
importarcddvd
if [ -n $arquivo ]
then
VBoxManage storageattach $1 --storagectl "Controladora IDE" --port 1 --device 0 --type dvddrive --medium $arquivo > /dev/null 2>/dev/null
fi
else
caminho=`VBoxManage list dvds | grep $cdv | awk '{print $2}'`
VBoxManage storageattach $1 --storagectl "Controladora IDE" --port 1 --device 0 --type dvddrive --medium $caminho > /dev/null 2>/dev/null
fi
}
# Configuração da rede
function confrede(){
rede=$( dialog --stdout \
--title "Tipo de rede" \
--menu "Defina o tipo de rede. (Você não pode adicionar ou retirar interfaces com a máquina ligada)." \
0 0 0 \
Nat 'A vm acessa tudo, mas ninguém acessa ela' \
Bridged 'A vm terá um ip da vlan real' \
Interna 'Rede apenas internamente, sem comunicação com a rede real' \
Hostonly 'A vm será acessada via roteamento para a interface virtual vboxnet0' \
None 'Cabo de rede desconectado' \
Ajuda 'Ajuda sobre as opções acima' )
}
# Tela de ajuda na configuração de rede
function ajudarede(){
echo 'Com Nat, a máquina virtual vai funcionar como uma aplicação na máquina real. Ela conseguirá acessar todo o mundo' > $$.ajuda.tmp
echo 'externo com o ip da máquina real. Porém ninguém conseguirá acessá-la.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'Com Bridged, a máquina virtual vai ganhar um ip da rede local, acessará o mundo externo por esse ip, e todo' >> $$.ajuda.tmp
echo 'poderão de conectar nela através desse endereço. Em outras palavras, ela será vista como uma máquina normal da' >> $$.ajuda.tmp
echo 'rede local. Você terá que escolher em qual placa de rede real a máquina virtual estará pendurada.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'Com Interna, a máquina virtual terá acesso apenas a uma rede virtual que funciona apenas internamente na máquina' >> $$.ajuda.tmp
echo 'real. Ela poderá se comunicar com outras máquina virtuais que também tenham acesso a essa rede virtual.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'Com Hostonly, a máquina ganhará um ip na rede virtual 192.168.56.0/24. A máquina real tem uma interface virtual' >> $$.ajuda.tmp
echo 'com ip 192.168.56.1, que deverá ser o gateway padrão da máquina virtual. Em outras palavras, a máquina real' >> $$.ajuda.tmp
echo 'atuará como um roteador, sendo necessário regras de firewall e/ou nat para que a máquina virtual possa' >> $$.ajuda.tmp
echo 'comunicar com a rede real. As máquinas da rede real poderão se conectar a essa máquina virtual configurando' >> $$.ajuda.tmp
echo 'rotas específicas, ou através de nat.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'None, desabilita a rede. É semelhante a retirar a placa de rede da máquina virtual.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
dialog \
--title 'Ajuda das opções de rede' \
--textbox $$.ajuda.tmp \
0 0
}
# Gerenciamento de uma máquina virtual específica.
function detalhes_vm(){
while true
do
unset snap
VBoxManage showvminfo $1 > $$.detalhes.tmp
detalhes[1]='Sistema'
valor[1]=`grep 'Guest OS:' $$.detalhes.tmp | awk '{print $3 $4 $5 $6 $7 $8 $9}'`
detalhes[2]='Memória'
valor[2]=`grep 'Memory size:' $$.detalhes.tmp | awk '{print $3}'`
detalhes[3]='Vídeo'
valor[3]=`grep 'VRAM size:' $$.detalhes.tmp | awk '{print $3}'`
detalhes[4]='Cpu'
valor[4]=`grep 'Number of CPUs:' $$.detalhes.tmp | awk '{print $4}'`
detalhes[5]='Status'
valor[5]=`grep 'State:' $$.detalhes.tmp | awk '{print $2}'`
detalhes[6]='Rede\ 1'
valor[6]=`grep 'NIC 1:' $$.detalhes.tmp | awk '{print $6" "$8" "$9" "$10" "$11}' | cut -d"," -f1-2`
detalhes[7]='Rede\ 2'
valor[7]=`grep 'NIC 2:' $$.detalhes.tmp | awk '{print $6" "$8" "$9" "$10" "$11}' | cut -d"," -f1-2`
detalhes[8]='Rede\ 3'
valor[8]=`grep 'NIC 3:' $$.detalhes.tmp | awk '{print $6" "$8" "$9" "$10" "$11}' | cut -d"," -f1-2`
detalhes[9]='Rede\ 4'
valor[9]=`grep 'NIC 4:' $$.detalhes.tmp | awk '{print $6" "$8" "$9" "$10" "$11}' | cut -d"," -f1-2`
detalhes[10]='Audio'
valor[10]=`grep 'Audio:' $$.detalhes.tmp | cut -d"(" -f2 | cut -d")" -f1`
detalhes[11]='Cd/Dvd'
valor[11]=`grep ^Controladora\ IDE $$.detalhes.tmp | awk '{print $5}' | head -1`
detalhes[12]='HD'
valor[12]=`grep ^Controladora\ SATA $$.detalhes.tmp | awk '{print $5}' | head -1`
detalhes[13]='Boot'
valor[13]=`grep ^Boot\ Device $$.detalhes.tmp | head -1 | cut -d" " -f4`
detalhes[14]='Snapshot'
for i in `grep -A 100 ^Snapshot $$.detalhes.tmp | grep Name |awk '{print $2}'`
do
snap=`echo -n $snap\ $i`
done
valor[14]=$snap
detalhes[15]='Exportar'
valor[15]='Exportar a máquina virtual'
detalhes[16]='Excluir'
valor[16]='Excluir a máquina virtual'
menu_detalhes=0
echo 'dialog --stdout \' > $$.detalhes.tmp
echo '--title "VM ' "$1" '" \' >> $$.detalhes.tmp
echo '--menu "Escolha o item para alterar:" \' >> $$.detalhes.tmp
echo '0 0 0 \' >> $$.detalhes.tmp
for i in `seq 16`
do
echo "${detalhes[$i]}" "'""${valor[$i]}" "'" ' \'>> $$.detalhes.tmp
done
chmod +x $$.detalhes.tmp >> /dev/null
menu_detalhes=$( ./$$.detalhes.tmp )
if [ -z "$menu_detalhes" ]
then
break
else
if [ "${valor[5]}" != "powered" ]
then
case $menu_detalhes in
"Status")
parar "$1" "${valor[5]}"
;;
"Rede 1"|"Rede 2"|"Rede 3"|"Rede 4")
lan=`echo $menu_detalhes | cut -d" " -f2`
confrede
case $rede in
"Nat")
VBoxManage controlvm $1 nic$lan nat >> /dev/null 2>>/dev/null
VBoxManage controlvm $1 setlinkstate$lan on >>/dev/null 2>>/dev/null
;;
"Bridged")
lanreal=`lanbridged $1`
VBoxManage controlvm $1 nic$lan bridged $lanreal setlinkstate$lan on >> /dev/null 2>>/dev/null
;;
"Interna")
VBoxManage controlvm $1 nic$lan intnet intnet setlinkstate$lan on >> /dev/null 2>>/dev/null
VBoxManage controlvm $1 setlinkstate$lan on >>/dev/null 2>>/dev/null
;;
"Hostonly")
VBoxManage controlvm $1 nic$lan hostonly vboxnet0 setlinkstate$lan on >> /dev/null 2>>/dev/null
VBoxManage controlvm $1 setlinkstate$lan on >>/dev/null 2>>/dev/null
;;
"None")
VBoxManage controlvm $1 setlinkstate$lan off >> /dev/null 2>>/dev/null
;;
"Ajuda")
ajudarede
;;
*)
break
;;
esac
;;
"Cd/Dvd")
confcddvd $1
;;
"Snapshot")
snapshot $1
;;
*)
dialog \
--title 'Máquina em execução' \
--msgbox 'A máquina virtual precisa estar parada para que essa opção possa ser alterada' \
10 40
;;
esac
else
case $menu_detalhes in
"Status")
parar "$1" "${valor[5]}"
;;
"Sistema")
tiposistema
sistema=$( ./$$.sistema.tmp )
if [ -n $sistema ]
then
VBoxManage modifyvm $1 --ostype $sistema >> /dev/null 2>>/dev/null
fi
;;
"Memória")
echo 'dialog --stdout \' > $$.sistema.tmp
echo '--title "Memória Ram" \' >> $$.sistema.tmp
echo '--menu "Defina o valor da memória Ram da VM:" \' >> $$.sistema.tmp
echo '0 0 0 \' >> $$.sistema.tmp
x=$((`free | grep Mem | awk '{print $2}'` / 4096))
i=0
mem=16
while [ $x -gt $mem ]
do
i=$(($i + 1))
mem=$(($mem * 2))
for i in 0 1 2 3
do
mem1=$(($mem / 4 * $i))
mem2=$(($mem + mem1))
echo $mem2 'MB \' >> $$.sistema.tmp
done
done
chmod +x $$.sistema.tmp
sistema=$( ./$$.sistema.tmp )
if [ -n $sistema ]
then
VBoxManage modifyvm $1 --memory $sistema >> /dev/null 2>>/dev/null
fi
;;
"Vídeo")
echo 'dialog --stdout \' > $$.sistema.tmp
echo '--title "Memória de vídeo" \' >> $$.sistema.tmp
echo '--menu "Defina o valor da memória de Vídeo:" \' >> $$.sistema.tmp
echo '0 0 0 \' >> $$.sistema.tmp
x=$((`free | grep Mem | awk '{print $2}'` / 20480))
i=0
mem=4
while [ $x -gt $mem ]
do
i=$(($i + 1))
mem=$(($mem * 2))
echo $mem 'MB \' >> $$.sistema.tmp
done
chmod +x $$.sistema.tmp
sistema=$( ./$$.sistema.tmp )
if [ -n $sistema ]
then
VBoxManage modifyvm $1 --vram $sistema >> /dev/null 2>>/dev/null
fi
;;
"Cpu")
echo 'dialog --stdout \' > $$.sistema.tmp
echo '--title "Número de processadores" \' >> $$.sistema.tmp
echo '--menu "Defina o número de processadores:" \' >> $$.sistema.tmp
echo '0 0 0 \' >> $$.sistema.tmp
x=$((`grep processor /proc/cpuinfo | wc -l`))
for i in `seq $x`
do
echo $i 'Cpu\(s\) \' >> $$.sistema.tmp
done
chmod +x $$.sistema.tmp
sistema=$( ./$$.sistema.tmp )
if [ -n $sistema ]
then
VBoxManage modifyvm $1 --cpus $sistema --ioapic on >> /dev/null 2>>/dev/null
fi
;;
"Rede 1"|"Rede 2"|"Rede 3"|"Rede 4")
lan=`echo $menu_detalhes | cut -d" " -f2`
confrede
case $rede in
"Nat")
VBoxManage modifyvm $1 --nic$lan nat >> /dev/null 2>>/dev/null
;;
"Bridged")
lanreal=`lanbridged $1`
VBoxManage modifyvm $1 --nic$lan bridged --bridgeadapter$lan $lanreal >> /dev/null 2>>/dev/null
;;
"Interna")
VBoxManage modifyvm $1 --nic$lan intnet >> /dev/null 2>>/dev/null
;;
"Hostonly")
VBoxManage modifyvm $1 --nic$lan hostonly --hostonlyadapter$lan vboxnet0 >> /dev/null 2>>/dev/null
;;
"None")
VBoxManage modifyvm $1 --nic$lan none >> /dev/null 2>>/dev/null
;;
"Ajuda")
ajudarede
;;
*)
break
;;
esac
;;
"Audio")
som=`VBoxManage showvminfo $1 | grep Audio | awk '{print $2}'`
if [ $som == "enabled" ]
then
VBoxManage modifyvm $1 --audio none > /dev/null 2>/dev/null
else
VBoxManage modifyvm $1 --audio alsa > /dev/null 2>/dev/null
fi
;;
"Cd/Dvd")
confcddvd $1
;;
"Boot")
boot=$( dialog --stdout \
--title "Boot por" \
--menu "Opções: " \
0 0 0 \
HD 'Primeiro hd' \
CD 'Drive de cd/dvd')
if [ $boot == "HD" ]
then
VBoxManage modifyvm $1 --boot1 disk >/dev/null 2>/dev/null
elif [ $boot == "CD" ]
then
VBoxManage modifyvm $1 --boot1 dvd >/dev/null 2>/dev/null
fi
;;
"Snapshot")
snapshot $1
;;
"HD")
listarhd
echo 'Nenhum' \'Sem nenhum disco\' '\' >> $$.cdv.tmp
hd=$( ./$$.cdv.tmp)
if [ -z $hd ]
then
echo . >> /dev/null
elif [ $hd == "Novo" ]
then
novohd $1
if [ $? == 0 ]
then
VBoxManage storageattach $1 --storagectl "Controladora SATA" --port 0 --device 0 --type hdd --medium ~/.VirtualBox/HardDisks/$hd >/dev/null 2>/dev/null
fi
elif [ $hd == "Nenhum" ]
then
VBoxManage storageattach $1 --storagectl "Controladora SATA" --port 0 --device 0 --type hdd --medium none >/dev/null 2>/dev/null
else
VBoxManage storageattach $1 --storagectl "Controladora SATA" --port 0 --device 0 --type hdd --medium ~/.VirtualBox/HardDisks/$hd >/dev/null 2>/dev/null
fi
;;
"Exportar")
exportarvm $1
;;
"Excluir")
dialog \
--title "AVISO \!\!\!" \
--yesno "Deseja realmente excluir a vm $1 ? Isso apagará todos os snapshot desta VM." \
0 0
if [ $? -eq 0 ]
then
VBoxManage storagectl $1 --name "Controladora SATA" --remove > /dev/null 2>/dev/null
VBoxManage storagectl $1 --name "Controladora IDE" --remove > /dev/null 2>/dev/null
for i in `VBoxManage showvminfo $1 | grep -A 100 -i snapshot | grep Name | awk '{print $2}'`
do
VBoxManage snapshot $1 delete $i 2>/dev/null >/dev/null
done
VBoxManage unregistervm $1 --delete >> /dev/null 2>>/dev/null
return
fi
;;
esac
fi
fi
done
}
# Importa uma vm
function importarvm(){
while true
do
arquivo=$( dialog --stdout \
--title 'Selecione o arquivo' \
--fselect ~ \
10 55)
if [ -z $arquivo ]
then
break
elif [ -f $arquivo ]
then
VBoxManage import $arquivo 2>/dev/null >/dev/null
break
else
dialog \
--title 'Arquivo não existe' \
--msgbox "O arquivo $arquivo não existe." \
6 40
fi
done
}
# Escolha do tipo de sistema operacional da nova máquina virtual
function tiposistema(){
echo 'dialog --stdout \' > $$.sistema.tmp
echo '--title "Tipo de sistema operacional" \' >> $$.sistema.tmp
echo '--menu "Escolha o sistema operacional:" \' >> $$.sistema.tmp
echo '0 0 0 \' >> $$.sistema.tmp
VBoxManage list ostypes | grep ^ID | cut -d":" -f2 | sed s/" "/""/g | grep -v ^$ > $$.id.tmp
VBoxManage list ostypes | grep ^Description | cut -d":" -f2 | sed s/" "/""/g | grep -v ^$ > $$.desc.tmp
paste $$.id.tmp $$.desc.tmp | sed 's/$/ \\/g' | sed s/'('/"_"/g | sed s/')'/""/g >> $$.sistema.tmp
chmod +x $$.sistema.tmp
}
# Criação de uma nova vm
function novavm(){
while true
do
nomevm="$( dialog --stdout \
--inputbox 'Nome da nova vm:' 0 0 )"
if [ -z $nomevm ]
then
break
else
nomevm=$(echo "$nomevm" | sed s/" "//g | sed s/[^a-zA-Z0-9]//g)
VBoxManage list vms | grep \"$nomevm\" >> /dev/null 2>>/dev/null
if [ $? -eq 0 ]
then
dialog \
--title 'Crição de vm' \
--msgbox 'Já existe uma vm com este nome'\
6 40
else
tiposistema
sistema=$( ./$$.sistema.tmp )
if [ -n $sistema ]
then
VBoxManage createvm --name $nomevm --ostype $sistema >> /dev/null 2>>/dev/null
VBoxManage registervm $HOME/.VirtualBox/Machines/$nomevm/$nomevm.xml >> /dev/null 2>>/dev/null
else
VBoxManage createvm --name $nomevm >> /dev/null 2>>/dev/null
VBoxManage registervm $HOME/.VirtualBox/Machines/$nomevm/$nomevm.xml >> /dev/null 2>>/dev/null
fi
VBoxManage storagectl $nomevm --name "Controladora SATA" --add sata > /dev/null 2>/dev/null
VBoxManage storagectl $nomevm --name "Controladora IDE" --add ide > /dev/null 2>/dev/null
break
fi
fi
done
}
# Gerencia as máquinas virtuais
function listar(){
while true
do
listarvm
echo "Nova 'Criar uma nova máquina virtual' \\" >> $$.listar.tmp
echo "Importar 'Importar uma máquina virtual' " >> $$.listar.tmp
menu_listar=$(./$$.listar.tmp)
if [ -z $menu_listar ]
then
break
else
case $menu_listar in
"Nova")
novavm
;;
"Importar")
importarvm
;;
*)
detalhes_vm $menu_listar
;;
esac
fi
done
}
# Lista os discos virtuais
function listarhd(){
echo 'dialog --stdout \' > $$.cdv.tmp
echo '--title "Hd virtual" \' >> $$.cdv.tmp
echo '--menu "Escolha o hd virtual:" \' >> $$.cdv.tmp
echo '0 0 0 \' >> $$.cdv.tmp
VBoxManage list hdds | grep Location | grep -v Snapshot | awk '{print $2}' | cut -d"/" -f6 > $$.cdv2.tmp
for i in `cat $$.cdv2.tmp`
do
usado_por=`VBoxManage list hdds | grep -A3 $i | grep Usage | awk '{print $2}'`
if [ "a$usado_por" == "a" ]
then
echo $i \'Sem uso\' '\' >> $$.cdv.tmp
else
echo $i \'Usado por $usado_por\' '\' >> $$.cdv.tmp
fi
done
echo 'Novo' \'Criar um novo disco\' '\' >> $$.cdv.tmp
chmod +x $$.cdv.tmp
}
# Cria um novo disco virtual
function novohd(){
while true
do
criarnovohd
if [ -z $arquivo ]
then
break
elif [ -f ~/.VirtualBox/HardDisks/$arquivo.vdi ]
then
dialog \
--title 'Arquivo já existe' \
--msgbox 'O arquivo já existe.'\
6 40
else
echo 'dialog --stdout \' > $$.sistema.tmp
echo '--title "Tamanho do disco" \' >> $$.sistema.tmp
echo '--menu "Defina o tamanho do disco:" \' >> $$.sistema.tmp
echo '0 0 0 \' >> $$.sistema.tmp
x=$((`df -hm /home | tail -1 | awk '{print $4}'`))
i=0
tam=40
while [ $x -gt $tam ]
do
i=$(($i + 1))
tam=$(($tam * 2))
for i in 0 1 2 3
do
tam1=$(($tam / 4 * $i))
tam2=$(($tam + $tam1))
echo $tam2 'MB \' >> $$.sistema.tmp
done
done
chmod +x $$.sistema.tmp
tamanho=$( ./$$.sistema.tmp )
if [ -z $sistema ]
then
VBoxManage createhd --filename $arquivo.vdi --size $tamanho >/dev/null 2>/dev/null
VBoxManage openmedium disk ~/.VirtualBox/HardDisks/$arquivo.vdi >/dev/null 2>/dev/null
VBoxManage storageattach $1 --storagectl "Controladora SATA" --port 0 --device 0 --type hdd --medium ~/.VirtualBox/HardDisks/$arquivo.vdi >/dev/null 2>/dev/null
hd=$arquivo.vdi
listarhd
return 0
fi
fi
done
}
# Exclui uma hd virtual
function excluirhd(){
dialog \
--title 'AVISO!!!' \
--yesno 'Deseja realmente excluir PERMANENTEMENTE o disco virtual?' \
0 0
if [ $? -eq 0 ]
then
VBoxManage closemedium disk ~/.VirtualBox/HardDisks/$hd 2>/dev/null >/dev/null
rm -f ~/.VirtualBox/HardDisks/$hd
fi
}
# Retira um determinado hd de todas as vm
function nenhumhd(){
for i in `VBoxManage list vms | grep ^\" | cut -d"\"" -f2`
do
VBoxManage showvminfo $i | grep $1 2>/dev/null >/dev/null
if [ $? == 0 ]
then
VBoxManage storageattach $i --storagectl "Controladora SATA" --port 0 --device 0 --type hdd --medium none
fi
done
}
# Pede o nome de um novo hd
function criarnovohd(){
arquivo=$(dialog --stdout \
--title 'Escolha o nome do novo disco virtual' \
--inputbox 'Nome:' 0 0 "Novo_disco" )
}
# Clona um hd virtual
function clonar(){
while true
do
criarnovohd
if [ -z $arquivo ]
then
break
elif [ -f ~/.VirtualBox/HardDisks/$arquivo ]
then
dialog \
--title 'Arquivo existe' \
--msgbox "O arquivo $arquivo já existe." \
6 40
else
VBoxManage clonehd ~/.VirtualBox/HardDisks/$hd ~/.VirtualBox/HardDisks/$arquivo >/dev/null 2>/dev/null
VBoxManage openmedium disk ~/.VirtualBox/HardDisks/$arquivo >/dev/null 2>/dev/null
break
fi
done
}
# Manutenção em hd virtual
function hd(){
while true
do
hd=$( ./$$.cdv.tmp)
if [ -z $hd ]
then
return
elif [ $hd == "Novo" ]
then
novohd
else
id=`VBoxManage list hdds | grep -B3 $hd | head -1 | awk '{print $2}'`
VBoxManage showhdinfo $id | tail -8 > $$.id.tmp
dialog \
--title 'Detalhes do disco virtual' \
--tailbox $$.id.tmp \
0 0
acao=$( dialog --stdout \
--title "Ação no disco" \
--menu "Escolha o tipo de ação no disco:" \
0 0 0 \
'Compactar' 'Compactar o hd virtual' \
'Clonar' 'Copiar um disco disco' \
'Excluir' 'Excluir o disco virtual' \
'Associar' 'Associar a uma máquina virtual' \
'Ajuda' 'Breve explicação sobre os menus acima')
case $acao in
"Compactar")
VBoxManage modifyhd $id --compact > $$.compact.tmp &
sleep 1
grep ^0%... $$.compact.tmp
if [ $? -eq 0 ]
then
ps wax | grep $id | grep -v grep 2>/dev/null >/dev/null
while [ $? -eq 0 ]
do
per=`grep ^0 $$.compact.tmp`
dialog \
--title 'Compactando o disco virtual' \
--infobox $per \
0 0
sleep 1
ps wax | grep $id | grep -v grep 2>/dev/null >/dev/null
done
else
dialog \
--title 'Não é possível compactar o disco' \
--msgbox 'Não foi possível compactar o disco. Certifique-se de que ele não esteja em uso por alguma máquina virtual no momento.'\
6 40
fi
;;
"Clonar")
clonar
;;
"Excluir")
VBoxManage list hdds | grep -A3 $hd | grep Usage 2>/dev/null >/dev/null
if [ $? == 0 ]
then
dialog \
--title 'Não é possível excluir o disco' \
--msgbox 'Este disco está associado a uma máquina vitual. Antes de excluí-lo, é necessário retirá-lo da vm.'\
6 40
else
excluirhd
fi
;;
"Associar")
listarvm
vm=$( ./$$.listar.tmp )
if [ -z $vm ]
then
break
elif [ $vm == "Nenhum" ]
then
nenhumhd $hd
else
VBoxManage storageattach $vm --storagectl "Controladora SATA" --port 0 --device 0 --type hdd --medium ~/.VirtualBox/HardDisks/$hd 2>/dev/null >/dev/null
fi
break
;;
"Ajuda")
echo 'O menu Comptactar é usado para reorganizar o disco virtual, diminuindo o espaço real dele.' > $$.ajuda.tmp
echo 'É aconselhado fazer isso quando muitos arquivos são apagados na máquina virtual que utiliza esse disco.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'No menu Clonar você pode fazer uma cópia do disco, útil em migrações e para testar um sistema.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'O menu Excluir apaga o disco virtual.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'No menu Associar você pode conectar o disco virtual em uma máquina virtual.' >> $$.ajuda.tmp
dialog \
--title 'Ajuda do menu Principal' \
--textbox $$.ajuda.tmp \
0 0
;;
*)
;;
esac
listarhd
fi
done
}
# Lista os cd e dvd virtuais
function listarcddvd(){
echo 'dialog --stdout \' > $$.cdv.tmp
echo '--title "Cd virtual" \' >> $$.cdv.tmp
echo '--menu "Escolha o cd virtual:" \' >> $$.cdv.tmp
echo '0 0 0 \' >> $$.cdv.tmp
VBoxManage list dvds | grep Location | cut -d"/" -f5 > $$.cdv2.tmp
for i in `cat $$.cdv2.tmp`
do
usado_por=`VBoxManage list dvds | grep -A3 $i | grep Usage | awk '{print $2}'`
if [ "a$usado_por" == "a" ]
then
echo $i \'Sem uso\' '\' >> $$.cdv.tmp
else
echo $i \'Usado por $usado_por\' '\' >> $$.cdv.tmp
fi
done
echo 'Cd_local' 'Drive\ de\ cd\ do\ servidor' '\' >> $$.cdv.tmp
echo 'Novo' 'Utilizar\ um\ novo\ cd/dvd\ virtual' '\' >> $$.cdv.tmp
chmod +x $$.cdv.tmp
}
# Importação de cd e dvd virtuais
function importarcddvd(){
while true
do
arquivo=$( dialog --stdout \
--title 'Selecione o arquivo' \
--fselect ~ \
10 55)
if [ -z $arquivo ]
then
break
elif [ -f $arquivo ]
then
VBoxManage openmedium dvd $arquivo 2>/dev/null >/dev/null
if [ $? -ne 0 ]
then
dialog \
--title 'Erro!!!' \
--msgbox "Não consegui anexar o cd/dvd virtual." \
6 40
else
break
fi
else
dialog \
--title 'Arquivo não existe' \
--msgbox "O arquivo $arquivo não existe." \
6 40
fi
done
}
# Retira o cd de todas as vm's
function nenhumcd(){
for i in `VBoxManage list vms | grep ^\" | cut -d"\"" -f2`
do
VBoxManage showvminfo $i | grep $1 > /dev/null 2>/dev/null
if [ $? -eq 0 ]
then
VBoxManage storageattach $i --storagectl "Controladora IDE" --port 1 --device 0 --type dvddrive --medium emptydrive > /dev/null 2>/dev/null
fi
done
}
# Manutenção em cd virtual
function cdd(){
while true
do
cdv=$( ./$$.cdv.tmp )
if [ -z $cdv ]
then
return
elif [ $cdv == "Novo" ]
then
importarcddvd
else
listarvm
echo Nenhum \'Retirar de todos as Vms\' '\' >> $$.listar.tmp
echo Excluir \'Exclui o cd/dvd virtual\' '\' >> $$.listar.tmp
vms=$(./$$.listar.tmp)
caminho=`VBoxManage list dvds | grep $cdv | awk '{print $2}'`
if [ -z $vms ]
then
return
elif [ $vms == "Nenhum" ]
then
nenhumcd $cdv
elif [ $vms == "Excluir" ]
then
nenhumcd $cdv
VBoxManage closemedium dvd $caminho > /dev/null 2>/dev/null
else
VBoxManage storageattach $vms --storagectl "Controladora IDE" --port 1 --device 0 --type dvddrive --medium $caminho > /dev/null 2>/dev/null
fi
fi
listarcddvd
done
}
# Gerencia os discos e unidades de dvd virtuais
function discos(){
while true
do
discos=$( dialog --stdout \
--title "Tipo de midia" \
--menu "Escolha o tipo de midia:" \
0 0 0 \
'Cd virtual' 'Arquivo de imagem .iso' \
'Hd virtual' 'Arquivo de disco virtual' \
'Ajuda' 'Breve explicação sobre os menus acima' )
case $discos in
"Cd virtual")
listarcddvd
cdd
;;
"Hd virtual")
listarhd
hd
;;
"Ajuda")
echo 'No menu Cd Virtual você pode administrar os cds virtuais, criar, importar, excluir, etc.' > $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'No menu Hd Virtual você pode administrar os HDs virtuais, criar, assciá-los a uma VM, excluir, compactar, tirar snapshot, etc.' >> $$.ajuda.tmp
dialog \
--title 'Ajuda do menu Discos' \
--textbox $$.ajuda.tmp \
0 0
;;
*)
break
;;
esac
done
}
# Checa se a máscara de subrede é válida
function checamask(){
ipa=`echo $1 | cut -d"." -f1`
ipb=`echo $1 | cut -d"." -f2`
ipc=`echo $1 | cut -d"." -f3`
ipd=`echo $1 | cut -d"." -f4`
for i in $ipa $ipb $ipc $ipd
do
if [ $i != 0 ] && [ $i != 128 ] && [ $i != 192 ] && [ $i != 224 ] && [ $i != 240 ] && [ $i != 248 ] && [ $i != 252 ] && [ $i != 254 ] && [ $i != 255 ]
then
dialog \
--title 'Máscara inválida' \
--msgbox 'A máscara só aceita os valors 0, 128, 192, 224, 240, 248, 252, 254 e 255 no formato xxx.xxx.xxx.xxx.'\
6 40
return 1
fi
done
return 0
}
# Mensagem padrão para endereço ip inválido
function erroip(){
dialog \
--title 'Ip inválido' \
--msgbox 'O ip só pode conter números entre 0 e 255 no formato xxx.xxx.xxx.xxx.'\
6 40
}
# Checa se o ip digitado é válido
function checaip(){
ipa=`echo $1 | cut -d"." -f1`
ipb=`echo $1 | cut -d"." -f2`
ipc=`echo $1 | cut -d"." -f3`
ipd=`echo $1 | cut -d"." -f4`
for i in $ipa $ipb $ipc $ipd
do
echo $i | grep [^0-9] 2>/dev/null >/dev/null
if [ $? == 0 ]
then
erroip
return 1
elif [ $i -gt 255 ] || [ $i -lt 0 ]
then
erroip
return 1
fi
done
return 0
}
# Configuração do endereço ip
function ip(){
while true
do
ip=$(dialog --stdout \
--title 'Digite o ip' \
--inputbox 'Ip' 0 0 "$ip" )
if [ -z $ip ]
then
return 1
fi
checaip $ip
if [ $? -eq 0 ]
then
return
fi
done
}
# Configuração da máscara de subrede
function mask(){
while true
do
mask=$(dialog --stdout \
--title 'Digite a máscara de rede' \
--inputbox 'Máscara de sub-rede:' 0 0 "$mask" )
if [ -z $mask ]
then
return 1
fi
checamask $mask
if [ $? -eq 0 ]
then
return
fi
done
}
# Configuração da rota padrão
function gw(){
while true
do
gw=$(dialog --stdout \
--title 'Digite o gateway padrão' \
--inputbox 'Default gateway:' 0 0 "$gw" )
if [ -z $gw ]
then
return 1
fi
checaip $gw
if [ $? -eq 0 ]
then
return
fi
done
}
# Configurção da rede
function rede(){
while true
do
echo 'dialog --stdout \' > $$.rede.tmp
echo '--title "Interfaces de rede" \' >> $$.rede.tmp
echo '--menu "Escolha a interface de rede:" \' >> $$.rede.tmp
echo '0 0 0 \' >> $$.rede.tmp
ifconfig | grep encap | sed s/"Link encap"//g | awk '{print $1$2}'| sed s/":"/" "/g | sed 's/$/ \\/g' >> $$.rede.tmp
chmod +x $$.rede.tmp
rede=$(./$$.rede.tmp)
if [ -z $rede ]
then
return
else
ip=`ifconfig $rede | grep inet | grep -v inet6 | awk '{print $3}'`
mask=`ifconfig $rede | grep inet | grep -v inet6 | awk '{print $5}' | cut -d":" -f2`
gw=`netstat -nr | grep ^0.0.0.0 | awk '{print $2}'`
ip
if [ $? -eq 0 ]
then
mask
if [ $? -eq 0 ]
then
gw
if [ $? -eq 0 ]
then
ifconfig $rede $ip netmask $mask 2>/dev/null >/dev/null
route delete -net default 2>/dev/null >/dev/null
route add -net default gw $gw 2>/dev/null >/dev/null
fi
fi
fi
fi
done
}
# Configurações do servidor real.
function servidor(){
while true
do
menu_servidor=$( dialog --stdout \
--title "Administração do Servidor" \
--menu "Opções: " \
0 0 0 \
Update 'Atualização dos pacotes' \
Informacoes 'Informações sobre o status do servidor' \
Rede 'Configuração da rede' \
Console 'Acesso ao console do servidor' \
Ajuda 'Breve explicação sobre os menus acima')
case $menu_servidor in
"Update")
clear
apt-get update
apt-get -y upgrade
read
;;
"Informacoes")
dialog --no-shadow \
--sleep 1 \
--infobox 'Aguarde...' 12 40 --and-widget &
cpu=`top -b -n 2 | grep Cpu | tail -1 | awk '{print $2}'`
tarefas=`top -b -n 1 | grep Tasks | tail -1 | awk '{print $2}'`
ioread=`iostat -dm 1 2 | grep -v ^$ | tail -1 | awk '{print $3}'`
iowrite=`iostat -dm 1 2 | grep -v ^$ | tail -1 | awk '{print $4}'`
swap=`free -m | tail -1 | awk '{print $3}'`
free=0
y=`free -m | grep ^Mem | awk '{print $4" "$6" "$7}'`
for i in $y
do
free=$(($free + $i))
done
in1=$((`ifconfig eth0 | grep 'RX bytes' | awk '{print $2}' | cut -d":" -f2` / 1024))
out1=$((`ifconfig eth0 | grep 'RX bytes' | awk '{print $6}' | cut -d":" -f2` / 1024))
sleep 1
in2=$((`ifconfig eth0 | grep 'RX bytes' | awk '{print $2}' | cut -d":" -f2` / 1024))
out2=$((`ifconfig eth0 | grep 'RX bytes' | awk '{print $6}' | cut -d":" -f2` / 1024))
in=$(( $in2 - $in1 ))
out=$(( $out2 - $out1 ))
hora=`date "+%H:%M"`
conn=`netstat -na | grep ESTAB | wc -l`
echo "Hora: $hora" > $$.servidor.tmp
echo "Tarefas: $tarefas" >> $$.servidor.tmp
echo "Uso de cpu: $cpu" >> $$.servidor.tmp
echo "Leitura de disco (Mb/s): $ioread" >> $$.servidor.tmp
echo "Escrita em disco (Mb/s): $iowrite" >> $$.servidor.tmp
echo "Uso de swap (Mb): $swap" >> $$.servidor.tmp
echo "Inbound (eth0, Kb/s): $in" >> $$.servidor.tmp
echo "Outbound (eth0, Kb/s): $out" >> $$.servidor.tmp
echo "Conexões ativas (eth0): $conn" >> $$.servidor.tmp
echo "Memória ram livre (Mb): $free" >> $$.servidor.tmp
dialog \
--title 'Detalhes do servidor' \
--textbox $$.servidor.tmp \
16 50
;;
"Rede")
rede
;;
"Console")
clear
read -p "Para voltar ao menu, digite 'Exit'. " -t 3
/bin/bash
;;
"Ajuda")
echo 'No menu Update você pode atualizar os programa via apt-get. É necessário estar logado como root' > $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'No menu Informações é mostrado um status do servidor, como uso de cpu, memória ram, espaço em disco, etc.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'No menu Rede é possível alterar as configurações de rede. Essas configurações serão perdidas no próximo boot.' >> $$.ajuda.tmp
echo ' Para que as configurações fiquem permanentes, acesse o menu Console e altere o arquivo /etc/network/interfaces.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'O menu Console dá acesso ao console do servidor, permitindo fazer configurações e ajustes avançados.' >> $$.ajuda.tmp
dialog \
--title 'Ajuda do menu Servidor' \
--textbox $$.ajuda.tmp \
0 0
;;
*)
break
;;
esac
done
}
# Programa principal
depend
if [ $? -ne 0 ]
then
exit 255
fi
versao=`VBoxManage -v`
while true
do
menu_principal=$( dialog --stdout \
--title "Administração do VirtualBox versão $versao" \
--menu "Opções: " \
0 0 0 \
VMs 'Administrar as máquinas virtuais' \
Discos 'Administraçãos dos discos e imagens de cd e dvd' \
Servidor 'Administração do servidor' \
Ajuda 'Breve explicação sobre os menus acima')
case $menu_principal in
"VMs")
listar
;;
"Discos")
discos
;;
"Servidor")
servidor
;;
"Ajuda")
echo 'No menu VMs você pode administrar as máquinas virtuais, criar, iniciar, congelar, excluir, etc.' > $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'No menu Discos você pode administrar os HDs e CDs virtuais, criar, assciá-los a uma VM, excluir, etc.' >> $$.ajuda.tmp
echo "" >> $$.ajuda.tmp
echo 'No menu Servidor você pode administrar o servidor real, obter informações, status, efetuar atualizações, etc' >> $$.ajuda.tmp
dialog \
--title 'Ajuda do menu Principal' \
--textbox $$.ajuda.tmp \
0 0
;;
*)
rm $$.*.tmp > /dev/null 2>/dev/null
break
;;
esac
done
Diário Oficial da União - Download facilitado
Criação de pasta com senha no Apache
Atualiza base de dados do Clamav e avisa o admin
IA Turbina o Desktop Linux enquanto distros renovam forças
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
IA chega ao desktop e impulsiona produtividade no mundo Linux
Atualizando o Fedora 42 para 43
Como saber se o seu e-mail já teve a senha vazada?
Como descobrir se a sua senha já foi vazada na internet?
Ubunto não reconhece rede ethernet (0)
Secure boot, artigo interessante, nada técnico. (3)
Instalação dualboot Windows 11 e Debian 13 (11)









