Operações matemáticas com shell script

Uma coisa que chama a atenção em shell script são as operações matemáticas. Em shell script a princípio elas não são resolvidas diretamente, para resolver essas operações é necessário usar algum comando auxiliar, por exemplo:


a=1;
b=2;
# c=$a+$b; não iria funcionar
d=$(( $a + $b )); # ok

obs. também é possível usar os comandos let, expr e bc para resolver operações matemáticas.

Mas essa caracteristica apesar de ser padrão, pode ser modificada usando o comando ‘declare -i’ para criar as variáveis, veja:


a=1;
b=2;
declare –i c; # a variavel c é do tipo inteiro
c=$a+$b; # a operacao é resolvida diretamente...
# cuidado com os epaços...

Isso garante que a variável ‘c’ é do tipo inteiro, e não vai aceitar outros tipos de valores, algo parecido com o que ocorre com linguagens fortemente tipadas, mas diferentemente dessas, ao se atribuir um valor diferente do estipulado não será emitida uma mensagem de erro, veja:


declare –i c; # c é inteiro
c=”paulo”;
echo $c # imprime 0 (zero)

Ao tentar setar uma string em ‘c’ o valor é desconsiderado, ficando o valor de zero no lugar.

É importante perceber que usando o comando ‘declare -i’, além da variável assumir (parcialmente) caracteristicas de uma linguagem fortemente tipada, também terá alterações no seu escopo. Veja os exemplos:


Function teste() {
a=10;
}
teste # executa a função
echo $a #imprimie 10

Diferente de outras linguagens as variáveis dentro de funções não são por padrão locais, ou seja, elas iram escapar para o escopo principal quando a função for executada (caracteristica bem estranha, na minha opinião), mas se for usado o comando ‘declare –i’ isso não acontece:


Function teste() {
declare –i a=10;
}
teste
echo $a # nao imprimi 10

valeu pessoal, espero que seja util…

Obs. Se você precisa que as variáveis dentro de funções sejam locais e não quer usar o declare –i ou as suas variáveis não são numericas use “local a=10”;

Animações com CSS3

O CSS3 traz varias possibilidades de animações. Animações que antes envolveriam toda uma lógica de programação e algumas(ou muitas) linhas de código Javascript podem agora ser feitas apenas com CSS. Um exemplo disso é a pequena animação de aumentar uma imagem quando o mouse é colocado sobre ela. Isso já era possível apenas com o :hover, mas a idéia é que ela aumente aos poucos e não tudo de uma vez só. Na verdade, é algo bem simples, mas que até a chegada do CSS3 só era possível com Javascript. Veja um exemplo de como fazer essa animação apenas com CSS3:

#ex-css-img1 { 
width: 120px;
transition: width 2s; /* padrão */
-moz-transition: width 2s; /* Firefox */
-webkit-transition: width 2s; /* Safari and Chrome */
-o-transition: width 2s; /* Opera */
}

#ex-css-img1:hover {
width: 190px;
}

Veja a simplicidade do código, basicamente usei a propriedade “transition” para amenizar a alteração que ocorre na propriedade “width” quando o mouse fica por cima da imagem(hover). Perceba que sem a propriedade “transition” o tamanho da imagem aumenta rápidamente sem produzir a animação esperada:

Obs. no exemplo, não utilizei todas as possibilidades da propriedade “transition”, nesses casos é assumido o valo padrão.

A sintaxe da propriedade “transition” é :

transition: property duration timing-function delay;

onde:

property: A propriedade que será alterada durante a animação
duration: O tempo até que a animação termine
timing-function: A forma de execução da animação. Alguns valores suportados são: linear, ease, ease-in, ease-out…
delay: O tempo antes que a animação inicie

veja mais sobre essa propriedade aqui

Outra propriedade que simplifica e muito as animações com CSS3 é a “transform”, veja alguns exemplos:

A propriedade “transform” tem a seguinte sintaxe:

transform: function;

Onde:

“function”: É uma das muitas funções que essa propriedade suporta. Por exemplo nas animações acima usei respectivamente: transform: rotate( 180deg ), transform: rotateX( 180deg ) e transform: rotateY( 180deg ). Veja mais sobre a propriedade “transform” e suas funções aqui

Para obter resultados mais elaborados é possível especificar mais de uma propriedade para a “transition”, por exemplo:

#ex-css-img7 {
transition-property: transform, border-radius;
transition-duration: 1s;
-moz-transition-property: transform, border-radius;
-moz-transition-duration: 1s;
-webkit-transition-property: transform, border-radius;
-webkit-transition-duration: 1s;
-o-transition-property: transform, border-radius;
-o-transition-duration: 1s;
}

#ex-css-img7:hover{
transform: rotate( 360deg );
-moz-transform: rotate( 360deg );
-webkit-transform: rotate( 360deg );
-o-transform: rotate( 360deg );
border-radius: 100px;
-moz-border-radius: 100px;
-webkit-border-radius: 100px;
-o-border-radius: 100px;
}

Obs. Nesse exemplo usei a “transition” especificando cada possibilidade em uma propriedade diferente. ( da mesma forma que acontecia no CSS2, por exemplo: margim: top right bottom left; ou margin-top:, margim-right:, margin-bottom: e margin-left: )

Além das propriedades “transition” e “transform” o CSS3 também disponibiliza as propriedades “animation” e “@keyframes” (essa última na verdade é uma regra). Com elas é possível ter um maior controle sobre a animação, por exemplo:

#ex-css-img8 {
position:relative;
animation:mymove 3s infinite alternate;
-moz-animation:mymove 3s infinite alternate;
-webkit-animation:mymove 3s infinite alternate;
-o-animation:mymove 3s infinite alternate;
}

@keyframes mymove {
from {
left:0px;
}

to {
left:310px;
transform: rotate( 360deg );
border-radius: 100px;
-moz-transform: rotate( 360deg );
-moz-border-radius: 100px;
-webkit-transform: rotate( 360deg );
-webkit-border-radius: 100px;
-o-transform: rotate( 360deg );
-o-border-radius: 100px;
}
}

Essas propriedades trabalham em conjunto: A propriedade “@keyframes” define os passos da animação( from e to ou 0%,10%,20%… ), e a propriedade “animation” define a @keyframe que vai ser utilizada, o tempo até que animação se complete, a forma e quantas vezes animação será realizada. A sintaxe da propriedade @keyframes é :

@keyframes animationname { keyframes-selector { css-styles; } };;

onde:

animationname: O nome que representa a @keyframes.
keyframes-selector: Um passo na animação. Aceita valores como: from e to ou ainda em percentagem( 0%, 50%, 100%…).
veja mais sobre essa propriedade aqui

E a sintaxe da propriedade animation é :

animation: name duration timing-function delay iteration-count direction;;

onde:

name: É o nome da propriedade @keyframe que será executada.
duration: O tempo até que o efeito termine.
timing-function: Controla a forma de execução do efeito, exemplo mais lento no inicio e mais rápido no final
delay: O tempo antes que o efeito inicie.
iteration-count: A quantidade de vezes que animação será executada.
direction: A forma que animação é realizada.
veja mais sobre essa propriedade aqui

Essas são as principais propriedades para se criar animações com CSS3, os navegadores atuais já estão dando suporte à elas( ainda que com os prefixos dos navegadores ), não deixe de ver os links no final do post, neles você vai encontrar otimas animações com CSS3. Para terminar vou deixar mais um exemplo de animação com as porpriedades “animation” e “@keyframes”:

#ex-css-img9  {
position:relative;
animation: movex-css-img9 3s infinite alternate;
-moz-animation: movex-css-img9 3s infinite alternate;
-webkit-animation: movex-css-img9 3s infinite alternate;
-o-animation: movex-css-img9 3s infinite alternate;
}

@keyframes movex-css-img9 {
from {
left: 390px;
width: 120px;
}
75% {
left: 195px;
width: 60px;
transform: rotate( 360deg );
border-radius: 100px;
}
to {
left: 0px;
width: 120px;
}
}

@-moz-keyframes movex-css-img9 {
from {
left: 390px;
width: 120px;
}
75% {
left: 195px;
width: 60px;
transform: rotate( 360deg );
border-radius: 100px;
}
to {
left: 0px;
width: 120px;
}
}


@-webkit-keyframes movex-css-img9 {

from {
left: 390px;
width: 120px;
}
75% {
left: 195px;
width: 60px;
transform: rotate( 360deg );
border-radius: 100px;
}
to {
left: 0px;
width: 120px;
}
}


@-o-keyframes movex-css-img9 {

from {
left: 390px;
width: 120px;
}
75% {
left: 195px;
width: 60px;
transform: rotate( 360deg );
border-radius: 100px;
}
to {
left: 0px;
width: 120px;
}
}

mais sobre animações com css3:
http://marcobruno.com.br/example/parallax-sem-plugin-css3.html
http://www.impressivewebs.com/demo-files/css3-animated-scene/
http://devfiles.myopera.com/articles/9132/sun-rise.html
http://www.broken-links.com/2009/03/10/css-animation-pong/

Configurando o GRUB2 no Debian Squeeze

Os principais arquivos de configuração do GRUB2 são o /boot/grub/grub.cfg, o /etc/default/grub e também os scripts localizados no diretório /etc/grub.d/.

Na verdade, a configuração manual do GRUB2 é feita apenas no arquivo /etc/default/grub e nos scripts do diretório /etc/grub.d/. O arquivo /boot/grub/grub.cfg apesar de ser o principal arquivo de configuração, não deve ser alterado manualmente, esse arquivo será configurado pelo comando update-grub tendo como base o conteúdo dos arquivos anteriores.

/etc/grub.d/

Os arquivos do diretório /etc/grub.d/ são scripts responsáveis por montar o arquivo /boot/grub/grub.cfg. Esses scripts serão executados pelo comando update-grub, por tanto, devem ter permissão de execução.

A ordem de execução desses arquivos segue a ordem alfabética de seus nomes, por exemplo: o arquivo 05_debian_theme é executado antes do 10_linux.

Alguns scripts desse diretorio são:

00_header: é o script que carrega as configurações que estão no arquivo /etc/default/grub, por exemplo: o tempo de espera e a entrada de boot padrão.

05_debian_theme: Define a aparência do GRUB2

10_linux: Localiza os kernels do sistema operacional e cria suas entradas no menu.

20_memtest86+: Cria as entradas do memtest.

30_os-prober: Busca outros sistemas operacionais e cria as suas entradas no menu.

40_custom: é apenas um modelo para criar entradas adicionais no menu do GRUB2.

/etc/default/grub

O arquivo /etc/default/grub não é exatamente um script, nele é possível alterar diretamente o valor de varias variáveis de configuração, por isso, esse arquivo é bem mais amigável que os scripts do diretório grub.d.

Configurações

Configurar as cores do menu:

Tecnicamente o arquivo responsável por essa configuração é o script 05_debian_theme, mas por se tratar de um script, ele exige um certo conhecimento em programação, felizmente existe uma forma mais simples de fazer essa configuração: Crie o arquivo /boot/grub/custom.cfg e dentro dele coloque o seguinte conteúdo:

set color_normal=light-gray/black

set color_highlight=blue/white

set menu_color_normal=magenta-light-grayset

menu_color_highlight=blue/white

Onde:

color_normal : Cor da fonte e do background

color_highlight: Cor da fonte e do background com seleção

menu_color_normal:  Cor da fonte e do background do menu

menu_color_highlight: Cor da fonte e do background do menu com seleção

Alguma das cores possíveis são: black, blue, green, cyan, red, magenta, brown, light-gray, dark-gray, light-blue, light-green, light-cyan, light-red, light-magenta, yellow e white.

E pronto, não é necessário rodar o comando update-grub, o arquivo será carregado automaticamente.

Colocar uma imagem no GRUB2

Essa é outra opção que a principio deveria ser configurada no script 05_debian_theme, mas pelo mesmo motivo anterior vou mostrar uma forma alternativa: No arquivo /etc/default/grub altere ou crie a seguinte linha e rode o comando update-grub:

GRUB_BACKGROUND=“coloque aqui o caminho até a imagem”

Uma boa fonte de imagens para o menu GRUB2 é o pacote GRUB2-splashimages, após a instalação, verifique o diretório /usr/share/images/grub/ ( para ver como instalar pacotes no Debian clique aqui )

Alterar a resolução do GRUB2:

Para configurar a resolução da tela do GRUB2 altere a seguinte linha no arquivo /etc/default/grub e rode o comando update-grub:

GRUB_GFXMODE=640×480

Essa configuração altera apenas a resolução da tela do GRUB2, não terá efeito no sistema. É interessante manter a resolução do menu igual a resolução do sistema.

Configurar o boot padrão:

Essa configuração especifica qual a entrada do menu que vai ser executada automaticamente se o usuário não especificar nenhuma até o final do tempo de espera. Para configurar o boot padrão, altere a seguinte linha no arquivo /etc/default/grub e rode o comando update-grub:

GRUB_DEFAULT=0

onde o 0(zero) é a primeira entrada do menu do GRUB2, 1 a segunda, 2 a terceira… Também é possível utilizar GRUB_DEFAULT=saved, assim, a entrada padrão será sempre a última que foi selecionada, ou seja, se na última vez o usuário selecionou a entrada 1, essa será opção padrão até que ele selecione outra.

Ajustar o tempo de espera:

Esse é o tempo que o GRUB2 vai esperar antes de chamar o boot padrão. Para configurar, altere a seguinte linha no arquivo /etc/default/grub e rode o comando update-grub:

GRUB_TIMEOUT=5

Incluir ou retirar o recovery mode:

Para configurar a entrada do recovery mode altere o valor da seguinte linha no arquivo /etc/default/grub e rode o comando update-grub:

GRUB_DISABLE_LINUX_RECOVERY=”true”

se o valor for true, o recovery mode não vai ter sua entrada no GRUB2, se for false vai ter.

Configurar a entrada do memtest:

Para retirar a opção de memtest do menu execute os seguintes comandos:

chmod -x /etc/grub.d/20_memtest86+; update-grub;

Para habilitar essa opção novamente rode os seguintes comandos:

chmod +x /etc/grub.d/20_memtest86+; update-grub;

Se quiser habilitar essa opção, mas o script 20_memtest86+ não estiver no diretório grub.d, instale o pacote memtest86+ .

Personalizar as entradas do menu

Para editar as entradas que estão no menu do GRUB2, é possível copiar essas entradas da configuração que já está pronta no arquivo /boot/grub/grub.cfg (afinal ela está funcionando normalmente) e depois colar no script 40_custom. As entradas do menu do GRUB2 são configuras pela palavra chave menuentry e são delimitadas por chaves {}, segue um exemplo:

menuentry “Titulo da opção” {

aqui ficam os comandos

}

O arquivo /boot/grub/grub.cfg é dividido por blocos BEGIN e END, cada bloco é gerado por um dos scripts do diretório /etc/grub.d/.

É importante guardar o nome dos scripts que geraram os blocos de onde estão as menuentry que serão copiadas. Cuidado, copie apenas as menuentry’s.

Com as entradas já coladas no script 40_custom faça as alterações necessárias e salve. Com isso, se o comando update-grub fosse rodado as entradas personalizadas já estariam no GRUB2, mas as entradas padrão também, ou seja, as entradas ficariam em dobro.

Para evitar isso, é necessário tirar a permissão de execução dos scripts que geram as entradas padrão(os scripts do diretorio grub.d), para isso, execute o comando a seguir para cada um desses scripts, faça somente naqueles que o nome aparecia em um bloco BEGIN e END de onde foram copiadas as menuentry’s, não tire a permissão dos outros…

cd /etc/grub.d/;
chmod -x nome_do_script

E por último rode o comando update-grub.

Criar uma nova entrada para o menu:

A principio dificilmente será necessário criar uma entrada manualmente para o menu do GRUB2, se por algum motivo um sistema não for reconhecido após o comando update-grub, instale o pacote os-prober e rode os comandos abaixo:

os-prober; update-grub;

O os-porber é capaz de localizar sistemas que não estejam sendo reconhecidos pelo GRUB2. Se ainda assim, o sistema não for reconhecido, é possível criar uma entrada no menu manualmente através do script 40_custom que está no diretório /etc/grub.d/. Para criar uma entrada para uma distribuição GNU/Linux insira o seguinte conteúdo no script 40_custom e execute o update-grub:

menuentry “Titulo do Sistema” {

set root=(hd0,1)
linux /boot/vmlinuz-versão_do_kernel
initrd /boot/initrd.img-versão_do_kernel
}

Esse é o mínimo para se criar uma entrada para um sistema GNU/Linux no GRUB2.
Em set root=(hd0,1) está sendo especificado que o sistema está no primeiro disco(hd0) e na primeira partição desse disco. Obs.: Os discos iniciam no zero( hd0, hd1, hd2… ), mas as partições iniciam no 1.

Onde diz “versão_do_kernel” substitua pela versão do kernel que o sistema utiliza. Se tiver acesso a esse sistema, é possível verificar qual a versão do kernel com o comando uname -r.

Para criar uma entrada no menu para um sistema Windows( xp, vista, 7 ) use:

menuentry “Titulo do Sistema” {

set root=(hd0,1)
chainloader +1
}

Mais sobre o GRUB2:
http://www.vivaolinux.com.br/dica/Personalizando-o-Grub-2
http://www.gnu.org/software/grub/
http://www.vivaolinux.com.br/dica/Colocando-senha-criptografada-no-GRUB-2

Programação em Shell Script

O Shell Script é uma linguagem de programação utilizada principalmente para automatizar tarefas administrativas em sistemas operacionais Unix, Linux, BSD… Existem vários interpretadores para os scripts em shell, o mais utilizado em distribuições linux é o Bash, além dele, também é possível utilizar o Sh , Csh e o Ksh . Nesse artigo vou utilizar o Bash, veja um exemplo de Shell Script com Bash:



#!/bin/bash
echo "ola $USER";

Esse script simplesmente cumprimenta o usuário. Nele utilizei o comando “echo”, que imprime na saída padrão ( nesse caso vai ser a tela do monitor ), e a variável de ambiente “$USER”, que guarda o usuário logado. A primeira linha desse Shell Script, “#!/bin/bash”, indica o interpretador que deve executar os comandos que estão no arquivo. é possível utilizar outro interpretador shell, por exemplo o “#!/bin/sh” ou um interpretador de outra linguagem como “#!/usr/bin/python”( seria possível usar até mesmo o PHP, veja um exemplo aqui ) ou não especificar nenhum interpretador, nesse ultimo caso, o sistema usa o interpretador que estiver na variável “$SHELL” ( interpretador padrão ).

Para testar esse script é necessário que ele tenha permissão de execução no sistema, para isso, supondo que o nome do arquivo seja “teste.sh” vou rodar no terminal o comando:



chmod +x teste.sh

e depois para executar o script vou usar o comando:



./teste.sh

Para executar o Shell Script coloquei o caminho completo do arquivo teste.sh ( o “./” representa o diretório atual ), isso foi necessário porquê quando é digitado um comando ( ou um Shell ) no terminal, sem especificar o caminho até o arquivo, o sistema busca por ele nos diretórios que aparecem no variável “$PATH”. Se não quiser especificar o caminho para executar seus scripts, você pode colocá-los em um dos diretórios que aparecem na “$PATH” ou configurar o diretório onde eles estão nessa variável ( exemplo de como fazer isso aqui ).

Assim como outras linguagens de programação, Shell Script possui estruturas de controle do tipo: if, case, while e for. A Sintaxe dessas estruturas é a seguinte:

If


#!/bin/bash
nome="paulo";
if [ $nome != "paulo" ] ; then

echo "vc não é o paulo!";
fi

Case


#!/bin/bash
i=1;
case $i in

1)
echo "é 1";
;;

2)
echo "é 2";
;;

*)
echo "não eh 1 nem 2";
;;
esac

While


#!/bin/bash
i=1;
while [ $i -le 10 ] ; do

echo $i;
i=$(( $i + 1 ));
done

For


#!/bin/bash
for i in $( seq 10 ) ; do

echo $i;
done

Em Shell Script os espaçamentos que normalmente são permitidos em outras linguagens causam erros, por exemplo quando é criada uma variável não deve haver espaços entre o nome da variável, o sinal de igual e o valor atribuído.


#!/bin/bash
i=1; # ok, vai funcionar
j = 2; # não vai funcionar

Obs. é possível utilizar o comando “read” para ler da entrada padrão( geralmente o teclado ) e criar variaveis especificadas pelo usuário. Veja mais sobre isso aqui

Outra particularidade do Shell Script é que operações matemáticas não são realizadas diretamente, é necessário utilizar algum comando para realizar o calculo, por exemplo:


#!/bin/bash
i=1;
j=$(( $i + 1 )); # ok
j=$( expr $i + 2 ); # ok
j=$i + 1; # não vai funcionar como esperado

Nesse exemplo foi utilizado o comando “$( expr $i + 2 )”, basicamente trata-se de um sub-shell, o que estiver dentro de “$( )” é executado à parte e o resultado( o que seria impresso na saída padrão) é atribuído para variável. Também seria possível utilizar o comando “` expr $i + 2 `” para ter o mesmo resultado.

Outro detalhe importante que foi visto nos exemplos anteriores são os operadores usados nas estruturas de controle dentro do comando “[ ]”, que na verdade é um açúcar sintático para o comando “test”, veja alguns exemplos de operadores:

Para Numeros
-lt É menor que (LessThan)
-gt É maior que (GreaterThan)
-le É menor ou igual (LessEqual)
-ge É maior ou igual (GreaterEqual)
-eq É igual (EQual)
-ne É diferente (NotEqual)
Para Strings
= É igual
!= É diferente
Testes logicos
! Negação
-a and ( geralmente && )
-o or( geralmente || )

O Shell Script também possui funções, elas tem a seguinte sintaxe:


#!/bin/bash

function somar() {

echo $(( $1 + $2 ));
}

somar 1 2

As funções em Shell Script são chamadas da mesma forma que um comando, elas recebem parâmetros sem a necessidade de especificá-los na declaração da função. Os parâmetros são recuperados através de variáveis especais, como a “$1” e a “$2” utilizadas no exemplo acima. Veja outras dessas variáveis especiais:

$0 O nome da função
$1 O primeiro parâmetro
$2 O segundo parâmetro
$numero O parâmetro da posição numero
$# A quantidade de parâmetros
$* Todos os parâmetros

O script anterior poderia ter sido escrito da forma abaixo para não limitar o número de parâmetros a ser somados:


#!/bin/bash

function somar() {

resultado=0;
for i in $* ; do

resultado=$(( $resultado + $i ));
done

echo $resultado;
}

somar 1 2 3 4 5

Uma observação importante sobre as funções em Shell Script é que apesar de possuir a instrução “return”, essa instrução é utilizada de uma forma diferente. Em Shell Script funções são como os comandos, os comandos tem um código de retorno que indica se o comando foi executado corretamente ou não( isso é testado com a variável “$?” ), portanto as funções também tem esse código de retorno, que é retornado com a instrução “return” 🙂

Para conseguir armazenar o retorno de função em uma variável costumo usar o sub-shell:


#!/bin/bash

function somar() {

resultado=0;
for i in $* ; do

resultado=$(( $resultado + $i ));
done

echo $resultado;
}

#usando o sub-shell é possível
#armazenar o retorno da função
total=$( somar 1 2 3 4 5 );

A grande utilidade das funções é que elas organizam e garantem a reutilização de código. Uma possibilidade interessante que o Shell Script permite( e a maior parte das linguagem de script também ) e incluir um arquivo dentro de outro ( parecido com o require e include do PHP). Por exemplo, posso criar varias funções que estejam relacionadas e coloca-las no mesmo arquivo e depois quando for necessário uso a instrução “source” para incluir essas funções em outro arquivo. Supondo que a função “somar” estivesse no arquivo matemática.sh posso usá-la da seguinte maneira:


#!/bin/bash

source "matematica.sh";

total=$( somar 1 2 3 4 5 );

Além de funções e estruturas de controle, Shell Script também possui arrays. Os arrays tem a seguinte sintaxe em Shell Script:


#!/bin/bash

dias=( "domingo" "segunda" "terca" "quarta" "quinta" "sexta" "sabado" );

echo ${dias[1]}; # imprime segunda

nomes[0]="paulo";
nomes[1]="ana";
nomes[2]="carlos";

echo ${nomes[1]};

# para retornar a quantidade de itens
echo ${#nomes[@]} # imprime 3

Vou terminar deixando um script com o que foi visto nesse artigo, se quiser saber mais sobre Shell Script veja os links mais abaixo. Até mais… 🙂


#!/bin/bash
function organiza() {

array=($@);
i=0;
while [ $i -lt ${#array[@]} ]; do

j=$(($i + 1));
while [ $j -lt ${#array[@]} ]; do

if [ ${array[$j]} -lt ${array[$i]} ]; then

aux=${array[$j]};
array[$j]=${array[$i]};
array[$i]=$aux;
fi
j=$(($j + 1));
done
i=$(($i + 1));
done

for n in ${array[@]}; do

echo "$n";
done
}

organiza 2 9 4 5 6 1

Mais Informações:
http://aurelio.net/shell/canivete/pdf/canivete-shell.pdf
http://thobias.org/doc/shell_bd.html
http://thobias.org/doc/cgi_shell.html
http://www.vivaolinux.com.br/dica/Utilizando-arrays-em-shell-script
http://lendscripts.blogspot.com.br/
http://victor-dba.blogspot.com.br/2012/02/10-dicas-para-programar-em-shell-script.html

MathML: Mathematical Markup Language

MathML é uma linguagem de marcação, baseada em XML, para criar formulas matemáticas. Ela está dividida em duas partes: Presentation e Content Markup. Esse artigo vai tratar apenas da Presentation Markup.

Atualmente me parece que apenas o Firefox e o Opera oferecem algum suporte nativo para as instruções MathML( tive alguns problemas com o Opera ), mas isso provavelmente vai mudar em breve, pois a MathML está incluído na especificação do HTML5. Portanto para acompanhar esse artigo recomendo o uso de um desses navegadores ( também existe o plugin Mathplayer para IEca, mas eu não testei )

Vamos iniciar com um exemplo simples:


<math>
<msqrt>
<mn>2</mn>
</msqrt>
</math>

Essa marcação deve apresentar a raiz quadrada de 2, assim:

2

Nesse exemplo notamos que o elemento raiz do MathML é o math, a raiz quadrada é representada pelo elemento msqrt e o elemento mn representa um número.

Os elementos mais usados em MathML são mn, mi e mo. Eles servem para representar respectivamente numeros( ex. 1, 0.235 ), variáveis/constantes( ex. x, &#960 ) e operadores( ex. +, = ). Veja um exemplo usando os 3 elementos:


<math>
<mi> y </mi>
<mo> = </mo>
<mi> x </mi>
<mo> - </mo>
<mn> 3 </mn>
</math>
y = x 3

Outro elemento usado com freqüência é o mrow. Esse elemento tem a função de agrupar outros elementos em linha. A principio pode parecer um elemento sem muita utilidade, mas em MathML existem elementos com um numero especifico de filhos. Dessa forma mrow se torna muito útil. Por exemplo, o elemento mfenced serve para colocar parênteses ao redor de outro elemento, mas se for colocado mais de um elemento filho dentro dele, esses elementos são separados por vírgula, veja:


<math>
<mfenced>
<mi> x </mi>
<mo> - </mo>
<mn> 3 </mn>
</mfenced>
</math>
x 3

Essa característica pode ser útil em alguns casos, mas nesse exemplo seria melhor que não houvesse essa separação. Para evitar isso podemos fazer o seguinte:


<math>
<mfenced>
<mrow>
<mi> x </mi>
<mo> - </mo>
<mn> 3 </mn>
</mrow>
</mfenced>
</math>
x 3

Outra característica importante do elemento mfenced é que podemos especificar quais caracteres serão utilizados como parênteses e separadores. Isso é possível através dos atributos open, close e separators.


<math>
<mfenced open='[' close=']' separators='|'>

<mn> 2 </mn>
<mn> 5 </mn>
<mn> 8 </mn>

</mfenced>
</math>
2 5 8

Outro elemento que tem o numero de filhos predefinido é mfrac que serve para criar frações, o primeiro filho é o numerador e o segundo é o denominador. Segue um exemplo:


<math>
<mfrac>
<mrow>
<mn> 2 </mn>
<mo> + </mo>
<mn> 5 </mn>
</mrow>
<mn>2</mn>
</mfrac>
</math>
2 + 5 2

Ainda temos os elementos msub e msup que também tem o numero de filhos predefinidos:


<math>
<msub>
<mn> 2 </mn>
<mn> 5 </mn>
</msub>

<mo>+</mo>

<msup>
<mn> 1 </mn>
<mn> 4 </mn>
</msup>
</math>
2 5 + 1 4

Com MathML também podemos criar matrizes. A sintaxe é semelhante as tabelas html. O elemento pai é o mtable. Dentro dele temos elementos de linha mtr, e dentro desses, elementos de coluna mtd.


<math>
<mfenced><mtable>
<mtr>
<mtd> <mn> 1 </mn> </mtd>
<mtd> <mn> 0 </mn> </mtd>
</mtr>
<mtr>
<mtd> <mn> 0 </mn> </mtd>
<mtd> <mn> 1 </mn> </mtd>
</mtr>
</mfenced></mtable>
</math>
1 0 0 1

Com esse conhecimento sobre os elementos de MathML podemos criar expressões como essas:


<math>
<mrow>
<mn>x</mn>
<mo>=</mo>
<mrow>
<mfrac>
<mrow>
<mo>-</mo>
<mi>b</mi>
<mo>±</mo>
<msqrt>
<mrow>
<msup>
<mi>b</mi><mn>2</mn>
</msup>
<mo>-</mo>
<mn>4</mn>
<mo>.</mo>
<mi>a</mi>
<mo>.</mo>
<mi>c</mi>
</mrow>
</msqrt>
</mrow>
<mrow>
<mn>2</mn>
<mo>.</mo>
<mi>a</mi>
</mrow>
</mfrac>
</mrow>
</mrow>
</math>
x = b &PlusMinus; b2 4 . a . c 2 . a

<math>
<mrow>
<msub>
<mi>S</mi>
<mi>n</mi>
</msub>
<mo>=</mo>
<mfrac>
<mrow>
<mfenced>
<mrow>
<msub>
<mi>a</mi><mn>1</mn>
</msub>
<mo> + </mo>
<msub>
<mi>a</mi><mn>1</mn>
</msub>
</mrow>
</mfenced>
<mo>.</mo>
<mi>n</mi>
</mrow>
<mn>2</mn>
</mfrac>
</mrow>
</math>
S n = a1 + an . n 2

<math>
<mrow>
<msup>
<mi>a</mi><mn>2</mn>
</msup>
<mo>+</mo>
<msup>
<mi>b</mi><mn>2</mn>
</msup>
<mo>=</mo>
<msup>
<mi>c</mi><mn>2</mn>
</msup>
</mrow>
</math>
a2 + b2 = c2

Update:
13/01/2012 O Chrome gerou todos os códigos corretamente

Mais informações:
http://www.fisiocomp.ufjf.br/seminarios/MathML.pdf
http://www.w3.org/TR/MathML3/
https://developer.mozilla.org/en-US/docs/MathML/Element

POLA – Princípio da Menor Surpresa

O POLA ou Princípio da Menor Surpresa é um principio que busca evitar que o usuário seja surpreendido por um retorno não esperado. A idéia básica do POLA é a previsibilidade. Nesse post vou mostrar alguns exemplos de códigos java, que vão contra esse principio, não vou colocar o resultado, a idéia é que você tente imaginar a resposta e depois teste, ok?

Veja esse código, qual a saída dele?



Integer a = 1;
int b = 1;
Integer c = 1;

System.out.println(a == b);
System.out.println(b == c);
System.out.println(a == c);

e se for somado 999 nas três variáveis o resultado das comparações é o mesmo? O que você acha?



a += 999;
b += 999;
c += 999;

System.out.println(a == b);
System.out.println(b == c);
System.out.println(a == c);


No próximo código temos duas variáveis com a string “paulo”. O que é retornado quando comparamos as duas com o operador de igualdade(==) ? E se a comparação fosse feita com as strings em maiúsculas? O resultado é o mesmo? Têm certeza?

OBS. O certo é usar o método .equals para comparar strings



String a = "paulo";
String b = "paulo";

System.out.println(a == b);
System.out.println(a.toUpperCase() == b.toUpperCase());


Agora veja esse código, ele não compila e nem deveria, não é?



float f = 2f;

int i = 0;

i = i + f;

mas e esse, será que compila?



float f = 2f;

int i = 0;

i += f;


Por ultimo qual o resultado de 0.1 + 0.1 + 0.1 ? simples né? será?



System.out.println( 0.1 + 0.1 + 0.1 );

Mais sobre Princípios de Projetos Orientados a Objetos:
http://ferhenriquef.com
http://www.henriqueavila.com.br