Archive for June, 2007

Published by carla on 29 Jun 2007

Email no Unix (mail/mailx) - Como enviar arquivo anexo

Como fazer para enviar um arquivo anexo através do comando mail ou mailx no Unix?

Por exemplo, pode ser necessário enviar um arquivo anexo em emails enviados através de scripts que realizam funções administrativas. Além do anexo, podemos enviar junto o conteúdo no corpo do email (body).

Seguem os passos para enviar um email contendo um arquivo compactado (.zip) e conteúdo no corpo do email:

1 - Compactar arquivos, gerando arquivo zip:

/usr/bin/zip arquivo.zip $diretorio/*ERR*

2 - Gerar o anexo. Para isso usamos o comando uuencode:

/usr/bin/uuencode arquivo.zip arquivo.zip > attachment.txt

OBS: Sim, o nome do arquivo zip é repetido 2 vezes no comando. Não é erro de digitação. :)

3 - Combinar o anexo com o texto que irá no corpo do email:

cat texto_email.txt attachment.txt > combinado.txt

O arquivo texto_email.txt contém o que irá escrito no corpo do email.

4 -Enviar o email com conteúdo no corpo do email e arquivo zip anexo:

/usr/bin/mailx -s “Email com anexo e conteúdo” email@dominio < combinado.txt

A opção “-s” é para colocar o Assunto/Subject do email.

Published by daniduc on 14 Jun 2007

Incrementar variável numérica em bash2

Até a bash 1, para você incrementar uma variável numérica de 1 em 1 era preciso toda uma contorção:

contador=0; \
while [ $contador -lt 10 ]; \
do echo “o valor do contador eh $contador”; \
let contador=$contador+1; \
done

Agora, com a bash2, você pode usar o for de maneira parecida com a sintaxe do C:

for (( contador=0; contador < 10; contador++ )); \
do echo “o valor do contador eh $contador” ;\
done

Published by daniduc on 14 Jun 2007

Como remover um arquivo com nome estranho

Se você precisar remover um arquivo chamado -h o comando rm -h não irá funcionar. O comando rm irá interpretar o -h como um parâmetro e não como um arquivo, já que o primeiro caracter é o -, noramlmente utilizado para sinalizar parâmetros. Para remover o arquivo basta dar o caminho até ele:

daniduc@nicholas:~/teste$ ls
-h
daniduc@nicholas:~/teste$ rm ./-h
daniduc@nicholas:~/teste$ ls
daniduc@nicholas:~/teste$

Se o nome do arquivo começar por um espaço, basta colocar uma contrabarra na frente do espaço. Veja:

daniduc@nicholas:~/teste$ ls
teste
daniduc@nicholas:~/teste$ rm teste
rm: cannot lstat `teste’: No such file or directory
daniduc@nicholas:~/teste$ rm \ teste
daniduc@nicholas:~/teste$ ls
daniduc@nicholas:~/teste$

Published by daniduc on 13 Jun 2007

bash: Argument list too long

Pode ser que você já tenha tentado dar um comando usando o asterisco * na bash e tenha obtido este erro:

bash: comando: Argument list too long

Aonde comando pode ser um rm, ou um cp, ou qualquer outro. Por exemplo:

daniduc@nicholas:~/teste$ rm -f *
bash: /bin/rm: Argument list too long
daniduc@nicholas:~/teste$

Quem imprimiu esse erro não foi o comando (o rm, no exemplo), mas a bash, que é responsável por expandir o wildcard *, substituindo-o pela lista de arquivos no diretório. Em sistemas UNIX, há um limite fixo de memória reservado para o ambiente e lista de parâmetros de um comando. No caso do meu servidor Linux, esse limite é 128K, mas isso varia de sistema para sistema. Você pode descobrir no seu sistema usando o comando getconf. Veja:

daniduc@nicholas:~/teste$ getconf ARG_MAX
131072
daniduc@nicholas:~/teste$

Agora, ao que interessa. Como fazer para remover os arquivos do meu exemplo acima? Existem diversas saídas, variando a eficiência dependendo de qual é o seu comando, na verdade. Mas vamos ver o rm, pois o exemplo dele pode ser aplicado a outros, como por exemplo o cp, ou o mv.

Se você puder eliminar o diretório inteiro no qual estão os arquivos, não há problemas:

daniduc@nicholas:~$ rm -rf teste/
daniduc@nicholas:~$

Se você só pode eliminar os arquivos, uma saída é usar o comando find.

daniduc@nicholas:~/teste$ find . -type f -exec rm -f {} \;
daniduc@nicholas:~/teste$

Nesse caso, eu pedi para o find encontrar no diretório em que estou (.) todos os arquivos (-type f) e para cada um deles executar (-exec) o comando rm. As chaves {} são substituídas por cada arquivo encontrado pelo find. Dessa forma o rm é executado uma vez para cada arquivo, tendo assim apenas aquele arquivo como parâmetro, o que evita ultrapassar o limite de memória imposto. O final \; é para fechar o comando do -exec com um ponto e vírgula, que precisa ser precedido da contra barra (\) para que a bash não o interprete (uma vez que ; é um caractere com sentido especial para a bash) e apenas o passe para o find.

Caso, por exemplo, você precise remover somente os arquivos html e não os arquivos .php em um diretório, basta usar o find novamente:

daniduc@nicholas:~/teste$ ls *.php
1.php 2.php
daniduc@nicholas:~/teste$ ls
(saida resumida:)
23497.html 36998.html 50498.html 6399.html 774.html 9.html
23498.html 36999.html 50499.html 639.html 77500.html
23499.html 3699.html 5049.html 63.html 77501.html
2349.html 369.html 504.html 64000.html 77502.html
234.html 36.html 50500.html 64001.html 77503.html

daniduc@nicholas:~/teste$ find . -name \*.html -exec rm -f {} \;
daniduc@nicholas:~/teste$ ls
1.php 2.php
daniduc@nicholas:~/lixo

Aqui o asterisco funciona porque está precedido pela contrabarra o que faz com que a bash não o interprete, apenas o find. E find não expande o asterisco em todos os arquivos do diretório, como a bash. Para o find, o asterisco é parte de uma expressão regular, que quer dizer “encontre arquivos cujo nome seja qualquer coisa seguida de um .html”.

Eu uso a versão da GNU do find, presente na maioria dos sistemas Linux. Caso o seu find não entenda o parâmetro -exec, use-o em conjunto com comando xargs:

daniduc@nicholas:~/teste$ find . -name \*.html | xargs rm -f
daniduc@nicholas:~/teste$ ls
1.php 2.php
daniduc@nicholas:~/teste$

Referências:

http://www.gnu.org/software/coreutils/faq/coreutils-faq.html#Argument-list-too-long

Published by carla on 11 Jun 2007

Comando rpm: Como listar todos os arquivos de um pacote instalado

Já escrevi como listar os arquivos de um pacote instalado no Aix através do comando lslpp. Agora segue como verificar os arquivos de um pacote instalado com o comando rpm:

Exemplo:

>rpm -ql sudo-1.6.5p2-2
/etc/sudoers
/opt/freeware/bin/sudo
/opt/freeware/doc/sudo-1.6.5p2
/opt/freeware/doc/sudo-1.6.5p2/BUGS
/opt/freeware/doc/sudo-1.6.5p2/CHANGES
/opt/freeware/doc/sudo-1.6.5p2/HISTORY
/opt/freeware/doc/sudo-1.6.5p2/LICENSE
/opt/freeware/doc/sudo-1.6.5p2/README
/opt/freeware/doc/sudo-1.6.5p2/RUNSON
/opt/freeware/doc/sudo-1.6.5p2/TODO
/opt/freeware/doc/sudo-1.6.5p2/TROUBLESHOOTING
/opt/freeware/doc/sudo-1.6.5p2/UPGRADE
/opt/freeware/doc/sudo-1.6.5p2/sudo.pod
/opt/freeware/doc/sudo-1.6.5p2/sudoers.pod
/opt/freeware/doc/sudo-1.6.5p2/visudo.pod
/opt/freeware/man/man5/sudoers.5
/opt/freeware/man/man8/sudo.8
/opt/freeware/man/man8/visudo.8
/opt/freeware/sbin/visudo
/usr/bin/sudo
/usr/sbin/visudo
/var/run/sudo

O comando rpm é utilizado em algumas distribuições Linux, bem como no Aix.

Referência:

How to use RPM Commands: http://www.faqs.org/docs/securing/chap3sec20.html

RPM Commands: http://www.idevelopment.info/data/Unix/Linux/LINUX_RPMCommands.shtml

RPM man page: http://www.die.net/doc/linux/man/man8/rpm.8.html

Published by carla on 01 Jun 2007

Solaris - Verificando a versão de um pacote instalado

Anotação simples. Para ver a versão de um pacote instalado no Solaris, use a opção “-x” do comando pkginfo:

Para identificar o pacote (exemplo: FTP server Proftp):

foo>pkginfo |grep proft
application SMCpftpd proftpd

Uma vez identificado o pacote, verifica-se a versão:

foo>pkginfo -x SMCpftpd
SMCpftpd proftpd
(sparc) 1.3.1rc2