256 lines
9.3 KiB
Org Mode
256 lines
9.3 KiB
Org Mode
#+title: Shell Script na Prática
|
|
#+author: Blau Araujo
|
|
#+email: blau@debxp.org
|
|
|
|
|
|
* Desafio 1: Salve, simpatia
|
|
|
|
** Objetivos
|
|
|
|
- O que é um shell
|
|
- O que são scripts
|
|
- Como criá-los
|
|
- Como executá-los
|
|
- Como imprimir mensagens no terminal
|
|
- O que são variáveis
|
|
- O que são argumentos
|
|
- O que são parâmetros
|
|
- O que são expansões de parâmetros
|
|
|
|
** Enunciado
|
|
|
|
Imprimir a mensagem ~Salve, simpatia!~ no terminal.
|
|
|
|
** Evolução 1
|
|
|
|
Tornar o conteúdo da mensagem dependente do valor associado à variável ~nome~,
|
|
que substituirá a palavra ~simpatia~.
|
|
|
|
** Evolução 2
|
|
|
|
Tornar o conteúdo da mensagem dependente do primeiro argumento passado na
|
|
invocação do script, que substituirá a palavra ~simpatia~.
|
|
|
|
** Evolução 3
|
|
|
|
Tornar a impressão da palavra ~simpatia~ condicionada à ausência do primeiro
|
|
argumento na invocação do script.
|
|
|
|
-----
|
|
|
|
* Anotações da aula 1
|
|
|
|
** O que é um shell
|
|
|
|
Em sistemas parecidos com o Unix (/unix-like/), como o GNU/Linux, o shell é um
|
|
programa que exerce três funções básicas:
|
|
|
|
*Interface padrão entre o usuário e o sistema:*
|
|
|
|
- Quando um terminal é disponibilizado para o usuário, um shell é iniciado para
|
|
que o usuário digite seus comandos;
|
|
|
|
- Quando o usuário tecla =ENTER=, a linha com o seu comando é enviado para o
|
|
shell;
|
|
|
|
- O shell, então, inicia o processamento da linha do comando para determinar o
|
|
que deve ser executado;
|
|
|
|
- Ao fim do processamento, o shell providencia a execução do que foi solicitado
|
|
pelo usuário.
|
|
|
|
*Interpretador de comandos:*
|
|
|
|
No papel de interpretador, o shell deve processar a linha do comando digitado
|
|
pelo usuário a fim de determinar o que deve ser executado.
|
|
|
|
O shell pode interpretar comandos de dois modos:
|
|
|
|
- *Modo interativo:* os comandos são digitados diretamente no terminal e
|
|
executados um a um.
|
|
|
|
- *Modo não interativo:* os comandos são escritos antes do shell ser executado
|
|
para interpretá-los, como em scripts ou como argumentos da opção =-c= do shell.
|
|
|
|
*Plataforma de operação do sistema:*
|
|
|
|
Como o shell é a interface padrão do sistema, além de seus comandos e mecanismos
|
|
internos, inúmeros programas, para as mais diversas finalidades, são criados para
|
|
serem utilizados no terminal através do shell, o que termina por constituir um
|
|
ambiente de operação completo e coerente (uma /plataforma/) para a execução de
|
|
tarefas e operação do sistema.
|
|
|
|
** O que é um comando
|
|
|
|
Um /comando/ é a expressão da vontade do usuário na forma de uma linha de texto
|
|
escrita segundo uma sintaxe bem definida. Na sua forma mais simples, um comando
|
|
é composto por:
|
|
|
|
#+begin_example
|
|
[EXPORTAÇÕES] [[INVOCAÇÃO] [ARGUMENTOS]] [REDIRECIONAMENTOS]
|
|
#+end_example
|
|
|
|
Onde:
|
|
|
|
- *Exportações:* Atribuições de /variáveis/, no formato ~NOME=VALOR~, que serão
|
|
exportadas para o programa ou comando que for /invocado/; caso a linha não
|
|
tenha uma ~INVOCAÇÃO~, as variáveis serão definidas para uso no próprio shell.
|
|
|
|
- *Invocação:* Palavra que corresponde ao que deve ser executado, podendo ser o
|
|
nome do arquivo executável ou um comando interno do shell (/builtin/).
|
|
|
|
- *Argumentos:* Todas as palavras escritas depois do nome do que estiver sendo
|
|
invocado é interpretada como /argumento/ da invocação e serão passadas para
|
|
o que vier a ser executado.
|
|
|
|
- *Redirecionamentos:* O que define o fim da lista de palavras que compõem a
|
|
~INVOCAÇÃO~ e seus eventuais ~ARGUMENTOS~ é o fim da linha ou a presença de
|
|
um /operador/; se o operador for composto pelos caracteres ~<~ ou ~>~, eles
|
|
indicarão que os dados produzidos pelo comando (a sua /saída/), em vez de
|
|
serem exibidos no terminal, serão escritos em um arquivo ou, na direção
|
|
contrária, que o comando receberá dados através da leitura de um arquivo.
|
|
|
|
** O que são scripts
|
|
|
|
Scripts são arquivos-texto contendo os comandos que o shell deve executar de
|
|
modo /não interativo/. Como parte de seus mecanismos internos, o shell oferece
|
|
diversos recursos para controlar como, quando e com que dados os comandos
|
|
devem ser executados -- em outras palavras, esses mecanismos tornam possível
|
|
a criação de /programas/.
|
|
|
|
** Como criá-los
|
|
|
|
Para criar um script, basta criar um arquivo-texto com os comandos. Para isso,
|
|
nós precisamos de um editor (como: Vim, Nano, Micro, Emacs, etc) ou podemos
|
|
utilizar os próprios recursos do shell.
|
|
|
|
** Como executá-los
|
|
|
|
O conteúdo do script terá que ser interpretado e executado pelo shell, o que
|
|
pode ser feito de duas formas básicas:
|
|
|
|
*Arquivos sem permissão de execução*
|
|
|
|
Apenas arquivos com o atributo de execução ativados podem ser executados a
|
|
partir da invocação de seus nomes. Sem essa permissão, o nome do arquivo do
|
|
script pode ser passado como argumento da invocação do shell:
|
|
|
|
#+begin_example
|
|
:~$ bash meu-script.sh
|
|
#+end_example
|
|
|
|
*Arquivos com permissão de execução*
|
|
|
|
Se o atributo de execução estiver ativo, e o usuário tiver permissão para
|
|
executá-lo, basta invocar o caminho e o nome do arquivo do script:
|
|
|
|
#+begin_example
|
|
:~$ ./script1.sh # O script está no diretório onde é invocado.
|
|
:~$ ~/bin/script2.sh # O script está em /home/usuário/bin.
|
|
#+end_example
|
|
|
|
Contudo, quando iniciado no modo /interativo/, o shell recebe uma variável,
|
|
de nome ~PATH~, cujo valor associado é uma lista de diretórios em que arquivos
|
|
executáveis devem ser procurados. Se o script estiver em algum desses
|
|
diretórios, basta invocar seu nome:
|
|
|
|
#+begin_example
|
|
:~$ meu-script.sh
|
|
#+end_example
|
|
|
|
** Como o script é executado
|
|
|
|
A não ser que um interpretador seja especificado (ou invocado), todo
|
|
arquivo-texto será lido e executado como se contivesse apenas comandos
|
|
do shell em execução no terminal. Para especificar um interpretador
|
|
no próprio script, ele deve iniciar com uma /hashbang/ (~#!~), ou /linha do
|
|
interpretador de comandos/.
|
|
|
|
No caso do Bash, a /hashbang/ pode ser escrita de várias formas:
|
|
|
|
- ~#!/bin/bash~
|
|
- ~#!/usr/bin/bash~
|
|
- ~#!/usr/bin/env bash~
|
|
|
|
A presença da /hashbang/ na primeira linha do script diz ao shell quem
|
|
deverá ser utilizado para executar o conteúdo do arquivo. Internamente,
|
|
isso tem o mesmo efeito de:
|
|
|
|
#+begin_example
|
|
:~$ /bin/bash SCRIPT
|
|
#+end_example
|
|
|
|
** Como imprimir mensagens no terminal
|
|
|
|
Existem várias formas, mas o shell tem dois comandos internos dedicados
|
|
a essa finalidade:
|
|
|
|
- ~echo~: imprime seus argumentos separados por um espaço e com uma quebra
|
|
de linha do final.
|
|
|
|
- ~printf~: imprime seus argumentos conforme uma formatação especificada
|
|
como primeiro argumento.
|
|
|
|
** O que são variáveis
|
|
|
|
No shell, variáveis são /nomes/ que identificam valores que podem ser criados
|
|
e alterados. Para ser válido como identificador de uma valor, o nome deve
|
|
conter apenas caracteres alfabéticos maiúsculos e minúsculos, o caractere
|
|
sublinhado (~_~) e números, mas não pode começar com números.
|
|
|
|
** O que são parâmetros
|
|
|
|
O shell também faz associações entre identificadores e valores com variáveis.
|
|
Mas, os valores que não podem ser criados ou alterados diretamente por nós
|
|
são identificados por caracteres inválidos para /nomes/ (como números e outros
|
|
símbolos gráficos). Esses identificadores são chamados de /parâmetros/ e podem
|
|
ser classificados como /parâmetros posicionais/ e /parâmetros especiais/.
|
|
|
|
*Parâmetros posicionais:*
|
|
|
|
| Identificador | Valor associado |
|
|
|---------------+--------------------------------------------------------------|
|
|
| ~0~ | A palavra utilizada como ~INVOCAÇÃO~ na linha do comando |
|
|
| ~1..N~ | Cada palavra utilizada como ~ARGUMENTO~ conforme sua posição. |
|
|
| ~#~ | A quantidade de argumentos (exclui a invocação da contagem). |
|
|
| ~@~ | A lista de todas as palavras utilizadas como argumentos. |
|
|
| ~*~ | A lista de todas as palavras utilizadas como argumentos. |
|
|
|
|
*Parâmetros especiais:*
|
|
|
|
| Identificador | Valor associado |
|
|
|---------------+----------------------------------------------------------|
|
|
| ~-~ | As opções de início do shell (na forma de caracteres) |
|
|
| ~$~ | O número do /processo/ do shell em execução. |
|
|
| ~?~ | O estado de término do último comando (sucesso ou erro). |
|
|
| ~!~ | O número do último processo executado em segundo plano. |
|
|
|
|
** O que são expansões de parâmetros
|
|
|
|
No shell, tanto variáveis quanto parâmetros são chamados de /parâmetros/ e seus
|
|
valores são acessados através do mecanismo da /expansão/, que é o nome dado
|
|
a qualquer troca de símbolos ou identificadores na linha do comando pelos
|
|
seus respectivos valores.
|
|
|
|
No caso de variáveis e parâmetros, a expansão é indicada para o shell com o
|
|
caractere ~$~ escrito no início do identificador:
|
|
|
|
#+begin_example
|
|
$IDENTIFICADOR # Expande o valor associado a IDENTIFICADOR.
|
|
|
|
${IDENTIFICADOR} # Forma utilizada quando a expansão é modificada
|
|
# ou quando IDENTIFICADOR pode ser confundido com
|
|
# os caracteres seguintes na linha.
|
|
#+end_example
|
|
|
|
A coisa mais importante a saber sobre as expansões, é que elas são processadas
|
|
*antes* da linha do comando ser efetivamente executada. Portanto, no exemplo
|
|
abaixo...
|
|
|
|
#+begin_example
|
|
:~$ fruta=bananas
|
|
:~$ echo Vou comprar $fruta.
|
|
Vou comprar bananas.
|
|
#+end_example
|
|
|
|
A variável ~fruta~ teve seu valor expandido antes do comando ~echo~ ser executado.
|