Administração de VirtualBox com ShellScript
Publicado por Ricardo Lino Olonca (última atualização em 25/08/2012)
[ Hits: 8.598 ]
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
Shell Script / Perl para sincronizar base de usuários do AD com o Zimbra
POSTFIX AUTOMÁTICO COM MYSQL E IPTABLES - APAGANDO MSG ANTIGAS
EPD 0.5 (Criando e editando pacotes de instalação debian)
Backup e PHP conbinação explosiva.
Cirurgia para acelerar o openSUSE em HD externo via USB
Void Server como Domain Control
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
Jogar games da Battle.net no Linux com Faugus Launcher
Como fazer a Instalação de aplicativos para acesso remoto ao Linux
Como fazer a instalação do Samba
Como fazer a conversão binária e aplicar as restrições no Linux
Duas Pasta Pessoal Aparecendo no Ubuntu 24.04.3 LTS (19)
Formas seguras de instalar Debian Sid (13)
Malware encontrado em extensões do Firefox. (0)
Fiz uma pergunta no fórum mas não consigo localizar [RESOLVIDO] (21)









