Inicialmente este blog foi criado para armazenar algumas dicas e links de UNIX/Linux, OpenVMS, linguagem C, Assembly, TCP/IP e nerdezas afins. No entanto devido ao autor ter abandonado o seu plano de ser um super hacker e dominar o mundo (devido esposa, família, filhos, trabalho), a partir de 2012 este blog tem um tipo de nerdeza mais light (Android, Linux, RetroPie (retrogames), produtividade, e por aí vai). Estas dicas raramente serão criações minhas.

Mostrando postagens com marcador shell. Mostrar todas as postagens
Mostrando postagens com marcador shell. Mostrar todas as postagens

sexta-feira, 6 de maio de 2016

fazer o find parar depois do primeiro match

Estava fazendo um script para abrir um determinado arquivo baseado no que era encontrado através de um find. O problema é que as vezes o find encontrava mais de um arquivo que atendia o critério de busca, e eu gostaria de parar no primeiro arquivo encontrado. Uma rápida googlada e a solução apareceu...

Fazer o comando find parar após o primeiro arquivo encontrado:

find caminho/do/diretorio -name nome-do-arquivo -print -quit
Simples assim!

Aritmética de datas em shell scripts

Estava eu felizinho e tranquilo fazendo um scriptzinho aqui para me ajudar em algumas coisas do trabalho, quando esbarrei no problema da aritmética de datas.

O caso é o seguinte: tenho um arquivo (planilha excel) onde todos os dias preencho várias informações, e às 17h eu tenho que fechar este arquivo e abrir um novo que se encerrará às 17h do dia seguinte. O meu objetivo era fazer um script onde eu pudesse passar uma data na linha de comando e ele já abrisse diretamente o arquivo referente a esta data. Útil para consultar os arquivos de dias anteriores.

O problema que encontrei foi que o nome dos arquivos contem a data de fechamento daquele arquivo e a data anterior, exemplo: "Dados 01-05-2016 a 02-05-2016.xls". Isso é um problema pois não é uma matemática tão simples fazer o script saber qual é o dia anterior de uma determinada data. Alguns meses tem 28, 29, 30 ou 31 dias...

Numa rápida googlada achei uma solução simples, bonita e elegante:

date -d "2016-05-01 - 1 day"

Para obter a data no formato desejado basta usar o caractere de formatação '%', de acordo com o que é mostrado na manpage. No meu caso fica assim:

date -d "2016-05-01 - 1 day" +%d-%m-%Y

(OBS.: pelo que andei lendo esse recurso de aritmética de datas é uma feature do GNU date. Portanto funcionará em qualquer distro Linux moderna, porém não funciona no date do BSD, que é o utilizado nos SOs da Apple.)

quinta-feira, 8 de maio de 2008

transformando o eeepc num meeeleupc

Se, assim como eu, você tem um eeepc e gosta de modo texto e quando está no modo gráfico quer no máximo um Window Maker, experimente o meeeleupc! ;-)

Baixe o arquivo em http://www.geocities.com/meleuzord/meeeleupc.tar.gz.

Descompacte o arquivo em algum lugar, por exemplo no seu homedir:


tar xvzf meeeleupc.tar.gz

entre no diretório criado e execute o instalar como root:

cd meeeleupc
sudo ./instalar


Resumidamente o script vai fazer duas coisas:
  • configurar o EeePC para que inicie no modo texto (Multiuser Mode) com dois consoles (tty4 e 5);
  • instalar e configurar o wmaker bem bacaninha para ser utilizado no EeePC.

    Além disso, desinstala aqueles programas coreanos/chines/tailandes/xingling/etc. e instala alguns programas que eu acho importante ter (vim, nmap, netcat, lynx, irssi, etc.)

    Fiz uma comparacao usando 'df -h' para ver quanto de espaco foi consumido neste process. O EeePC 701 após um 'Restore Factory Settings' tem 1.3GB livres, após a instalacão do meeeleupc fica com 1.1GB livres.

    Após a instalacão, os arquivos podem ser encontrados em /usr/local/share/meeeleupc, inclusive um script para desabilitar o Multiuser Mode (somente texto) e voltar com a interface original.

    Eu acho que o codigo está bem simples de ler. Qualquer dúvida/sugestão/crítica será bem vinda em meleuzord arroba yahoo ponto com.

  • segunda-feira, 30 de julho de 2007

    desassemblando para hexadecimal

    Venci o desafio lançado a mim mesmo! Consegui uma maneira rápida de desassemblar uma função e ver os opcodes em hexadecimal! E nada de grep+sed, apenas o bom e velho shell script. Aí vai a solução:

    #!/bin/bash

    if [ $# -ne 2 ]; then
    echo "Falta parametros!"
    echo
    echo "Uso: `basename $0` funcao programa"
    echo
    exit 1
    fi

    # a opcao -t do objdump mostra a tabela de simbolos do arquivo
    # e eh lah que temos as informacoes sobre as funcoes do programa
    # tais como endereco, tamanho, nome, etc...
    # o grep procura a funcao que queremos na tabela de simbolos
    LINHA=`objdump -t $2 | grep " $1$"` || {
    echo "Erro!"
    echo
    echo "Nao existe a funcao \"$1\" no programa \"$2\""
    echo
    exit 1
    }

    # a variavel ENDERECO tem o endereco inicial e final da funcao
    # mais infos sobre vetores em bash no meu texto de bashscripting
    ENDERECO=(`echo $LINHA | cut -d' ' -f1,5`)

    # a saida do objdump NAO coloca 0x no inicio dos numeros hexa
    INICIO="0x${ENDERECO[0]}"

    # o endereco final eh (inicio + tamanho_da_funcao)
    # a conta eh feita dentro do $[ cifrao-colchetes ]
    FIM="$[ $INICIO + 0x${ENDERECO[1]} ]"

    # voilah! agora o golpe de misericordia:
    objdump -j.text -d --start-address=$INICIO --stop-address=$FIM $2
    Tá tá tá... não ficou lá muito elegante, mas é só pra quebrar um galho, né!

    Um dia eu faço um mais bacana com getopts e talz...

    suid bash

    Eu achava que o bash ignorava o setuid bit nele mesmo. Mas descobri na man page a opção -p. Faça testes e observe ;-)

    quinta-feira, 19 de julho de 2007

    "Desassemblando" uma função de programa

    Essa eu aprendi na man page do gdb. Achei útil para ver o endereço e o tamanho das instruçoões.

    O parâmetro "-batch" executa o gdb no modo execução de comandos em lote. E o parâmetro "-x file" é o arquivo onde está os comandos a serem executados.

    Por exemplo: veja o seguinte arquivo chamado disassmain.

    disassemble main

    disassemble é o comando do gdb que desassembla uma função

    Agora execute o seguinte comando (supondo um programa chamado prog):

    $ gdb -batch -x disassmain prog

    Observe o resultado e veja que maravilha! ;-)

    Agora eu fiz um script muito simples, porém interessante, que recebe como parâmetros na linha de comando o nome da funcao a ser "desassemblada" e o nome do programa. Chamei-o carinhosamente de mdisasm (meleu's disassembler):

    #!/bin/bash
    TMPFILE=/tmp/mdisasm.$$     # este '$$' retorna o PID do script em execucao

    if [ $# -ne 2 ]; then       # $# eh o numero de argumentos (tem que ser 2)
       echo
       echo "uso: `basename $0` funcao programa
       echo
       exit 1
    fi

    cat << _EOF_ > $TMPFILE     # abaixo daqui ateh _EOF_ vai para $TMPFILE
    disassemble $1
    _EOF_

    gdb -batch -x $TMPFILE $2

    rm -f $TMPFILE

    Isso é útil quando queremos ver o endereço de uma determinada instrução, seu tamanho e o seu mnemônico.

    Agora para "desassemblar" uma única função e ver as instruções em hexadecimal (útil para escrita de shellcodes) eu ainda não achei uma solução. Ainda continuo usando 'objudump -d prog > arquivo.out' e depois lendo arquivo.out procurando a função desejada. Fica lançado um desafio pra mim mesmo. Queria uma solução simples, mas acho que terei que apelar para o grep+sed...


    [Desafio vencido: http://mdicas.blogspot.com/2007/07/desassemblando-para-hexadecimal.html]

    segunda-feira, 16 de julho de 2007

    O que o #! faz

    Essa eu li em http://br.geocities.com/cesarakg/tips-shell-programming.html.

    Quando executamos um arquivo que começa com o #! (chamado de hash-bang) o kernel lê o arquivo, vê o hash-bang, e continua a ler o resto da linha. Então ele pega o que ele encontrar nesta linha depois do hash-bang e executa tendo como parâmetro o próprio arquivo.

    Vamos aos exemplos:

    O arquivo abaixo chama-se hello.sh:

    #!/bin/bash
    # hello.sh: o famigerado "Hello World!"
    echo "Hello World!"

    quando é digitado no shell:
    prompt$ ./hello.sh

    o kernel vai ver o #! e vai ler o que vem a seguir, neste caso '/bin/bash'. E então ele executa o equivalente a isto:
    prompt$ /bin/bash hello.sh

    Então lembrando: o kernel lê o que está depois do hash-bang e executa o que estiver lá, usando o nome do arquivo como parâmetro. No caso do exemplo acima temos o seguinte:

    O que foi lido após o hash-bang: /bin/bash
    Nome do arquivo: hello.sh


    Um exemplo muito interessante mencionado no texto é o seguinte:

    O nome do arquivo é helpme.
    #!/bin/cat
    vi unix editor
    man manual pages
    sh Bourne Shell
    ksh Korn Shell
    csh C Shell
    bash Bourne Again Shell

    O que é lido após o hash-bang: /bin/cat
    Nome do arquivo: helpme

    Portanto será executado: /bin/cat helpme

    Uma observação interessante é que o bash (e a maioria dos shells) considera tudo que vem depois de um caractere '#' como comentário, portanto o hash-bang e toda a sua linha é um comentário para o shell. Porém no exemplo helpme acima, o /bin/cat não vai ignorar e #! e irá exibir o contúdo de todo o arquivo.

    No documento mencionado existem outras dicas. O texto é curto e de rápida leitura. Eu recomendo.

    tags