1 Bash e scripts bash #
Atualmente, muitas pessoas usam computadores com uma GUI (Graphical User Interface – Interface Gráfica do Usuário), como o GNOME. As GUIs oferecem muitos recursos, mas elas são limitadas para executar tarefas automatizadas. Os shells são um bom complemento às GUIs, e este capítulo apresenta uma visão geral de vários aspectos deles; neste caso, o shell Bash.
1.1 O que é “o shell”? #
Normalmente, o shell do Linux é o Bash (Bourne again Shell). Quando este capítulo menciona “o shell”, ele se refere ao Bash. Há mais shells disponíveis (ash, csh, ksh, zsh, etc.), cada um deles empregando recursos e características diferentes. Se você precisar de mais informações sobre outros shells, pesquise por shell no YaST.
1.1.1 Arquivos de configuração do Bash #
Um shell pode ser acionado como:
Shell de login interativo. Ele é usado para efetuar login em uma máquina, chamando o Bash com a opção
--login
, ou para efetuar login em uma máquina remota com SSH.Shell interativo “comum”. Normalmente, este é o caso ao iniciar o xterm, o konsole, o gnome-terminal ou as ferramentas semelhantes de interface de linha de comando (CLI, Command Line Interface).
Shell não interativo. Ele é invocado para chamar um script de shell na linha de comando.
Cada shell lê arquivos de configuração diferentes. As tabelas seguintes mostram os arquivos de configuração de shell de login e sem login.
O Bash procura os arquivos de configuração em uma ordem específica, dependendo do tipo de shell em que ele é executado. Encontre mais detalhes na página de manual do Bash (man 1 bash
). Procure o título INVOCATION
.
Arquivo |
Descrição |
---|---|
|
Não modifique esse arquivo, senão as suas modificações poderão ser destruídas durante a próxima atualização. |
|
Use esse arquivos se for estender |
|
Contém arquivos de configuração de programas específicos para todo o sistema |
|
Insira aqui a configuração específica de usuário para os shells de login |
O shell de login também extrai os arquivos de configuração listados na Tabela 1.2, “Arquivos de configuração do Bash para shells sem login”.
|
Não modifique esse arquivo, senão as suas modificações poderão ser destruídas durante a próxima atualização. |
|
Use esse arquivo para inserir suas modificações apenas do Bash em todo o sistema |
|
Insira aqui a configuração específica de usuário |
Além disso, o Bash usa vários arquivos:
Arquivo |
Descrição |
---|---|
|
Contém uma lista de todos os comandos que você digitou |
|
Executado durante o logout |
|
Áliases definidos pelo usuário dos comandos usados com frequência. Consulte |
Shells sem login#
Há shells especiais que impedem que os usuários efetuem login no sistema: /bin/false
e /sbin/nologin
. Os dois apresentam uma falha silenciosa quando o usuário tenta efetuar login no sistema. Isso foi planejado como uma medida de segurança para os usuários do sistema, embora os sistemas operacionais Linux modernos tenham ferramentas mais eficazes para controlar o acesso ao sistema, como PAM e AppArmor.
O padrão no SUSE Linux Enterprise Desktop é atribuir /bin/bash
a usuários humanos e /bin/false
ou /sbin/nologin
a usuários do sistema. O usuário nobody
tem o /bin/bash
por razões de histórico, já que se trata de um usuário com privilégios mínimos que costumava ser o padrão para usuários de sistema. No entanto, o pouco de segurança obtida com o uso de nobody
se perde quando vários usuários de sistema o utilizam. Talvez seja possível mudá-lo para /sbin/nologin
. A forma mais rápida de fazer esse teste é mudá-lo e verificar se isso corrompe quaisquer serviços ou aplicativos.
Use o comando a seguir para listar os shells que são atribuídos a todos os usuários, tanto de sistema quanto humanos, em /etc/passwd
. A saída varia de acordo com os serviços e os usuários no sistema:
>
sort -t: -k 7 /etc/passwd | awk -F: '{print $1"\t" $7}' | column -t
tux /bin/bash
nobody /bin/bash
root /bin/bash
avahi /bin/false
chrony /bin/false
dhcpd /bin/false
dnsmasq /bin/false
ftpsecure /bin/false
lightdm /bin/false
mysql /bin/false
postfix /bin/false
rtkit /bin/false
sshd /bin/false
tftp /bin/false
unbound /bin/false
bin /sbin/nologin
daemon /sbin/nologin
ftp /sbin/nologin
lp /sbin/nologin
mail /sbin/nologin
man /sbin/nologin
nscd /sbin/nologin
polkitd /sbin/nologin
pulse /sbin/nologin
qemu /sbin/nologin
radvd /sbin/nologin
rpc /sbin/nologin
statd /sbin/nologin
svn /sbin/nologin
systemd-coredump /sbin/nologin
systemd-network /sbin/nologin
systemd-timesync /sbin/nologin
usbmux /sbin/nologin
vnc /sbin/nologin
wwwrun /sbin/nologin
messagebus /usr/bin/false
scard /usr/sbin/nologin
1.1.2 Estrutura de diretórios #
A tabela a seguir fornece uma breve visão geral dos mais importantes diretórios de nível superior encontrados em um sistema Linux. Informações mais detalhadas sobre os diretórios e subdiretórios importantes são encontradas na lista a seguir.
Diretório |
Conteúdo |
---|---|
|
Diretório raiz: o ponto de partida da árvore do diretório. |
|
Arquivos binários essenciais, como comandos necessários pelo administrador do sistema e por usuários comuns. Geralmente contém os shells, como o Bash. |
|
Arquivos estáticos do carregador de boot. |
|
Arquivos necessários para acessar dispositivos específicos de host. |
|
Arquivos de configuração do sistema específicos de host. |
|
Contém os diretórios pessoais de todos os usuários que possuem conta no sistema. Porém, o diretório pessoal do |
|
Bibliotecas compartilhadas e módulos de kernel essenciais. |
|
Pontos de montagem de mídia removível. |
|
Ponto de montagem para montar temporariamente um sistema de arquivos. |
|
Pacotes de aplicativos complementares. |
|
Diretório pessoal do superusuário |
|
Binários essenciais do sistema. |
|
Dados de serviços fornecidos pelo sistema. |
|
Arquivos temporários. |
|
Hierarquia secundária com dados apenas leitura. |
|
Dados variáveis, como arquivos de registro. |
|
Disponível apenas se você tiver o Microsoft Windows* e o Linux instalados no sistema. Contém os dados do Windows. |
A lista a seguir fornece informações mais detalhadas e alguns exemplos de arquivos e subdiretórios encontrados nos diretórios:
/bin
Contém os comandos básicos do shell que podem ser usados pelo usuário
root
e por outros usuários. Esses comandos incluemls
,mkdir
,cp
,mv
,rm
ermdir
. O/bin
também contém o Bash, o shell padrão do SUSE Linux Enterprise Desktop./boot
Contém dados necessários para inicializar, como o carregador de boot, o kernel e outros dados usados para que o kernel possa executar programas em modo de usuário.
/dev
Contém arquivos de dispositivos que representam componentes de hardware.
/etc
Contém arquivos de configuração local que controlam a operação de programas como o Sistema X Window. O subdiretório
/etc/init.d
contém scripts init LSB que podem ser executados durante o processo de boot./home/USERNAME
Contém os dados privados de todos os usuários que possuem uma conta no sistema. Os arquivos localizados aqui apenas podem ser modificados por seu proprietário ou pelo administrador do sistema. Por padrão, o diretório de e-mail e a configuração de área de trabalho pessoal estão localizados aqui, na forma de arquivos e diretórios ocultos, como
.gconf/
e.config
.Nota: Diretório pessoal em um ambiente de redeSe você estiver trabalhando em um ambiente de rede, seu diretório pessoal poderá ser mapeado para um diretório no sistema de arquivos diferente de
/home
./lib
Contém as bibliotecas compartilhadas essenciais necessárias para inicializar o sistema e executar os comandos no sistema de arquivos raiz. O equivalente no Windows para as bibliotecas compartilhadas são os arquivos DLL.
/media
Contém pontos de montagem para mídia removível, como CD-ROMs, discos flash e câmeras digitais (se usarem USB).
/media
geralmente mantém qualquer tipo de unidade, exceto o disco rígido do sistema. Quando o meio removível for inserido ou conectado ao sistema e estiver montado, você poderá acessá-lo deste local./mnt
O diretório fornece um ponto de montagem para um sistema de arquivos montado temporariamente. O
root
pode montar sistemas de arquivos aqui./opt
Reservado para a instalação de software de terceiros. Software opcional e pacotes de programas complementares maiores são encontrados aqui.
/root
Diretório pessoal do usuário
root
. Os dados pessoais doroot
estão localizados aqui./run
Um diretório tmpfs usado pelo
systemd
e por vários componentes./var/run
é um link simbólico para/run
./sbin
Como indicado pelo
s
, esse diretório contém utilitários do superusuário./sbin
contém os binários essenciais para inicialização, restauração e recuperação do sistema, além dos binários em/bin
./srv
Contém dados de serviços fornecidos pelo sistema, como FTP e HTTP.
/tmp
Esse diretório é usado por programas que exigem o armazenamento temporário dos arquivos.
Importante: Limpando o/tmp
no momento da inicializaçãoOs dados armazenados em
/tmp
não têm uma garantia de existir após a reinicialização do sistema. Isso depende, por exemplo, das configurações feitas em/etc/tmpfiles.d/tmp.conf
./usr
O
/usr
não tem relação com os usuários, mas se trata do acrônimo de Unix system resources (recursos do sistema Unix). Os dados em/usr
são estáticos, apenas leitura e podem ser compartilhados com vários hosts compatíveis comFilesystem Hierarchy Standard
(FHS). Este diretório contém todos os programas de aplicativo, incluindo as áreas de trabalho gráficas, como o GNOME, e estabelece uma hierarquia secundária no sistema de arquivos./usr
contém vários subdiretórios, como/usr/bin
,/usr/sbin
,/usr/local
e/usr/share/doc
./usr/bin
Contém programas geralmente acessíveis.
/usr/sbin
Contém programas reservados ao administrador do sistema, como as funções de reparo.
/usr/local
Nesse diretório, o administrador do sistema pode instalar extensões locais e independentes de distribuição.
/usr/share/doc
Contém vários arquivos de documentação e as notas de versão do sistema. No subdiretório
manual
, você encontra uma versão online deste manual. Se houver mais de um idioma instalado, esse diretório poderá conter versões dos manuais em idiomas diferentes.Em
packages
, você encontra a documentação incluída nos pacotes de software instalados no sistema. Para cada pacote, é criado um subdiretório/usr/share/doc/packages/PACKAGENAME
, geralmente contendo arquivos README do pacote e, às vezes, exemplos, arquivos de configuração ou scripts adicionais.Se houver HOWTOs instalados no sistema,
/usr/share/doc
também incluirá o subdiretóriohowto
com documentação adicional sobre muitas tarefas relacionadas à configuração e operação do software Linux./var
Ao passo que
/usr
contém dados estáticos apenas leitura,/var
destina-se aos dados gravados durante a operação do sistema, portanto variáveis, como arquivos de registro ou dados de spooling. Para obter uma visão geral dos arquivos de registro mais importantes que estão em/var/log/
, consulte a Tabela 42.1, “Arquivos de registro”./windows
Disponível apenas se você tiver o Microsoft Windows e o Linux instalados no sistema. Contém os dados do Windows disponíveis na partição do Windows do sistema. A sua capacidade de editar dados nesse diretório depende do sistema de arquivos usado pelas partições do Windows. No caso do FAT32, você pode abrir e editar os arquivos desse diretório. Para NTFS, o SUSE Linux Enterprise Desktop também oferece suporte a acesso de gravação. No entanto, o driver para o sistema de arquivos NTFS-3g possui funcionalidade limitada.
1.2 Gravando scripts shell #
Os scripts shell são um modo conveniente para executar uma ampla gama de tarefas: coleta de dados, pesquisa por uma palavra ou frase em um texto e muitas outras coisas úteis. O exemplo seguinte mostra um pequeno script shell que imprime um texto:
#!/bin/sh 1 # Output the following line: 2 echo "Hello World" 3
A primeira linha começa com os caracteres Shebang ( | |
A segunda linha é um comentário que começa com o sinal de hash. É recomendável comentar linhas difíceis. Com o comentário apropriado, você pode se lembrar da finalidade e da função da linha. Além disso, outros leitores poderão entender seu script. O comentário é considerado uma boa prática na comunidade de desenvolvimento. | |
A terceira linha usa o comando interno |
Antes que você possa executar esse script, há alguns pré-requisitos:
Todo script deve conter uma linha Shebang (como no exemplo acima). Se a linha estiver ausente, você precisará chamar o interpretador manualmente.
Grave o script no lugar desejado. Contudo, convém gravá-lo em um diretório onde o shell possa encontrá-lo. O caminho de pesquisa em um shell é determinado pela variável de ambiente
PATH
. Um usuário normal não tem acesso de gravação a/usr/bin
. Por essa razão, recomenda-se gravar seus scripts no diretório~/bin/
dos usuários. O exemplo acima leva o nomehello.sh
.O script requer permissões de executável. Defina as permissões com o seguinte comando:
>
chmod +x ~/bin/hello.sh
Se você atendeu a todos os pré-requisitos acima, pode executar o script das seguintes maneiras:
Como caminho absoluto. O script pode ser executado em um caminho absoluto. No nosso caso, ele é
~/bin/hello.sh
.Em todos os lugares. Se a variável de ambiente
PATH
incluir o diretório no qual o script está localizado, você poderá executar o script usando o comandohello.sh
.
1.3 Redirecionando eventos de comando #
Cada comando pode usar três canais, seja para entrada ou para saída:
Saída padrão. Esse é o canal de saída padrão. Sempre que um comando imprime algo, ele usa o canal de saída padrão.
Entrada padrão. Se um comando precisar da entrada dos usuários ou de outros comandos, ele usará esse canal.
Erro padrão. Os comandos usam esse canal para gerar relatórios de erros.
Para redirecionar os canais, as possibilidades são as seguintes:
Command > File
Grava a saída do comando em um arquivo. O arquivo existente é apagado. Por exemplo, o comando
ls
grava sua saída no arquivolisting.txt
:>
ls > listing.txtCommand >> File
Anexa a saída do comando a um arquivo. Por exemplo, o comando
ls
anexa sua saída ao arquivolisting.txt
:>
ls >> listing.txtCommand < File
Lê o arquivo como entrada do comando em questão. Por exemplo, o comando
read
extrai o conteúdo do arquivo para a variável:>
read a < fooCommand1 | Command2
Redireciona a saída do comando à esquerda como entrada para o comando à direita. Por exemplo, o comando
cat
retorna o conteúdo do arquivo/proc/cpuinfo
. Essa saída é usada porgrep
para filtrar apenas as linhas que contêmcpu
:>
cat /proc/cpuinfo | grep cpu
Cada canal possui um descritor de arquivo: 0 (zero) para entrada padrão, 1 para saída padrão e 2 para erro padrão. É permitido inserir esse descritor de arquivo antes de um caractere <
ou >
. Por exemplo, a linha a seguir procura por um arquivo que começa com foo
, mas suprime seus erros redirecionando-o para /dev/null
:
>
find / -name "foo*" 2>/dev/null
1.4 Usando álias #
Um álias é uma definição de atalho de um ou mais comandos. A sintaxe de um álias é a seguinte:
alias NAME=DEFINITION
Por exemplo, a linha a seguir define um álias lt
que gera uma listagem extensa (opção -l
), classifica-a por horário de modificação (-t
) e imprime-a em ordem de classificação inversa (-r
):
>
alias lt='ls -ltr'
Para ver todas as definições de álias, use alias
Remova seu álias com unalias
e o nome do álias correspondente.
1.5 Usando variáveis no Bash #
Uma variável de shell pode ser global ou local. Variáveis globais, ou de ambiente, podem ser acessadas em todos os shells. As variáveis locais, ao contrário, são visíveis apenas no shell atual.
Para ver todas as variáveis de ambiente, use o comando printenv
. Se for preciso saber o valor de uma variável, insira o nome da variável como argumento:
>
printenv PATH
Uma variável, seja ela global ou local, também pode ser visualizada com echo
:
>
echo $PATH
Para definir uma variável local, use um nome de variável, seguido pelo sinal de igual, seguido pelo valor:
>
PROJECT="SLED"
Não insira espaços antes e depois do sinal de igual, senão você obterá um erro. Para definir uma variável de ambiente, use export
:
>
export NAME="tux"
Para remover uma variável, use unset
:
>
unset NAME
A tabela a seguir contém variáveis de ambiente comuns que você pode usar em seus scripts de shell:
|
diretório pessoal do usuário atual |
|
nome do host atual |
|
quando uma ferramenta é localizada, ela usa o idioma dessa variável de ambiente. Também é possível definir o idioma inglês como |
|
caminho de pesquisa do shell, uma lista de diretórios separados por dois-pontos |
|
especifica o prompt normal impresso antes de cada comando |
|
especifica o prompt secundário impresso quando você executa um comando em várias linhas |
|
diretório de trabalho atual |
|
usuário atual |
1.5.1 Usando variáveis de argumento #
Por exemplo, se você tiver o script foo.sh
, poderá executá-lo desta maneira:
>
foo.sh "Tux Penguin" 2000
Para acessar todos os argumentos que são passados ao seu script, você precisa de parâmetros de posição. São eles: $1
para o primeiro argumento, $2
para o segundo etc. É possível usar até nove parâmetros. Para obter o nome do script, use $0
.
O script foo.sh
a seguir imprime todos os argumentos de 1 a 4:
#!/bin/sh echo \"$1\" \"$2\" \"$3\" \"$4\"
Se você executar esse script com os argumentos acima, obterá:
"Tux Penguin" "2000" "" ""
1.5.2 Usando substituição de variável #
As substituições de variáveis aplicam um padrão ao conteúdo de uma variável, seja da esquerda ou da esquerda. A lista a seguir contém as formas de sintaxe possíveis:
${VAR#pattern}
remove a correspondência mais curta possível da esquerda:
>
file=/home/tux/book/book.tar.bz2>
echo ${file#*/} home/tux/book/book.tar.bz2${VAR##pattern}
remove a correspondência mais longa possível da esquerda:
>
file=/home/tux/book/book.tar.bz2>
echo ${file##*/} book.tar.bz2${VAR%pattern}
remove a correspondência mais curta possível da direita:
>
file=/home/tux/book/book.tar.bz2>
echo ${file%.*} /home/tux/book/book.tar${VAR%%pattern}
remove a correspondência mais longa possível da direita:
>
file=/home/tux/book/book.tar.bz2>
echo ${file%%.*} /home/tux/book/book${VAR/pattern_1/pattern_2}
substitui o conteúdo de VAR de PATTERN_1 por PATTERN_2:
>
file=/home/tux/book/book.tar.bz2>
echo ${file/tux/wilber} /home/wilber/book/book.tar.bz2
1.6 Agrupando e combinando comandos #
Os shells permitem concatenar e agrupar comandos para uma execução condicional. Cada comando retorna um código de saída que determina o sucesso ou a falha de sua operação. Se o código for 0 (zero), significa que o comando obteve sucesso. Todos os outros códigos significam erro específico do comando.
A lista a seguir mostra como os comandos podem ser agrupados:
Command1 ; Command2
executa os comandos em sequência. O código de saída não é verificado. A linha a seguir exibe o conteúdo do arquivo com
cat
e depois imprime as propriedades dele comls
, independentemente dos códigos de saída:>
cat filelist.txt ; ls -l filelist.txtCommand1 && Command2
executa o comando à direita quando o comando à esquerda for bem-sucedido (E lógico). A linha a seguir exibe o conteúdo do arquivo e imprime suas propriedades apenas quando o comando anterior obtiver sucesso (compare com a entrada anterior nesta lista):
>
cat filelist.txt && ls -l filelist.txtCommand1 || Command2
executa o comando à direita quando o comando da esquerda falhar (OU lógico). A seguinte linha cria um diretório em
/home/wilber/bar
apenas quando há falha na criação do diretório em/home/tux/foo
:>
mkdir /home/tux/foo || mkdir /home/wilber/barfuncname(){ ... }
cria uma função shell. Você pode usar os parâmetros de posição para acessar seus argumentos. A linha a seguir define a função
hello
para imprimir uma mensagem curta:>
hello() { echo "Hello $1"; }Você pode chamar essa função assim:
>
hello Tuxque imprimirá:
Hello Tux
1.7 Trabalhando com construções de fluxo comuns #
Para controlar o fluxo do script, um shell tem as construções while
, if
, for
e case
.
1.7.1 Comando de controle if #
O comando if
é usado para verificar expressões. Por exemplo, o código a seguir testa se o usuário atual é Tux:
if test $USER = "tux"; then echo "Hello Tux." else echo "You are not Tux." fi
A expressão de teste pode ser tão complexa ou simples quanto possível. a expressão a seguir verifica se o arquivo foo.txt
existe:
if test -e /tmp/foo.txt ; then echo "Found foo.txt" fi
A expressão de teste também pode ser abreviada entre colchetes:
if [ -e /tmp/foo.txt ] ; then echo "Found foo.txt" fi
Outras expressões úteis estão disponíveis em https://bash.cyberciti.biz/guide/If..else..fi.
1.7.2 Criando loops com o comando for
#
O loop for
permite executar comandos para uma lista de entradas. Por exemplo, o código a seguir imprime determinadas informações sobre arquivos PNG no diretório atual:
for i in *.png; do ls -l $i done
1.8 Mais informações #
Informações importantes sobre o Bash são fornecidas nas páginas de manual man
bash
. Mais informações sobre este tópico estão disponíveis na lista a seguir:
https://tldp.org/LDP/Bash-Beginners-Guide/html/index.html — Bash Guide for Beginners (Guia do Bash para Iniciantes)
https://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html — BASH Programming - Introduction HOW-TO (COMO FAZER Programação de Bash: Introdução)
https://tldp.org/LDP/abs/html/index.html — Advanced Bash-Scripting Guide (Guia Avançado de Criação de Scripts Bash)
https://www.grymoire.com/Unix/Sh.html — Sh - the Bourne Shell (Sh: o Bourne Shell)