Funções como comandos

Antes de começar vamos relembrar um conceito básico: quando se executa um shell script você obtém o mesmo resultado que obteria se digitasse o conteúdo do script no prompt de um shell. Com isso eu quero dizer que você pode fazer tudo que faz em um shell script na linha de comando, inclusive criar e utilizar funções (que é o assunto deste tópico).

Bom chega de falar de coisas óbvias... :-)

Na linha de comando você declara uma função da mesma maneira que faz num script. Por exemplo, digite o seguinte na sua linha de comando:

function heko {
    echo -e "\e[5;1;32mHekodangews, para de enrolar a mina e casa logo! \e[m"
}

Agora quando você entrar com "heko" na linha de comando será impresso na tela um recadinho para o Hekodangews numa corzinha verde e piscante super-fashion. =)

Veja este outro exemplo um pouco mais útil:

function SetPath {
    PATH=${PATH:="/bin:/usr/bin"}
    for DIR in "$@"; do
        if [ -d "$DIR" ]; then
        PATH="$PATH:$DIR"
        else
        echo "* * * Erro: $DIR nao eh um diretorio"
        fi
    done
    export PATH
    unset DIR
}

Acho que deu pra sacar qual é, né? Quando você quiser acrescentar algum diretório no seu PATH basta usar SetPath dir1 dir2 dirn. ;-)

E se você tiver várias idéias de funções legais que queira usar sempre em suas sessões? Vai ter que digitá-las na linha de comando toda hora? Não! Para este propósito o comando source pode ser muito útil (informações detalhadas na manpage do bash).

Lembra-se de eu ficar enchendo o saco dizendo "Quando executamos um shellscript ele é executado num shell a parte (shell filho)"? Pois eu não fiquei enchendo o saco com isso sem motivo. O comando source faz com que o script seja executado no shell pai, ou seja, é como você estivesse digitando todo o conteúdo do arquivo na linha de comando. E isso é especialmente útil quando temos arquivos com as nossas funções que queremos usar como comandos.

Uma coisa legal de se fazer é colocar o arquivo com as funções que você quer usar num arquivo oculto no seu $HOME (ex.: $HOME/.MyFunctions) e no seu $HOME/.bash_profile você coloca uma linha com o comando source $HOME/.MyFunctions.

Veja este arquivo com alguns exemplos de funções:

#!/bin/bash
# Mfunctions
#
# "INSTALAÇÃO":
# copie este arquivo para seu $HOME:
# [prompt]$ cp Mfunctions ~/.Mfunctions
#
# depois faça o seguinte:
# [prompt]$ echo ". ~/.Mfunctions" >> ~/.bash_profile
#
# Dê login novamente ou digite ". ~/.Mfunctions" e pronto.
# Agora é só digitar o nome da função.
#
# DICA: depois de corretamente instalada, use "M"
#	para ver as funções disponíveis.
#
# Funções disponíveis neste arquivo:
# + Mecho
# + Mcenter
# + Mclock
# + Mclock2
# + Msetpath
# + Mdica
# + Marrumanome
# + Mnocomments
# + Mcalcula
# + Mcores
#
# Aproveite!
# meleu
#
# P.S.: graças a esse tal de "oupem sórssi" você pode ler
#	um código e alterá-lo para que se adeque as suas
#	necessidades eu que fique ao seu gosto. Pois foi
#	isso que eu fiz aqui! Saí olhando as funções que
#	outras pessoas fizeram e arrumei do meu jeito. E
#	a minha principal fonte foi o funcoeszz do aurélio.
#	veja em: http://verde666.org/zz
#



# imprime em negrito
function Mecho {
	echo -e "\e[1m$*\e[m"
}



# imprime em negrito no centro da linha
function Mcenter {
	local POS=$[ ( $COLUMNS - `echo -en "$*" | wc -c` ) / 2 ]
	Mecho "\e[${POS}C$*"
}



# deixa sempre no cantinho da primeira linha do console:
# "[ hora:minuto dia/mes/ano ]".
# Se houver algum processo em segundo plano (background) ele também indica.
# OBS.: nos emuladores de terminal em que eu testei só funcionou no xterm
# o rxvt não aceita os códigos de salvar e restaurar a posição do cursor
# (respectivamente "\e[s" e "\e[u").
function Mclock {
local CIANO="\e[1;36m"
local AMARELO="\e[1;33m"
local SCOR="\e[m"

alias DiaMesAno='date +'\''%H:%M %e/%m/%y'\'

PROMPT_COMMAND="
JOBS=\$(echo \$(jobs | wc -l))
if [ \$JOBS -ne 0 ]; then
        HEADER=\"Jobs: \$JOBS     -     \$(DiaMesAno)\"
else
        HEADER=\"\$(DiaMesAno)\"
fi
POS=\$[ (\$COLUMNS - \$(echo \"\$HEADER\" | wc -c) ) - 3 ]"

PS1="\[\e[s\e[1;0H\e[K\
\e[\$(echo -n \$POS)C\
$CIANO[$AMARELO \$HEADER $CIANO]$SCOR\
\e[u\e[1A\]
$PS1"

echo -e "\nMclock ativado!\n"

}



# Parecido com o Mclock mas fica tudo escrito no centro da primeira linha
# e em um formato mais longo.
function Mclock2 {
local CIANO="\e[1;36m"
local AMARELO="\e[1;33m"
local SCOR="\e[0m"

alias Mdate='date +'\''%H:%M - %A, %e %B %Y'\'

PROMPT_COMMAND="
JOBS=\$(echo \$(jobs | wc -l))
if [ \$JOBS -ne 0 ]; then
        HEADER=\"Jobs: \$JOBS  -  $(Mdate)\"
else
        HEADER=\"\$(Mdate)\"
fi
POS=\$[ (\$COLUMNS - \$(echo \"\$HEADER\" | wc -c) ) / 2 ]"

PS1="\[\e[s\e[1;0H\e[K\
\e[\$(echo -n \$POS)C\
$CIANO[$AMARELO \$HEADER $CIANO]$SCOR\
\e[u\e[1A\]
$PS1"

echo -e "\nMclock2 ativado!\n"

}



# Adiciona um diretório na sua variável $PATH
function Msetpath {
local DIR
PATH=${PATH:="/bin:/usr/bin"}
[ $# -eq 0 ] && { echo "PATH = $PATH"; return; }
for DIR in "$@"; do
    if [ -d "$DIR" ]; then
	PATH="$DIR:$PATH"
    else
	echo "* * * Erro: $DIR não é um diretório"
	continue
    fi
done
export PATH
}



# eu tenho no meu home um diretório dicas onde eu vou colocando
# dicas sobre programas diversos.
# o nome dos arquivos são iguais aos nomes dos programas, então
# quando eu me deparo com uma dica sobre o grep, por exemplo, eu
# faço:
# [prompt]$ cat dica_grep >> ~/grep
# esta função serve para visualizar as dicas
# OBS.: o aurélio que me deu ESTA dica do diretório "$HOME/dicas".
# valeu rapaz! ;)
function Mdica {
local DICASDIR=$HOME/dicas
[ "$1" ] || {
	Mecho "Uso: Mdica [assunto]\n"
	echo "Os assuntos disponíveis são:"
	ls $DICASDIR
	return
}

more $DICASDIR/$1

}



# renomeia os arquivos que possuem nomes com caracteres feiosos
# fazendo com que letras maiúsculas fiquem minúsculas;
# letras acentuadas fiquem a letra correspondente sem acento;
# e espaços em branco, símbolos e outras coisas feias fiquem
# underline '_'
function Marrumanome {
[ "$1" ] || {
	Mecho "Erro: você precisa passar os arquivos que quer renomear";
	echo 'Uso: Marrumanome arquivo1 [arquivoN ...]'
	return 1
}

local FILE NINICIAL NFINAL DIR

for FILE in "$@"; do
	[ -f "$FILE" ] || continue
	NINICIAL=`basename "$FILE"`
	DIR=`dirname "$FILE"`
	NFINAL=`echo "$NINICIAL" | sed '
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
y/ÃãÀàÂâÄäÁáÈèÊêËëÉé/aaaaaaaaaaeeeeeeee/
y/ÌìÎîÏïÍíÕõÒòÔôÖöÓó/iiiiiiiioooooooooo/
y/ÙùÛûÜüÚúÇçÑñ/uuuuuuuuccnn/
s/^-/_/
s/[^a-z0-9._-]/_/g'`

	[ "$NINICIAL" != "$NFINAL" ] && mv -- "$FILE" "$DIR/$NFINAL"
done
}



# visualiza um arquivo retirando linhas que comecem com um caractere
# de comentário (#) e linhas vazias (linhas com espaços não são
# vazias)
function Mnocomments {
[ "$1" ] || {
	Mecho "Erro: falta argumentos"
	echo "Uso: Mnocomments arquivo1 [arquivoN ...]"
	return
}

# estou usando o more só por causa daqueles ":::::::" que aparecem
# quando é passado mais de um arquivo como parâmetro. ;-)
more $@ | egrep -v "^#|^$"

}



# faz cálculos usando o bc
# só pra não precisar ficar fazendo "echo  | bc" toda hora
function Mcalcula {
[ "$1" ] || {
	Mecho "Erro: você precisa passar uma expressão"
	echo "Uso: Mcalcula "
	echo "Exemplo: Mcalcula '4^2+3*(7-4)'"
	return 1
}

# mude o valor de "scale" se quiser mais de duas casas decimais
echo "scale=2; $@" | bc

}



# mostra todas as cores do console e seus respectivos códigos.
# mais uma cortesia do aurélio
function Mcores {
for LETRA in `seq 0 7`; do
  for BOLD in '' ';1'; do
    for FUNDO in `seq 0 7`; do
      SEQ="4$FUNDO;3$LETRA"
      echo -ne "\e[$SEQ${BOLD}m $SEQ${BOLD:-  } \e[m"
    done
    echo
  done
done
}

Se você quer ver umas funções porretas que o aurélio fez conheça as funcoeszz (ver Referências).

results matching ""

    No results matching ""