Preview only show first 10 pages with watermark. For full document please download

Bash Novo

Explore a última versão do grande Bourne-again shell. Apesar da maturidade do Bash, seus desenvolvedores continuam aprimorando-o. A versão 4 do shell está cheia de novidades. por Bernhard Bablok e Nils Magnus.

   EMBED

  • Rating

  • Date

    December 2018
  • Size

    1.4MB
  • Views

    7,491
  • Categories


Share

Transcript

Explore a última versão do grande Bourne-again shell ANÁLISE Bash novo yewkeo, 123RF Apesar da maturidade do Bash, seus desenvolvedores continuam aprimorando-o. A versão 4 do shell está cheia de novidades. por Bernhard Bablok e Nils Magnus A pesar da competição recente por parte de poderosas alter­ nativas como o Zsh [1], o Bourne-again shell (Bash) [2] ain­ da é o rei do pedaço no console do GNU/Linux. O Bash, que pode ser usado de forma interativa, tam­ bém serve como uma linguagem de script simples e prática. O Bash faz parte do esqueleto de todo sistema GNU/Linux – mais um motivo para investigar os benefícios de adotar a nova versão 4, lançada em fevereiro de 2009. Por que não? Em sistemas em produção, talvez seja mais recomendável avaliar se é realmente necessário atualizar o Bash para sua nova versão. Por um lado, as principais distribuições cer­ tamente difundirão a nova versão por meio de suas atualizações, então o novo Bash fatalmente vai chegar ao seu sistema mais cedo ou mais tarde. Programadores e usuários avançados, por outro lado, gostam de usufruir os benefícios oferecidos por novas versões o mais rápido possível. Quem desejar já se familiarizar com o shell principal da maioria das distribuições do futuro certamente 58 gostará de passar algum tempo com o Bash 4 já. A tabela 1 mostra um resumo de alguns novos recursos importantes; para uma listagem completa, verifi­ que o arquivo NEWS na documentação do Bash. Este artigo levanta algumas das mudanças mais importantes. Linha de comando Usuários da linha de comando apre­ ciarão algumas extensões inconspí­ cuas, mas muito úteis, incorporadas ao novo Bash. Por exemplo, a string ** é expandida para uma lista de arquivos e caminhos sob o diretório atual, de forma semelhante ao co­ mando externo find. Porém, os usuá­ rios precisam ativar esse recurso por meio do comando shopt -s globstar. Os desenvolvedores agora ado­ taram uma técnica mais amigável para um dos maiores mistérios do Bash: o redirecionamento da saída de erro padrão. Em vez do mantra 2>&1 1>arquivo, agora os usuários po­ dem usar simplesmente &> >arquivo para redirecionar as saídas padrão e de erro para um único arquivo. O atalho |&, que redireciona o erro padrão de um comando para um pipe, é outra novidade útil. Vetores associativos A crença popular reza que scripts Bash criam muitos processos, que acabam prejudicando o desempe­ nho. Mas muitos dos aplicativos simples que costumavam ser usados com o Bash, incluindo sed, grep, basename e dirname, já não são mais necessários; o Bash realiza essas tarefas tão rápido quanto qualquer outra linguagem de script com fer­ ramentas embutidas. Apesar desses avanços, os programadores Bash continuam com olhares invejosos a Perl e Python, ambos com estruturas de dados mais versáteis. Em sua versão 4, o Bash final­ mente acrescenta a seus vetores uni­ dimensionais os vetores associativos (semelhantes aos hashes em Perl e dicionários em Python). Para muitos programadores, essa mudança, por si só, já é motivo suficiente para ado­ tar a nova versão, pois ela oferece uma solução bem mais elegante a vários problemas. Por exemplo, os desenvolvedores podem usar textos arbitrários como índices de vetores associativos em vez de apenas intei­ ros. A listagem 1 mostra um exemplo. A listagem 2 contém um script que ordena arquivos em diretórios http://www.linuxmagazine.com.br Bash 4 | ANÁLISE Tabela 1: Principais mudanças Mudança Substrings PID autocd checkjobs read mapfile command_not_found_handle globstar Chaves Saída de erro padrão Saída de erro padrão case Expansão variável Conversão automática Vetores associativos coproc Seleção Descrição A extensão para parâmetros de posição suporta o desvio zero O PID do shell atual está disponível na variável BASHPID Suporta navegação rápida por meio do nome do diretório Verifica e relata trabalhos (jobs) ativos ou parados na saída Atribui entradas parciais a variáveis e mantém seus valores mesmo que o comando tenha seu tempo expirado Facilita o processamento de arquivos O Bash 4 chama essa função caso não consiga encontrar um comando Usa ** para realizar buscas recursivas ao longo de múltiplos diretórios A extensão cria uma lista de valores com zeros na frente Em vez de 2>&1 1>arquivo, o Bash agora suporta &> >arquivo Da mesma forma, |& substitui 2>&1 | Agora o Bash 4 suporta ;;, ;& e ;;& para terminar um case. O primeiro processa incondicionalmente as instruções do próximo grupo; o segundo verifica mais uma vez e, se adequado, continua processando o próximo grupo. Os operadores ^ e , alteram para caixa alta ou baixa declare -u e declare -l convertem automaticamente para caixa alta ou baixa ao atribuir valores Os índices podem ser strings: $idade[“fulano”] Cria processos assíncronos O comando read -t 0 -u fd verifica se o descritor de arquivo fd fornece dados Complete a sua coleção O objetivo da coleção é trazer conhecimento confiável e de alto nível sempre com enfoque prático e voltado para a utilização do sistema Linux e de outras tecnologias livres. Mais informações Site: www.linuxmagazine.com.br Linux Magazine #58 | Setembro de 2009 Tel: 11 4082-1300 59 ANÁLISE  | Bash 4 Listagem 1: Programação com vetores associativos 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 #!/bin/bash declare -A name nome[“Linus”]=”Torvalds” nome[“Bill”]=”Gates” nome[“Steve”]=”Jobs” nome[“Richard”]=”Stallman” # Mostrar todos os valores: echo “Valores: ${nome[@]}” # Mostrar todas as chaves: echo “Chave: ${!nome[@]}” # Acessar valores individuais for v in “{!nome[@]}”; do echo “$v ${name[$v]}” done Listagem 2: Texto errado em listas 01 02 03 04 05 06 07 08 09 10 11 12 13 14 #!/bin/bash dirs=”” for f in “$@”; do d=`getDir “$f”` mkdir ‑p “$d” mv ‑f “$f” “$d” dirs=”$dirs $d” done for d in $dirs; do createIndex “$d” done Listagem 3: Vetores associativos 01 02 03 04 05 06 07 08 09 10 11 12 13 14 60 #!/bin/bash declare ‑A dirs for f in “$@”; do d=`getDir “$f”` mkdir ‑p “$d” mv ‑f “$f” “$d” dirs[$d]=1 done for d in “${!dirs[@]}”; do createIndex “$d” done segundo suas propriedades – por exemplo, a data de criação. O script possui dois problemas fundamen­ tais: primeiro, ele não funciona com diretórios que contenham espaços em branco, e segundo, ele pode processar cada diretório mais de uma vez. As versões anteriores do Bash usavam técnicas diferentes para re­ solver esse problema. No Bash 3.2, os programadores podem armaze­ nar os nomes de diretórios entre aspas num vetor. Um script poderia evitar o duplo processamento por meio de buscas no nome – ou por meio de uma lenta busca linear no vetor. Nenhuma dessas técnicas é particularmente elegante. O Bash 4 lida com essa tarefa de forma bem mais simples (veja a listagem 3): o nome do diretó­ rio serve como chave; o valor não tem importância. Na linha 12, o loop itera por todas as chaves. A construção especial com alguns & entre aspas duplas faz o mesmo que em outros pontos do Bash: faz com que o shell processe os valo­ res como elementos individuais. Portanto, a solução funciona com diretórios que contenham espaços em branco. Arquivos A listagem 4 contém um padrão de programação típico. O loop while nas linhas 5 a 8 processa as linhas de um arquivo uma após a outra e guarda o resultado num vetor. Essa construção ocorre com frequência, mas infelizmente é imperfeita. Caso a úlima linha não termine com um caractere de nova linha, o loop não armazenará a linha. O comando read embutido não fará a atribuição sem a nova linha. A nova versão do Bash não ape­ nas economiza teclas como tam­ bém oferece uma implementação mais limpa. Em vez do loop while, uma única linha já faz todo o tra­ balho sujo (linha 4 da listagem 5). O comando mapfile usa o “apelido” readarray, que descreve seu propósito de forma mais precisa. O comando mapfile pode até fazer mais que isso. Para mais detalhes, help mapfile e man mapfile devem ajudar bastante. O comando pode processar múltiplas linhas de uma única vez e processá-las uma a uma com uso de uma função callback. Infelizmente, os desenvolvedores não forneceram uma implementação es­ pecialmente elegante dessa função. O Bash 4 chama a função callback antes de processá-la, e não depois. Essa técnica oferece ao script um callback antes de o shell de fato ler algo, mas perde um callback após a última linha. Apesar dessa com­ plicação, a função ainda é útil para processar arquivos inteiros. Caixa alta e baixa Se você já precisou implementar uma técnica robusta para processa­ mento de arquivos de configuração ou entrada de usuários, já conhece o seguinte problema: o valor no ar­ quivo de configuração ou o resultado da operação read pode ser SIM, sim, Sim, YES, true ou eViDentemEnte. Até o Bash 3.2, os autores de scripts usavam o utilitário externo tr para converter o valor para caixa alta ou baixa. O Bash 4 facilita isso. A instrução declare -u Variável converte auto­ maticamente todas as atribuições da variável Variável para caixa alta. De forma análoga, declare -l converte para caixa baixa. Essas ferramentas de conversão economizam chamadas a programas externos e melhoram o desempenho do script. Para con­ verter apenas uma vez, em vez de globalmente, é possível usar a nova extensão de parâmetro: foo=SIM echo ${foo^} echo ${foo^^} http://www.linuxmagazine.com.br Bash 4 | ANÁLISE Quadro 1: Entrevista com o desenvolvedor do Bash 4 Chet Ramey Chat Ramey é gerente do Grupo de Segurança e Engenharia de Redes da divisão de serviços de TI da Case Western Reserve University. Ele é o mantenedor do Bash desde 1990. A Linux Magazine fez algumas perguntas a ele com relação à última versão do Bash. A comunidade do Software Livre não via uma nova versão do Bash há algum tempo. Alguns dizem que a versão 3.2 era adequada para praticamente todas as tarefas necessárias. Então, por que algo novo?  Bash 4 também acrescentou diversos novos recurO sos para usuários da linha de comando. Agora ele está pronto para competir com shells especializadas nisso, como o Zsh? Fico feliz que as pessoas tenham uma opinião tão boa sobre o Bash 3.2. Eu não gosto de lançar novas versões com muita frequência, pois o shell é muito básico para vários distribuidores, mas já estava na hora. O Bash 4.0 oferece diversos recursos novos (normalmente eu não incluo grandes recursos novos em versões de atualização), várias correções de falhas que não entraram como patches no 3.2, e mais funcionalidades para os recursos já presentes.  A  cho que sim. O Bash talvez não tenha tantas funcionalidades embutidas, mas acho que oferece ferramentas suficientes para torná-lo um ambiente interativo tão bom quanto o Zsh. Quais os três avanços ou novos recursos que você acha mais interessantes? Vejamos. Essa é difícil, porque há várias que são boas. 1  . Vetores associativos; 2  . A correção para o último trecho incompatível com Posix. O shell não exige mais os parênteses balanceados ao processar substituições de comandos no estilo $(...) (por exemplo, ao processar uma instrução case dentro de uma substituição de comando). Estou empolgado com isso porque foi, certamente, a parte mais complicada para implementar. Não foi fácil com um parser gerado pelo yacc. 3  . As melhorias possíveis com o bind -x. Ao executar um comando associado a uma sequência chave com bind -x, esse comando terá acesso ao buffer do readline e à posição atual do cursor e poderá alterá-la. Uma função de shell poderia chamar um programa externo para rearranjar as palavras na linha de comando, por exemplo, e fazer com que se refletissem no buffer de edição. Acho que esse recurso ainda não foi muito usado, mas há várias possibilidades. O Bash 4 acrescentou vários novos recursos para facilitar a programação. Você acha que ele já consegue competir com linguagens como Perl e Python? Acho que Perl e Python são linguagens mais sofisticadas, pois têm muito mais funções embutidas. Shells em geral são feitas para “grudar” programas externos ou funções de shell, além de oferecerem um ambiente para facilitar essas tarefas. Porém, é possível escrever programas bastante complexos usando shell: veja o bash debugger, por exemplo. Linux Magazine #58 | Setembro de 2009  H  á algumas discussões sobre estilos de programação e uso de recursos em shell scripts. Enquanto alguns tradicionalistas exigem compatibilidade com o Bourne shell, outros usam inúmeros recursos do Bash. Qual o seu ponto de vista? E a compatibilidade com o Bash 3.2? Você recomenda adotar o 4.0 imediatamente ou deixá-lo em paralelo com o 3.2 por certo tempo?  A  cho que depende dos seus objetivos. É fato que quando pedem “compatibilidade total com o Bourne shell”, referem-se à versão do sh presente em suas máquinas. Há diferentes versões do Bourne shell: v7, SVR2, SVR3, SVR4, SVR4.2... E fornecedores distintos acrescentam diferentes conjuntos de recursos à mesma versão do Bourne shell. É difícil descobrir exatamente o que se quer dizer com “Bourne shell original”. Para quem se interessar em escrever scripts portáveis, eu sugeriria seguir o padrão Posix. Ele pode ser considerado uma linha de base que todos os shells padrão implementam. Muitos – senão todos – fornecedores incluem um shell que obedece ao Posix. E se o seu fornecedor não incluir um, o Bash é compatível com praticamente todas as plataformas existentes.  Com relação à retrocompatibilidade com o Bash 3.2, tentei mantê-la ao máximo. Em certos locais, achei que o comportamento do Bash 3.2 era errado e o corrigi, sacrificando a retrocompatibilidade. Também existe a noção do “nível de compatibilidade” do shell, que preserva explicitamente certos comportamentos antigos quando ativado (veja as opções compat31 e compat32 do Bash). Creio que o nível de compatibilidade com o Bash 3.2 é bem alto e não deveria afetar a portabilidade dos scripts.  cho que a compatibilidade é suficiente para os usuáA rios atualizarem para o Bash 4.0 imediatamente e gradativamente acostumarem-se com os novos recursos. 61 ANÁLISE  | Bash 4 Listagem 4: Técnica antiga para processar arquivos 01 02 03 04 05 06 07 08 09 10 #!/bin/bash inputFile=”$1” i=0 while read line; do lines[$i]=”$line” let i++ done < “$inputFile” echo {05..15} # Processamento das linhas... Listagem 5: Nova técnica para processar arquivos 01 02 03 04 05 06 #!/bin/bash inputFile=”$1” mapfile ‑n 0 lines < “$inputFile” # Processamento das linhas... O primeiro comando converte a primeira letra para caixa alta e imprime Sim. O segundo converte todas as letras, portanto retorna SIM. Se for necessário converter para caixa baixa, pode-se usar: foo=SIM echo ${foo,} echo ${foo,,} A sintaxe ${Var^Padrão} suporta substituições ainda mais complexas. Co-processos e listas A maioria dos fabricantes de hardware atuais oferecem processadores com múltiplos núcleos, e já começam a aparecer técnicas para explorar essas funcionalidades. O Bash 4 permite ao programador executar o que se chama de “co-processos”: difícil de ler. Porém, se for preciso ordenar esse tipo de saída, as versões anteriores do Bash não ajudavam, pois eram incapazes de inserir um zero à frente dos números menores que dez. O Bash 4 já faz isso: cularmente útil para shell scripts que tratam com processamento paralelo [5]. Listas de valores automáticos, ou expansões de chaves, já existem há tempos, mas eram desconhecidas pela maioria dos usuários: o comando echo {5..15} conta do primeiro até o último número. Muitos programa­ dores Bash ainda usam o programa externo seq para isso: echo $(seq -s “ “ 5 15) O comando seq não apenas é mais lento, como seu resultado é mais A nova versão da shell padrão do GNU/Linux oferece alguns recursos úteis para os programadores e fãs da linha de comando. Apesar de algu­ mas pequenas incompatibilidades, o mantenedor do Bash incentiva os usuários a fazer a atualização (con­ fira a entrevista no quadro 1). A nova versão do Bash não é exa­ tamente magra – o binário agora ocupa 730 KB, em lugar dos 590 KB da versão anterior. Ele é mensuravel­ mente, mas não perceptivelmente, mais lento; os tempos de execução mais longos dificilmente devem ser problemáticos em hardwares atuais. Para usar as novas funções hoje, é preciso ter controle total sobre o ambiente para substituir todo o Bash. Em algums scripts, talvez seja preciso consultar as variáveis de ambiente BASH_VERSION e BASH_ VERSINFO para se assegurar da ver­ são em execução. Caso a versão não seja a 4, simplesmente termi­ ne o script graciosamente e emita uma mensagem de erro explicando o motivo.  n Mais informações [1] Zsh: http://www.zsh.org [2] Bash: http://tiswww.case.edu/php/chet/bash/bashtop.html [3] Bernhard Bablok, “Shell paralelo”: http://lnm.com.br/article/2586 coproc pipes comando Este comando retorna os descri­ tores de entrada e saída padrão do comando nas variáveis pipes[0] e pipes[1]. O processo principal do Bash os utiliza para se comunicar com o co-processo, o que é parti­ 62 Gostou do artigo? Queremos ouvir sua opinião. Fale conosco em [email protected] Este artigo no nosso site: http://lnm.com.br/article/2998 http://www.linuxmagazine.com.br Bash 4 | ANÁLISE SEÇÃO Linux Magazine #58 | Setembro de 2009 63