
Oi, habrozhiteli! O best-seller internacional Linux Command Line o ajudará a superar o caminho desde os primeiros cliques tímidos nas teclas até a criação confiante de programas completos para a versão mais recente do bash - o shell Linux mais popular. A segunda edição fala sobre novos recursos no bash 4.x, como novos operadores de redirecionamento e operações curinga. Você aprenderá as habilidades atemporais da linha de comando: navegando no sistema de arquivos, configurando o ambiente, encadeando comandos e combinando com expressões regulares. Você compreenderá a filosofia por trás de muitas ferramentas de linha de comando, entenderá o rico legado adquirido pelos supercomputadores Unix e aprenderá sobre o conhecimento acumulado por gerações de gurus que excluíram o mouse de seu arsenal de ferramentas. Tendo superado o primeiro “choque de concha”, você entenderá como é natural e lógico esse modo de interagir com um computador.
Trecho. Capítulo 25. Início do projeto
Neste capítulo, começamos a criar o programa. O objetivo deste projeto é mostrar como você pode usar os vários recursos do shell para criar programas e, o mais importante, criar
bons programas.
Em seguida, escreveremos
um gerador de relatórios . Ele exibirá uma variedade de informações sobre o sistema e seu status no formato HTML, para que possa ser visualizado em um navegador da web.
Normalmente, a criação de programas é realizada em vários estágios, em cada um dos quais novas funções e recursos são adicionados. No final da primeira etapa, nosso programa reproduzirá uma página HTML mínima sem qualquer informação. Adicionaremos essas informações nas próximas etapas.
Etapa um: Documento mínimo
Primeiro, vamos determinar como é o formato de um documento HTML bem formado. Tem a seguinte forma:
<html> <head> <title> </title> </head> <body> . </body> </html>
Se você digitar esse texto em um editor de texto e salvá-lo em um arquivo chamado
foo.html , podemos abri-lo inserindo o seguinte URL no Firefox:
arquivo: ///home/username/foo.html .
No primeiro estágio, criaremos um programa que produzirá essa marcação HTML na saída padrão. Escrever um programa desse tipo é muito simples. Abra um editor de texto e crie um arquivo chamado ~ / bin / sys_info_page:
[me@linuxbox ~]$ vim ~/bin/sys_info_page
E, em seguida, insira o seguinte programa:
#!/bin/bash # echo "<html>" echo " <head>" echo " <title>Page Title</title>" echo " </head>" echo " <body>" echo " Page body." echo " </body>" echo "</html>"
Nossa primeira versão contém uma linha shebang, um comentário (bem-vindo) e uma sequência de comandos de eco, um para cada saída de linha. Depois de salvar o arquivo, torne-o executável e tente executar:
[me@linuxbox ~]$ chmod 755 ~/bin/sys_info_page [me@linuxbox ~]$ sys_info_page
Após o início, o texto do documento HTML deve aparecer na tela, porque os comandos echo no script enviam suas linhas para a saída padrão. Execute o programa novamente e redirecione a saída do programa para o arquivo
sys_info_page.html , para visualizar o resultado em um navegador da web:
[me@linuxbox ~]$ sys_info_page > sys_info_page.html [me@linuxbox ~]$ firefox sys_info_page.html
Até agora, tudo bem.
Ao desenvolver programas, lembre-se sempre da simplicidade e clareza. A manutenção é mais fácil quando o programa é fácil de ler e compreensível, sem mencionar o fato de que o programa é mais fácil de escrever quando é possível reduzir a quantidade de entrada manual. A versão atual do programa funciona muito bem, mas pode ser simplificada. A combinação de todos os comandos de eco em um só tornará mais fácil no futuro adicionar novas linhas à saída do programa. Portanto, alteramos o programa conforme mostrado abaixo:
#!/bin/bash # echo "<html> <head> <title>Page Title</title> </head> <body> Page body. </body> </HTML>"
As strings entre aspas podem incluir feeds de linha e, consequentemente, conter várias linhas de texto. O shell continuará lendo o texto até encontrar uma citação de fechamento. Esta regra também se aplica à linha de comando:
[me@linuxbox ~]$ echo "<html> > <head> > <title>Page Title</title> > </head> > <body> > Page body. > </body> > </html>"
O símbolo> no início de cada linha é um prompt para inserir um shell definido por sua variável PS2. Aparece sempre que uma instrução de várias linhas é inserida. Esse recurso ainda é obscuro, mas, quando nos familiarizamos com as instruções do programa de várias linhas, suas vantagens se tornam óbvias.
Etapa 2: adicionar alguns dados
Agora que o programa é capaz de gerar um documento mínimo, adicione alguns dados ao relatório. Para fazer isso, faça as seguintes alterações:
#!/bin/bash # echo "<html> <head> <title>System Information Report</title> </head> <body> <h1>System Information Report</h1> </body> </html>"
Aqui é adicionado o nome da página e o título no corpo do relatório.
Variáveis e constantes
Houve um problema no nosso script. Você notou que a linha do Relatório de informações do sistema é repetida duas vezes? Em geral, para um cenário tão pequeno, esse não é um problema tão grande, mas imagine um cenário realmente longo no qual essa linha seja repetida várias vezes. Se você precisar alterar o nome nesse cenário, precisará fazer alterações em muitos lugares, e isso é muito trabalho manual. É possível alterar o script para que a string seja definida apenas uma vez? Isso simplificaria bastante a manutenção do script no futuro. Sim, isso é possível, por exemplo, assim:
#!/bin/bash # title="System Information Report" echo "<html> <head> <title>$title</title> </head> <body> <h1>$title</h1> </body> </html>"
Criando uma
variável chamada title e atribuindo a ela o valor System Information Report, aproveitamos a substituição de parâmetros e colocamos a string em muitos lugares.
Mas como criar uma variável? Simples - basta usá-lo. Quando o shell encontra uma variável, ele a cria automaticamente. Isso difere de muitas linguagens de programação nas quais variáveis devem ser explicitamente declaradas ou definidas antes de serem usadas. O shell de comando é muito liberal nesse aspecto, o que acaba levando a alguns problemas. Por exemplo, considere o seguinte script executado na linha de comando:
[me@linuxbox ~]$ foo="yes" [me@linuxbox ~]$ echo $foo yes [me@linuxbox ~]$ echo $fool [me@linuxbox ~]$
Primeiro, atribuímos o valor yes à variável foo e depois emitimos seu valor com o comando echo. Em seguida, tentamos novamente exibir o valor da variável, mas cometemos um erro de digitação especificando o nome fool e obtivemos uma string vazia. Esse resultado é explicado pelo fato de que o shell criou com êxito a variável tolo ao encontrá-la e atribuiu a ele um valor padrão vazio. A partir deste exemplo, segue-se que você precisa monitorar cuidadosamente a ortografia! Também é importante entender o que realmente aconteceu neste exemplo. Pelo conhecimento prévio dos recursos do mecanismo de substituição, sabemos que a equipe
[me@linuxbox ~]$ echo $foo
é exposto ao mecanismo de substituição de parâmetros, como resultado do qual assume a forma
[me@linuxbox ~]$ echo yes
Por outro lado, a equipe
[me@linuxbox ~]$ echo $fool
se transforma em
[me@linuxbox ~]$ echo
Nada é substituído por uma variável vazia! Isso pode causar erros nos comandos que requerem argumentos. Por exemplo:
[me@linuxbox ~]$ foo=foo.txt [me@linuxbox ~]$ foo1=foo1.txt [me@linuxbox ~]$ cp $foo $fool cp: 'foo.txt' , "cp --help" .
Atribuímos valores a duas variáveis, foo e foo1. E então eles tentaram executar o comando cp, mas cometeram um erro de digitação no nome do segundo argumento. Após o processamento pelo mecanismo de pesquisa, o comando cp recebeu apenas um argumento, embora exija dois.
A seguir, algumas regras para nomear variáveis:
- Os nomes de variáveis podem consistir em caracteres alfanuméricos (letras e números) e sublinhados.
- O primeiro caractere em um nome de variável pode ser apenas uma letra ou um sublinhado.
- A presença de espaços e sinais de pontuação nos nomes de variáveis não é permitida.
A
variável name significa um valor que pode mudar e, em muitos aplicativos, as variáveis são usadas dessa maneira. No entanto, a variável title em nosso aplicativo é usada como uma
constante . Uma constante, como uma variável, tem um nome e contém um valor. A única diferença é que o valor da constante não muda. Em um aplicativo que executa cálculos geométricos, é possível definir uma constante PI com um valor de 3,1415, em vez de usar esse número em todo o programa. O shell não faz distinção entre constantes e variáveis; Esses termos são usados principalmente para a conveniência do programador. Uma convenção típica é usar letras maiúsculas para indicar constantes e letras minúsculas para variáveis verdadeiras. Vamos mudar o cenário para alinhar com esta convenção:
#!/bin/bash # TITLE="System Information Report For $HOSTNAME" echo "<html> <head> <title>$TITLE</title> </head> <body> <h1>$TITLE</h1> </body> </html>"
Ao longo do caminho, complementamos o nome adicionando o valor da variável do shell HOSTNAME ao final. Este é o nome da rede da máquina.
NOTA
De fato, o shell possui um mecanismo para garantir a imutabilidade das constantes, na forma de um comando de declaração interno com o parâmetro -r (somente leitura - somente leitura). Se você atribuir um valor à variável TITLE, como mostrado abaixo:
declare -r TITLE="Page Title"
o shell não permitirá que o valor seja reatribuído à variável TITLE. Esse mecanismo raramente é usado na prática, mas está disponível e pode ser usado em cenários particularmente rigorosos.
Atribuindo valores a variáveis e constantes
Chegamos ao momento em que nosso conhecimento das características da operação do mecanismo de substituição começa a dar frutos. Como vimos, a atribuição de valores a variáveis é feita assim:
=
onde a
variável é o nome da variável e o
valor é a sequência. Diferente de outras linguagens de programação, o shell não se importa com os tipos de valores atribuídos às variáveis; ela interpreta todos os valores como strings. É possível forçar o shell a limitar o intervalo de valores atribuídos a números inteiros usando o comando declare com a opção -i, mas, como declarar variáveis somente leitura, esse recurso raramente é usado na prática.
Observe que não há espaços no operador de atribuição entre o nome da variável, o sinal de igual e o valor. E em que consiste o significado? De qualquer coisa, você pode expandir para uma string.
a=z # a "z". b="a string" # . c="a string and $b" # , # , . d=$(ls -l foo.txt) # . e=$((5 * 7)) # . f="\t\ta string\n" # , # .
Em uma linha, você pode atribuir várias variáveis ao mesmo tempo:
a=5 b="a string"
Ao usar a substituição, os nomes de variáveis podem ser colocados entre chaves {}. Isso é útil quando o nome da variável se torna ambíguo no contexto circundante. O exemplo a seguir tenta renomear
myfile para
myfile1 usando uma variável:
[me@linuxbox ~]$ filename="myfile" [me@linuxbox ~]$ touch $filename [me@linuxbox ~]$ mv $filename $filename1 mv: 'myfile' , "mv --help" .
Essa tentativa não teve êxito porque o shell interpretou o segundo argumento do comando mv como o nome de uma nova variável (e vazia). A seguir, mostramos como resolver esse problema:
[me@linuxbox ~]$ mv $filename ${filename}1
Adicionando chaves, garantimos que o shell não interpretaria o último caractere 1 como parte do nome da variável.
Nota
Ao executar a substituição, é recomendável que os nomes e comandos das variáveis sejam colocados entre aspas duplas para impedir que o shell divida linhas em palavras. É especialmente importante usar aspas quando uma variável pode conter um nome de arquivo.
Usaremos esta oportunidade para adicionar dados adicionais ao relatório, como a data e a hora do relatório, bem como o nome do usuário que criou o relatório:
#!/bin/bash # TITLE="System Information Report For $HOSTNAME" CURRENT_TIME=$(date +"%x %r %Z") TIME_STAMP="Generated $CURRENT_TIME, by $USER" echo "<html> <head> <title>$TITLE</title> </head> <body> <h1>$TITLE</h1> <p>$TIME_STAMP</p> </body> </html>"
Documentos Incorporados
Examinamos dois métodos diferentes de saída de texto e ambos usam o comando echo. No entanto, existe outro terceiro método, chamado de
documento embutido (aqui documento) ou um
script embutido (aqui script). Um documento incorporado é uma forma adicional de redirecionamento de E / S que passa o texto incorporado em um script para a entrada de comando padrão. Esse redirecionamento funciona assim:
<<
onde o
comando é o nome do comando que recebe o texto especificado por meio da entrada padrão e o
indicador é a linha que marca o final do texto incorporado. Modificaremos o cenário usando o documento incorporado:
#!/bin/bash # TITLE="System Information Report For $HOSTNAME" CURRENT_TIME=$(date +"%x %r %Z") TIME_STAMP="Generated $CURRENT_TIME, by $USER" cat << _EOF_ <html> <head> <title>$TITLE</title> </head> <body> <h1>$TITLE</h1> <p>$TIME_STAMP</p> </body> </html> _EOF_
Em vez do comando echo, o script agora usa o comando cat e o documento incorporado. A linha _EOF_ foi escolhida para a função de indicador (significa
fim do arquivo -
fim do arquivo , acordo comum) e marca o final do texto incorporado. Observe que a linha do indicador deve estar em uma linha separada, uma e nenhum espaço deve segui-la.
Mas quais são os benefícios de usar o documento incorporado aqui? Praticamente nenhum, exceto que as aspas nos documentos incorporados perdem seu significado especial para o shell. A seguir, é apresentado um exemplo do uso de um documento incorporado na linha de comando:
[me@linuxbox ~]$ foo="some text" [me@linuxbox ~]$ cat << _EOF_ > $foo > "$foo" > '$foo' > \$foo > _EOF_ some text "some text" 'some text' $foo
Como você pode ver, o shell de comando não presta atenção às aspas. Ela os interpreta como personagens comuns. Graças a isso, inserimos livremente aspas nos documentos incorporados. Essa circunstância pode ser usada ao desenvolver programas de relatórios.
Os documentos incorporados podem ser usados com qualquer comando que aceite dados da entrada padrão. O exemplo a seguir usa um documento interno para enviar uma sequência de comandos ao programa ftp para baixar um arquivo de um servidor FTP remoto:
#!/bin/bash # FTP FTP_SERVER=ftp.nl.debian.org FTP_PATH=/debian/dists/stretch/main/installer-amd64/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz ftp -n << _EOF_ open $FTP_SERVER user anonymous me@linuxbox cd $FTP_PATH hash get $REMOTE_FILE bye _EOF_ ls -l $REMOTE_FILE
Se você substituir o operador de redirecionamento << por << -, o shell do comando ignorará os caracteres iniciais da guia no documento incorporado. Graças a isso, recuos podem ser adicionados ao documento incorporado para maior legibilidade:
#!/bin/bash # FTP FTP_SERVER=ftp.nl.debian.org FTP_PATH=/debian/dists/stretch/main/installer-amd64/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz ftp -n <<- _EOF_ open $FTP_SERVER user anonymous me@linuxbox cd $FTP_PATH hash get $REMOTE_FILE bye _EOF_ ls -l $REMOTE_FILE
No entanto, o uso desse recurso nem sempre é conveniente, pois para o recuo muitos editores de texto (e os próprios programadores) preferem usar caracteres de espaço em vez de guias.
Conclusão
Neste capítulo, começamos a desenvolver um projeto com o qual passaremos por todas as etapas da criação de um script. Nós nos familiarizamos com variáveis e constantes e os recursos de seu uso. Eles são mais frequentemente do que outros componentes de software usados para substituição. Também vimos como organizar a saída de informações em um script e nos familiarizamos com diferentes métodos de incorporação de blocos de texto.
Sobre o autor
William Shotts é um desenvolvedor de software profissional com mais de 30 anos de experiência que utiliza ativamente o sistema operacional Linux há mais de 20 anos. Ele tem uma vasta experiência em desenvolvimento de software, suporte técnico, controle de qualidade e documentação de redação. Ele também é o criador do LinuxCommand.org, um site educacional e educacional dedicado ao Linux, onde notícias, análises e suporte são fornecidos usando a linha de comando do Linux.
Sobre o Science Editor
Jordi Gutiérrez Hermoso é um programador de computadores, matemático e hacker ético. Desde 2002, ele usa exclusivamente o Debian GNU / Linux, não apenas em casa, mas também no trabalho. Jordi está envolvido no desenvolvimento do GNU Octave, um ambiente de computação livre que é amplamente compatível com o Matlab, bem como com o Mercurial, um sistema de controle de versão distribuído. Ele gosta de matemática pura e aplicada, patinação no gelo, natação e tricô. Recentemente, ele pensa muito nos problemas das emissões de gases de efeito estufa e participa de ações para salvar rinocerontes.
»Mais informações sobre o livro podem ser encontradas no
site do editor»
Conteúdo»
TrechoCupom de 25% de desconto para vendedores ambulantes -
LinuxApós o pagamento da versão impressa do livro, um livro eletrônico é enviado por e-mail.