Aprenda Linux, 101: A linha de comando do Linux

Familiarizando-se com comandos GNU e UNIX

As GUIs estão boas, mas, para revelar o poder real do Linux®, não há substituto para a linha de comando. Neste artigo, Ian Shields apresenta alguns dos principais recursos do bash shell, com ênfase nos recursos importantes para a certificação LPI. No final deste artigo, você se sentirá à vontade para usar os comandos básicos do Linux, como echo e exit, definir variáveis de ambiente e reunir informações do sistema. [[As duas primeiras observações que seguem a Listagem 8 foram atualizadas para corrigir os IDs do processo (PIDs). -Ed.]

Ian Shields, Senior Programmer, IBM

Ian Shields works on a multitude of Linux projects for the developerWorks Linux zone. He is a Senior Programmer at IBM at the Research Triangle Park, NC. He joined IBM in Canberra, Australia, as a Systems Engineer in 1973, and has since worked on communications systems and pervasive computing in Montreal, Canada, and RTP, NC. He has several patents and has published several papers. His undergraduate degree is in pure mathematics and philosophy from the Australian National University. He has an M.S. and Ph.D. in computer science from North Carolina State University. Learn more about Ian in Ian's profile on developerWorks Community.


nível de autor Contribuidor do
        developerWorks

25/Set/2009 (Primeira publicação 25/Set/2009)

Sobre esta série

Esta série de artigos ajuda a ensinar as tarefas administrativas de sistema do Linux. É possível também usar o material dos artigos como preparação para os exames Linux Professional Institute Certification nível 1 (LPIC-1) (a página reside fora da ibm.com).

Consulte o roteiro da série para ver a descrição e o link de cada artigo da série. O roteiro está em andamento e reflete os objetivos mais recentes (abril de 2009) dos exames LPIC-1: à medida que finalizarmos os artigos, eles serão adicionados ao roteiro. Entretanto, nesse ínterim, é possível que encontre versões mais antigas do mesmo material, com suporte a objetivos de LPIC-1 anteriores a abril de 2009, em nossos tutoriais de preparação para o exame de certificação LPI.

Pré-requisitos

Para aproveitar ao máximo os artigos desta série, é preciso ter um conhecimento básico de Linux e um sistema Linux funcional, para que possa praticar nele os comandos abordados neste artigo. Às vezes, versões diferentes de um programa formatarão o resultado de maneira diferente, para que os resultados não fiquem sempre exatamente iguais às listagens e figuras mostradas aqui.

Visão Geral

Este artigo contém uma breve introdução a alguns dos principais recursos do bash shell e cobre os seguintes tópicos:

  • Interação com shells e comandos que usam a linha de comando
  • Uso de sequências de comando e comandos válidos
  • Definição, modificação, referência e exportação de variáveis de ambiente
  • Acesso a histórico de comandos e recursos de edição
  • Chamada de comandos no caminho e fora do caminho
  • Uso de páginas man (manuais) para saber mais sobre comandos

Este artigo ajuda na preparação para o Objetivo 103.1 no Tópico 103 do exame 101 Junior Level Administration (LPIC-1). O objetivo era um peso de 4. O material deste artigo corresponde aos objetivos de abril de 2009 para o exame 101 (a página reside fora da ibm.com). Sempre consulte os objetivos para os requisitos definitivos.


O bash shell

O bash shell é um dos vários shells disponíveis para Linux. Ele é também conhecido como shell Bourne again, após Stephen Bourne, o criador de um shell anterior (/bin/sh). Bash é bastante compatível com sh, mas contém muitas melhorias nos recursos de função e programação. Ele incorpora recursos do shell Korn (ksh) e do shell C (csh), e se destina a ser um shell compatível com POSIX.

Antes de analisarmos a fundo o bash, lembre-se de que o shell é um programa que aceita e executa comandos. Ele também suporta construções de programação, permitindo a criação de comandos complexos a partir de porções menores. Esses comandos complexos, ou scripts, podem ser salvos para se tornar novos comandos dentro do seu próprio direito. De fato, muitos comandos em um sistema Linux típico são scripts.

Os shells têm alguns comandos integrados, como cd, break e exec. Outros comandos são externos.

Os shells também usam três fluxos de E/S padrão:

  • stdin é o fluxo de entrada padrão, que fornece entrada para comandos.
  • stdout é o fluxo de saída padrão, que mostra a saída dos comandos.
  • stderr é o fluxo de erro padrão, que mostra a saída de erro dos comandos.

Os fluxos de entrada oferecem entrada aos programas, geralmente de pressionamentos de tecla de terminal. Os fluxos de saída imprimem caracteres de texto, geralmente no terminal. O terminal era originalmente uma máquina de escrever ASCII ou terminal de exibição, mas agora é mais, em geral, uma janela em um desktop gráfico. Mais detalhes sobre como redirecionar esses fluxos de E/S padrão serão abordados em outro artigo desta série.

Para o restante do artigo, consideraremos que você sabe como chegar a uma linha de comando do shell. Se não souber, o artigo do developerWorks " Tarefas básicas para novos desenvolvedores de Linux" mostrará como fazer isso e muito mais.

Se estiver usando um sistema Linux sem um desktop gráfico ou se abrir uma janela do terminal em um desktop gráfico, será exibido um prompt, talvez igual ao mostrado na Listagem 1.

Listagem 1. Alguns prompts de usuário típicos
[db2inst1@echidna db2inst1]$
ian@lyrebird:~>
$

Se efetuar login como usuário root (ou superusuário), o prompt poderá ser como o mostrado na Listagem 2.

Listagem 2. Exemplos de prompt de superusuário ou root
[root@echidna ~]#
lyrebird:~ #
#

O usuário root tem poder considerável, portanto, use-o com cautela. Quando se tem privilégios root, a maioria dos prompts contém um sinal de tralha à esquerda (#). Os privilégios de usuário simples geralmente são delineados por um caractere diferente, geralmente um sinal de cifrão ($). O prompt real pode ser diferente dos exemplos deste artigo. O prompt pode incluir o nome de usuário, o nome do host, o diretório atual, a data ou a hora em que o prompt foi impresso etc.

Os artigos contêm exemplos de código recortados e colados de sistemas Linux reais com o uso de prompts padrão desses sistemas. Nossos prompts root têm um # à esquerda, para que seja possível diferenciá-los dos prompts de usuário comum, que têm um $ à esquerda. Essa convenção é consistente com muitos livros sobre o assunto. Se algo aparentar não funcionar para você, verifique o prompt no exemplo.


Comandos e sequências

Agora que você tem um prompt, vamos ver o que se pode fazer com ele. A função principal do shell é interpretar os comandos para que se possa interagir com o sistema Linux. Nos sistemas Linux (e UNIX®), os comandos têm um nome de comando e opções e parâmetros. Alguns comandos não têm opções ou parâmetros e alguns têm um, mas não o outro..

Se uma linha tiver um caractere #, todos os caracteres restantes da linha serão ignorados. Portanto, um caractere pode indicar um comentário e também um prompt root. O que deve estar evidente no contexto.

Echo

O comando echo imprime (ou repete) seus argumentos para o terminal, conforme mostrado na Listagem 3.

Listagem 3. Exemplos de echo
[ian@echidna ~]$ echo Word
Word
[ian@echidna ~]$ echo A phrase
A phrase
[ian@echidna ~]$ echo Where     are   my   spaces?
Where are my spaces?
[ian@echidna ~]$ echo "Here     are   my   spaces." # plus comment
Here     are   my   spaces.

No terceiro exemplo da Listagem 3, todos os espaços adicionais foram compactados em espaços simples na saída. Para evitar isso, é preciso colocar aspas nas cadeias de caracteres, usando aspas duplas (") ou aspas simples ('). Bash usa espaço em branco, como brancos, tabulações e novos caracteres de linha para separar a linha de entrada em tokens, que são enviados ao comando. A colocação de aspas nas cadeias de caracteres preserva espaço em branco adicional e torna toda a cadeia de caracteres um único token. No exemplo acima, cada token após o nome de comando é um parâmetro, portanto, temos, respectivamente, os parâmetros 1, 2, 4 e 1.

O comando echo tem inúmeras opções. Normalmente, echo terá um caractere de nova linha à esquerda para a saída. Use a opção -n para suprimir isso. Use a opção -e para permitir que certos caracteres de escape com barra invertida tenham significado especial. Alguns deles são mostrados na Tabela 1.

Tabela 1. Caracteres echo e de escape
Sequência de escapeFunção
\aAlerta (campainha)
\bBackspace
\cSupressão de nova linha à esquerda (mesma função da opção -n)
\fAlimentação de formulário (limpa a tela em um monitor)
\nNova linha
\rRetorno de linha
\tTabulação horizontal

Escapes e continuação de linha

Há um pequeno problema com o uso de barras invertidas em bash. Quando o caractere de barra invertida (\) não fica entre aspas, ele funciona como um escape para o próprio bash de sinal a fim de preservar o significado literal do caractere seguinte. Isso é necessário para metacaracteres de shell especiais, que abordaremos em breve. Há uma exceção para essa regra: uma barra invertida seguida por uma nova linha faz com que o bash engula ambos os caracteres e trate a sequência como uma solicitação de continuação da linha. Isso pode ser conveniente para quebrar linhas longas, especialmente em scripts de shell.

Para que as sequências descritas acima sejam tratadas pelo comando echo ou um dos muitos outros comandos que usam caracteres de controle de escape similares, é preciso incluir as sequências de escape entre aspas ou como parte de uma cadeia de caracteres entre aspas, a menos que se utilize uma segunda barra invertida para que o shell preserve uma para o comando. A Listagem 4 mostra alguns exemplos dos vários usos de \.

Listagem 4. Mais exemplos de echo
[ian@echidna ~]$ echo -n No new line
No new line[ian@echidna ~]$ echo -e "No new line\c"
No new line[ian@echidna ~]$ echo "A line with a typed
> return"
A line with a typed
return
[ian@echidna ~]$ echo -e "A line with an escaped\nreturn"
A line with an escaped
return
[ian@echidna ~]$ echo "A line with an escaped\nreturn but no -e option"
A line with an escaped\nreturn but no -e option
[ian@echidna ~]$ echo -e Doubly escaped\\n\\tmetacharacters
Doubly escaped
        metacharacters
[ian@echidna ~]$ echo Backslash \
> followed by newline \
> serves as line continuation.
Backslash followed by newline serves as line continuation.

Observe que o bash mostra um prompt especial (>) ao digitar uma linha com aspas sem correspondência. A cadeia de caracteres de entrada continua em uma segunda linha e inclui o novo caractere de linha.

Operadores de controle e metacaracteres de shell de bash

Bash tem inúmeros metacaracteres, que, quando não estão entre aspas, também funcionam para dividir a entrada em palavras. Além de um valor em branco, eles também são:

  • |
  • &
  • ;
  • (
  • )
  • <
  • >

Abordaremos alguns deles mais detalhadamente em outras partes deste artigo. Por ora, observe que, se você quiser incluir um metacaractere como parte do seu texto, ele deverá estar entre aspas ou com escape, utilizando-se uma barra invertida (\), como indicado na Listagem 4.

A nova linha e determinados metacaracteres ou pares de metacaracteres também funcionam como operadores de controle. Elas são:

  • ||
  • &&
  • &
  • ;
  • ;;
  • |
  • (
  • )

Alguns desses operadores de controle permitem criar sequências ou listas de comandos.

A sequência de comandos mais simples é composta apenas por dois comandos separados por um ponto-e-vírgula (;). Cada comando é executado em sequência. Em qualquer ambiente programável, os comandos retornam uma indicação de sucesso ou falha; os comandos do Linux geralmente retornam um valor igual a zero para sucesso e um valor diferente de zero em caso de falha. É possível introduzir processamento condicional na lista usando os operadores de controle && e ||. Se dois comandos forem separados com o operador de controle &&, o segundo será executado somente se o primeiro retornar um valor de saída igual a zero. Se dois comandos forem separados com ||, o segundo será executado somente se o primeiro retornar um código de saída diferente de zero. A Listagem 5 mostra algumas sequências de comandos que usam o comando echo. Elas não são muito indicadas, visto que echo retorna 0, mas você verá mais exemplos adiante quando tivermos mais alguns comandos para usar.

Listagem 5. Sequências de comando
[ian@echidna ~]$ echo line 1;echo line 2; echo line 3
line 1
line 2
line 3
[ian@echidna ~]$ echo line 1&&echo line 2&&echo line 3
line 1
line 2
line 3
[ian@echidna ~]$ echo line 1||echo line 2; echo line 3
line 1
line 3

Sair

É possível encerrar um shell usando o comando exit. É possível, opcionalmente, fornecer um código de saída como parâmetro. Se estiver executando o shell em uma janela de terminal em um desktop gráfico, a janela será fechada. Da mesma forma, caso tenha se conectado a um sistema remoto usando ssh ou telnet (por exemplo), a conexão será encerrada. No bash shell, é possível também manter a tecla Ctrl pressionada e pressionar a tecla d para sair.

Vamos examinar outro operador de controle. Caso uma lista de comandos ou um comando sejam colocados entre parênteses, a sequência ou o comando serão executados em um subshell, para que o comando exit encerre o subshell em vez do shell em que você está trabalhando. A Listagem 6 mostra um exemplo simples em conjunto com && e || e dois códigos de saída diferentes.

Listagem 6. Subshells e sequências
[ian@echidna ~]$ (echo In subshell; exit 0) && echo OK || echo Bad exit
In subshell
OK
[ian@echidna ~]$ (echo In subshell; exit 4) && echo OK || echo Bad exit
In subshell
Bad exit

Fique atento a mais sequências de comandos mais adiante neste artigo.


Variáveis de ambiente

Quando em execução em um bash shell, muitas coisas constituem o ambiente, como a forma do prompt, o diretório inicial, o diretório de trabalho, o nome do shell, os arquivos abertos, as funções definidas etc. O ambiente contém muitas variáveis que podem ter sido definidas por bash ou por você. O bash shell também permite ter variáveis de shell, que você pode exportar ao seu ambiente para uso por outros processos em execução no shell ou por outros shells que podem ser criados a partir do shell atual.

As variáveis de ambiente e de shell têm um nome. A referência ao valor de uma variável é feita pela prefixação de seu nome com '$'. Algumas das variáveis de ambiente bash comuns que você encontrará se encontram na Tabela 2.

Tabela 2. Algumas variáveis de ambiente bash comuns
NomeFunção
USERO nome do usuário conectado
UIDO ID de usuário numérico do usuário conectado
HOMEO diretório inicial do usuário
PWDO diretório de trabalho atual
SHELLO nome do shell
$O ID de processo (ou PID) do processo de bash shell em execução (ou outro processo)
PPIDO ID de processo do processo que iniciou este processo (ou seja, o ID do processo pai)
?O código de saída do último comando

A Listagem 7 mostra o que pode ser visto em algumas dessas variáveis bash comuns.

Listagem 7. Variáveis de ambiente e shell
[ian@echidna ~]$ echo $USER $UID
ian 500
[ian@echidna ~]$ echo $SHELL $HOME $PWD
/bin/bash /home/ian /home/ian
[ian@echidna ~]$ (exit 0);echo $?;(exit 4);echo $?
0
4
[ian@echidna ~]$ echo $$ $PPID
2559 2558

Não está usando bash?

O bash shell é o padrão na maioria das distribuições Linux. Se não estiver executando em bash shell, considere uma das seguintes formas de praticar com o bash shell.

  • Use o comando
    chsh -s /bin/bash
    para carregar o shell padrão. O padrão estará válido na próxima vez em que o login for efetuado.
  • Use o comando
    su - $USER -s /bin/bash
    para criar outro processo como filho do shell atual. O novo processo será um shell de login que usa bash.
  • Crie um ID com um padrão de bash shell a ser usado para preparação de exame LPI.

É possível criar ou definir uma variável de shell digitando um nome seguido imediatamente por um sinal de igual (=). Se a variável existir, modifique-a para atribuir o novo valor. As variáveis têm diferenciação entre maiúsculas e minúsculas, portanto, var1 e VAR1 são variáveis diferentes. Por convenção, variáveis, particularmente as exportadas, são maiúsculas, mas isso não é um requisito. Tecnicamente, $$ e $? são parâmetros de shell em vez de variáveis. Eles podem apenas ser mencionados; não é possível atribuir um valor a eles.

Ao criar uma variável de shell, exporte-a ao ambiente para que fique disponível a outros processos iniciados a partir desse shell. As variáveis exportadas não ficam disponíveis a um shell pai. Use o comando export para exportar um nome de variável. Como um atalho em bash, é possível atribuir um valor e exportar uma variável em uma única etapa.

Para ilustrar a atribuição e a exportação, vamos executar o comando bash enquanto estivermos no bash shell e depois executar o shell Korn (ksh) a partir do novo bash shell. Usaremos o comando ps para mostrar informações sobre o comando em execução. Veremos mais sobre ps em outro artigo desta série. (Consulte Recursos para mais informações sobre o roteiro da série).

Listagem 8. Mais variáveis de ambiente e shell
[ian@echidna ~]$ ps -p $$ -o "pid ppid cmd"
  PID  PPID CMD
 2559  2558 -bash
[ian@echidna ~]$ bash
[ian@echidna ~]$ ps -p $$ -o "pid ppid cmd"
  PID  PPID CMD
 2811  2559 bash
[ian@echidna ~]$ VAR1=var1
[ian@echidna ~]$ VAR2=var2
[ian@echidna ~]$ export VAR2
[ian@echidna ~]$ export VAR3=var3
[ian@echidna ~]$ echo $VAR1 $VAR2 $VAR3
var1 var2 var3
[ian@echidna ~]$ echo $VAR1 $VAR2 $VAR3 $SHELL
var1 var2 var3 /bin/bash
[ian@echidna ~]$ ksh
$ ps -p $$ -o "pid ppid cmd"
  PID  PPID CMD
 2840  2811 ksh
$ export VAR4=var4
$ echo $VAR1 $VAR2 $VAR3 $VAR4 $SHELL
var2 var3 var4 /bin/bash
$ exit
[ian@echidna ~]$ echo $VAR1 $VAR2 $VAR3 $VAR4 $SHELL
var1 var2 var3 /bin/bash
[ian@echidna ~]$ ps -p $$ -o "pid ppid cmd"
  PID  PPID CMD
 2811  2559 bash
[ian@echidna ~]$ exit
exit
[ian@echidna ~]$ ps -p $$ -o "pid ppid cmd"
  PID  PPID CMD
 2559  2558 -bash
[ian@echidna ~]$ echo $VAR1 $VAR2 $VAR3 $VAR4 $SHELL
/bin/bash

Notas:

  1. No início dessa sequência, o bash shell tinha PID 2559.
  2. O segundo bash shell tinha PID 2811, e seu pai é PID 2559, o bash shell original.
  3. Criamos VAR1, VAR2 e VAR3 no segundo bash shell, mas exportamos apenas VAR2 e VAR3.
  4. No shell Korn, criamos VAR4. O comando echo exibiu valores apenas para VAR2, VAR3 e VAR4, confirmando que VAR1 não foi exportada. Ficou surpreso ao ver que o valor da variável SHELL não tinha mudado, embora o prompt tenha mudado? Não é possível confiar sempre em SHELL para informar em qual shell está ocorrendo a execução, mas o comando ps informa o comando real. Observe que ps coloca um hífen (-) diante do primeiro bash shell para indicar que este é o shell de login.
  5. De volta ao segundo bash shell, podemos ver VAR1, VAR2 e VAR3.
  6. E, finalmente, quando retornarmos ao shell original, nenhuma de nossas novas variáveis existirá.

A discussão anterior de uso das aspas mencionou que é possível usar aspas simples ou duplas. Há uma diferença importante entre elas. O shell expande as variáveis de shell que estão entre aspas duplas ($quot;), mas as expansão não é feita quando aspas simples (') são usadas. No exemplo anterior, iniciamos outro shell dentro de nosso shell e obtivemos um novo ID de processo. Usando a opção -c, é possível enviar um comando a outro shell, que executará o comando e retornará. Se você enviar uma cadeia de caracteres entre aspas como comando, o shell externo separará as aspas e enviará a cadeia de caracteres. Caso sejam usadas aspas duplas, a expansão da variável ocorrerá antes do envio da cadeia de caracteres, portanto, os resultados poderão não ser os esperados. O shell e o comando serão executados em outro processo, portanto, eles terão outro PID. A Listagem 9 mostra esses conceitos. O PID do bash shell de nível superior é selecionado.

Listagem 9. Variáveis de ambiente e shell
[ian@echidna ~]$ echo "$SHELL" '$SHELL' "$$" '$$'
/bin/bash $SHELL 2559 $$
[ian@echidna ~]$ bash -c "echo Expand in parent $$ $PPID"
Expand in parent 2559 2558
[ian@echidna ~]$ bash -c 'echo Expand in child $$ $PPID'
Expand in child 2845 2559

Até agora, todas as nossas referências de variável terminaram com espaço em branco, portanto, está claro onde o nome da variável termina. De fato, os nomes de variável podem ser compostos apenas por letras, números ou pelo caractere de sublinhado. O shell sabe que um nome de variável termina onde outro caractere é encontrado. Às vezes, é preciso usar variáveis em expressões em que o significado é ambíguo. Nesses casos, é possível usar chaves para delinear um nome de variável, conforme indicado na Listagem 10.

Listagem 10. Usando chaves com nomes de variável
[ian@echidna ~]$ echo "-$HOME/abc-"
-/home/ian/abc-
[ian@echidna ~]$ echo "-$HOME_abc-"
++
[ian@echidna ~]$ echo "-${HOME}_abc-"
-/home/ian_abc-

Env

O comando env sem nenhuma opção ou parâmetro mostra as variáveis de ambiente atuais. É possível usá-lo também para executar um comando em um ambiente personalizado. A opção -i (ou apenas -) limpa o ambiente atual antes de executar o comando, ao passo que a opção -u não define as variáveis de ambiente que não deseja enviar.

A Listagem 11 mostra a saída parcial do comando env sem nenhum parâmetro e três exemplos de chamada de diferentes shells sem o ambiente pai. Observe-os atentamente antes de discuti-los.

Nota: Caso o seu sistema não tenha os shells ksh (Korn) ou tcsh instalados, será preciso instalá-los para que possa fazer esses exercícios por conta própria.

Listagem 11. O comando env
[ian@echidna ~]$ env
HOSTNAME=echidna
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=9.27.206.68 1316 22
SELINUX_USE_CURRENT_RANGE=
QTDIR=/usr/lib/qt-3.3
QTINC=/usr/lib/qt-3.3/include
SSH_TTY=/dev/pts/3
USER=ian
...
_=/bin/env
OLDPWD=/etc
[ian@echidna ~]$ env -i bash -c 'echo $SHELL; env'
/bin/bash
PWD=/home/ian
SHLVL=1
_=/bin/env
[ian@echidna ~]$ env -i ksh -c 'echo $SHELL; env'
/bin/sh
_=/bin/env
PWD=/home/ian
_AST_FEATURES=UNIVERSE - ucb
[ian@echidna ~]$ env -i tcsh -c 'echo $SHELL; env'
SHELL: Undefined variable.

Observe que bash definiu a variável SHELL, mas não a exportou ao ambiente, embora haja três outras variáveis criadas por bash no ambiente. No exemplo de ksh, temos duas variáveis de ambiente, mas nossa tentativa de definir o echo do valor da variável SHELL retorna uma linha em branco. Por fim, tcsh não criou nenhuma variável de ambiente e retorna um erro em nossa tentativa de fazer referência ao valor de SHELL.

Não definir e definir

A Listagem 11 mostrou comportamento diferente no modo como os shells lidam com variáveis e ambientes. Embora o foco deste artigo seja o bash, é bom saber que nem todos os shells se comportam da mesma forma. Além do mais, os shells se comportam de maneira diferente, dependendo de serem um shell de login ou não. Até este momento, diremos apenas que um shell de login é aquele obtido quando se efetua login no sistema; é possível iniciar outros shells para que se comportem como shells de login, caso essa seja a sua preferência. Os três shells iniciados acima com o uso de env -i não eram shells de login. Tente enviar a opção -l ao próprio comando de shell para ver quais diferenças consegue enxergar com um shell de login.

Portanto, vamos considerar nossa tentativa de exibir o valor da variável SHELL nestes shells que não são de login:

  1. Quando o bash iniciou, ele definiu a variável SHELL, mas não a exportou automaticamente ao ambiente.
  2. Quando ksh iniciou, ele não definiu a variável SHELL. Entretanto, a referência a uma variável de ambiente não definida é equivalente a fazer referência a uma com um valor vazio.
  3. Quando tcsh iniciou, ele não definiu a variável SHELL. Nesse caso, o comportamento padrão é diferente em relação a ksh (e bash) porque um erro é relatado quando tentamos usar uma variável que não existe.

Não é possível usar o comando unset para cancelar a definição de uma variável e removê-la da lista de variáveis de shell. Se a variável tiver sido exportada ao ambiente, essa ação também a removerá do ambiente. Não é possível usar o comando set para controlar muitas facetas da forma como bash (ou outros shells) funcionam. Set é um shell integrado, portanto, as várias opções são específicas de shell. Em bash, a opção -u faz com que bash reporte um erro com variáveis indefinidas em vez de tratá-las como definidas, mas vazias. É possível ativar as várias opções para set com um - e desativá-las com um +. É possível exibir as opções definidas atualmente usando echo $-.

Listagem 12. Cancelar definição e definir
[ian@echidna ~]$ echo $-
himBH
[ian@echidna ~]$ echo $VAR1

[ian@echidna ~]$ set -u;echo $-
himuBH
[ian@echidna ~]$ echo $VAR1
-bash: VAR1: unbound variable
[ian@echidna ~]$ VAR1=v1
[ian@echidna ~]$ VAR1=v1;echo $VAR1
v1
[ian@echidna ~]$ unset VAR1;echo $VAR1
-bash: VAR1: unbound variable
[ian@echidna ~]$ set +u;echo $VAR1;echo $-

himBH

Caso o comando set seja usado sem nenhuma opção, ele mostrará todas as variáveis de shell e seus valores (se houver). Há também outro comando, declare, que pode ser usado para criar, exportar e exibir valores de variáveis de shell. É possível explorar as várias opções de set restantes e o comando declare usando as páginas man. Abordaremos as páginas man mais adiante neste artigo.

Exec

Um comando final a ser abordado é exec. Não é possível usar o comando exec para executar outro programa que substitua o shell atual. A Listagem 13 inicia como um bash shell filho e usa exec para substituí-lo por um shell Korn. Ao sair do shell Korn, você retorna ao bash shell original (PID 2852, neste exemplo).

Listagem 13. Usando exec
[ian@echidna ~]$ echo $$
2852
[ian@echidna ~]$ bash
[ian@echidna ~]$ echo $$
5114
[ian@echidna ~]$ exec ksh
$ echo $$
5114
$ exit
[ian@echidna ~]$ echo $$
2852

Informações de sistema com uname

O comando uname imprime informações sobre o sistema e seu kernel. A Listagem 14 mostra as várias opções para uname e as informações resultantes; cada opção está definida na Tabela 3.

Listagem 14. O comando uname
[ian@echidna ~]$ uname
Linux
[ian@echidna ~]$ uname -s
Linux
[ian@echidna ~]$ uname -n
echidna.raleigh.ibm.com
[ian@echidna ~]$ uname -r
2.6.29.6-217.2.3.fc11.i686.PAE
[ian@echidna ~]$ uname -v
#1 SMP Wed Jul 29 16:05:22 EDT 2009
[ian@echidna ~]$ uname -m
i686
[ian@echidna ~]$ uname -o
GNU/Linux
[ian@echidna ~]$ uname -a
Linux echidna.raleigh.ibm.com 2.6.29.6-217.2.3.fc11.i686.PAE 
#1 SMP Wed Jul 29 16:05:22 EDT 2009 i686 i686 i386 GNU/Linux
Tabela 3. Opções para uname
OpçãoDescrição
-sImprime o nome do kernel. Este será o padrão se nenhuma opção estiver especificada.
-nImprime o nome do nó ou o nome do host.
-rImprime o release do kernel. Esta opção é geralmente usada com comandos de manipulação de módulo.
-vImprime a versão do kernel.
-mImprime o nome do hardware (CPU) da máquina.
-oImprime o nome do sistema operacional.
-aImprime todas as informações acima.

Listagem 14 é de um sistema Fedora 11 em execução em uma® CPU Intel. O comando uname está disponível na maioria dos sistemas UNIX® e similares a UNIX, bem como Linux. As informações impressas variarão de uma distribuição e uma versão Linux para outra, bem como entre os tipos de máquina em operação. A Listagem 15 mostra a saída de um sistema AMD Athlon 64 que executa Ubuntu 9.04.

Listagem 15. Usando uname com outro sistema
ian@attic4:~$ uname -a
Linux attic4 2.6.28-14-generic #47-Ubuntu SMP Sat Jul 25 01:19:55 UTC 2009 x86_64 
GNU/Linux

Histórico de comandos

Se estiver digitando comandos à medida que lê, é possível observar que, em geral, você usa um comando várias vezes exatamente da mesma forma ou com sutis mudanças. A boa notícia é que o bash shell pode manter um histórico dos comandos. Por padrão, o histórico fica ativo. É possível desativá-lo usando o comando set +o history e reativá-lo usando set -o history. Uma variável de ambiente chamada HISTSIZE informa a bash quantas linhas de histórico manter. Várias outras configurações controlam como o histórico funciona e é gerenciado. Consulte as páginas man bash para ver todos os detalhes.

Alguns dos comandos que podem ser usados com o recurso de histórico são:

history
Mostra todo o histórico
history N
Mostra as últimas N linhas do histórico
history -d N
Exclui a linha N do histórico; isso poderá ser feito se, por exemplo, a linha tiver uma senha
!!
O comando mais recente
!N
O Nº comando de histórico
!-N
O comando que está N comandos atrás no histórico (!-1 é equivalente a !!)
!#
O comando atual sendo digitado
!string
O comando mais recente que começa com string
!?string?
O comando mais recente que contém string

É possível também usar um dois-pontos (:) seguido por determinados valores para acessar ou modificar parte de um comando ou um comando inteiro do seu histórico. A Listagem 16 mostra alguns dos recursos de histórico.

Listing 16. Manipulating history
[ian@echidna ~]$ echo $$
2852
[ian@echidna ~]$ env -i bash -c 'echo $$'
9649
[ian@echidna ~]$ !!
env -i bash -c 'echo $$'
10073
[ian@echidna ~]$ !ec
echo $$
2852
[ian@echidna ~]$ !en:s/$$/$PPID/
env -i bash -c 'echo $PPID'
2852
[ian@echidna ~]$ history 6
  595  echo $$
  596  env -i bash -c 'echo $$'
  597  env -i bash -c 'echo $$'
  598  echo $$
  599  env -i bash -c 'echo $PPID'
  600  history 6
[ian@echidna ~]$ history -d598

Os comandos da Listagem 16 fazem o seguinte:

  1. Usam echo para o PID do shell atual
  2. Executam um comando echo em um novo shell que é o PID do shell
  3. Executam novamente o último comando
  4. Executam novamente o último comando, começando com 'ec'; isso executa novamente o primeiro comando deste exemplo
  5. Executam novamente o último comando começando com 'en', mas substitua '$PPID' por '$$', para que o PID pai seja exibido
  6. Exibem os últimos 6 comandos do histórico
  7. Excluem a entrada de histórico 598, o último comando echo

É possível também editar o histórico interativamente. O bash shell usar a biblioteca readline para gerenciar o histórico e a edição de comandos. Por padrão, as teclas e as combinações de teclas usadas para navegar pelo histórico ou editar linhas são similares às usadas no editor GNU Emacs. As combinações de teclas de Emacs são geralmente expressas como C-x ou M-x, em que x é uma tecla regular e C e M, as teclas Control e Meta, respectivamente. Em um sistema de computador comum, a tecla Ctrl serve como a tecla de controle de Emacs, e a tecla Alt, como a tecla Meta. A Tabela 3 resume algumas das funções de edição de histórico disponíveis. Além das combinações de teclas mostradas na Tabela 3, as teclas de movimentação do cursor, como seta para direita, para esquerda, para cima e para baixo, e as teclas Home e End são geralmente definidas para funcionar de maneira lógica. As funções adicionais e o modo de personalização dessas opções que usam um arquivo init file (geralmente inputrc no diretório inicial) podem ser encontrados nas páginas man.

Tabela 3. Edição de histórico com comandos emacs
ComandoTecla de PC comumDescrição
C-fSeta para a direitaMove um espaço para a direita
C-bSeta para a esquerdaMove um espaço para a esquerda
C-pSeta para cimaMove para um comando anterior no histórico
C-nSeta para baixoMove para um comando posterior no histórico
C-rPesquisa inversa incremental. Digite uma letra ou letras para pesquisa inversa de uma cadeia de caracteres. Pressione C-r de novo para pesquisar a ocorrência anterior ou posterior da mesma cadeia de caracteres.
M-fAlt-fMove para o começo da próxima palavra; ambientes de GUI geralmente usam essa combinação de teclas para abrir o menu Arquivo da janela
M-bAlt-bMove para o começo da palavra anterior
C-aHomeMove para o começo da linha
C-eEndMove para o final da linha
BackspaceBackspaceExclui o caractere anterior ao cursor
C-dDelExclui o caractere após o cursor (as funções Del e Backspace podem ser configuradas com significados opostos)
C-kCtrl-kExclui (kill) até o final da linha e salva o texto removido para uso posterior
M-dAlt-dExclui (kill) até o final da palavra e salva o texto removido para uso posterior
C-yCtrl-yEmpurra para trás o texto removido com um comando kill

Se preferir manipular o histórico usando um modo de edição igual a vi, use o comando set -o vi para alternar para o modo vi. Volte para o modo emacs usando set -o emacs. Ao recuperar um comando no modo vi, você está inicialmente no modo de inserção de vi. O editor vi é abordado em outro artigo desta série. (Consulte Recursos para mais informações sobre o roteiro da série).


Caminhos - onde está o meu comando?

Alguns comandos bash estão integrados, outros são externos. Vamos agora observar os comandos externos e como executá-los e como dizer se um comando é interno.

Onde o shell localiza comandos?

Os comandos externos são apenas arquivos presentes no sistema de arquivos. O gerenciamento básico de arquivos é abordado em outro artigo desta série. (Consulte Recursos para mais informações sobre o roteiro da série). Em sistemas Linux e UNIX, todos os arquivos são acessados como parte de uma única árvore grande com rota em /. Em nossos exemplos até agora, o diretório atual tem sido o inicial do usuário. Os usuários não root geralmente têm um diretório inicial no diretório /home, como /home/ian, no meu caso. O diretório inicial de root é geralmente /root. Se um nome de comando for digitado, o bash procurará esse comando no caminho, que é uma lista de diretórios separados por dois pontos na variável de ambiente PATH.

Se quiser saber qual comando será executado se especificar uma determinada cadeia de caracteres, use o comando which ou type. A Listagem 17 mostra meu caminho padrão junto com os locais de diversos comandos.

Listagem 17. Procurando locais de comando
[ian@echidna ~]$ echo $PATH
/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/usr/lib/ccache:/usr/local/bin:/bin:/usr/b
in:/home/ian/bin
[ian@echidna ~]$ which bash env zip xclock echo set ls
alias ls='ls ++color=auto'
        /bin/ls
/bin/bash
/bin/env
/usr/bin/zip
/usr/bin/xclock
/bin/echo
/usr/bin/which: no set in (/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/usr/lib/ccache
:/usr/local/bin:/bin:/usr/bin:/home/ian/bin)
[ian@echidna ~]$ type bash env zip xclock echo set ls
bash is hashed (/bin/bash)
env is hashed (/bin/env)
zip is /usr/bin/zip
xclock is /usr/bin/xclock
echo is a shell builtin
set is a shell builtin
ls is aliased to `ls ++color=auto'

Observe que os diretórios do caminho geralmente terminam em /bin. Essa é uma convenção comum, mas não um requisito, como é possível ver em /usr/lib/ccache. O comando which relatou que o comando ls é um alias e que o comando set não pôde ser encontrado. Nesse caso, interpretamos que ele não existe ou que está integrado. O comando type relata que o comando ls é um alias,mas identifica o comando set como um shell integrado. Ele também relata que há um comando echo integrado, bem como o que está em /bin que foi localizado por which. Os comandos também geram saída em ordens diferentes.

Vimos que o comando ls, usado para listar conteúdo de diretório, é um alias. Os aliases são uma forma prática de configurar alguns comandos para usar diferentes conjuntos de padrões ou fornecer um nome alternativo para um comando. Em nosso exemplo, a opção --color=tty faz com que as listas de diretórios sejam codificadas por cores, de acordo com o tipo de arquivo ou diretório. Tente executar dircolors --print-database para ver como as codificações por cores são controladas e quais cores são usadas para qual tipo de arquivo.

Cada um desses comandos tem opções adicionais. Dependendo de sua necessidade, você pode usar qualquer um dos comandos. Eu tenho a tendência de usar which quando tenho certeza razoável de que encontrarei um executável e preciso apenas de sua especificação de caminho completo. Eu percebo que type me fornece informações mais precisas, as quais às vezes são necessárias em um script de shell.

Executando outros comandos

Vimos na Listagem 17 que arquivos executáveis têm um caminho completo que começa com /, o diretório root. Por exemplo, o programa xclock é na verdade /usr/bin/xclock, um arquivo localizado no diretório /usr/bin. Em sistemas mais antigos, você pode encontrar isso no diretório /usr/X11R6/bin. Se um comando não estiver na especificação PATH, você poderá executá-la ainda especificando um caminho e também um nome de comando. Existem dois tipos de caminhos que podem ser usados:

  • Os caminhos Absolutos são aqueles que começam com /, como os que vimos na Listagem 17 (/bin/bash, /bin/env etc).
  • Os caminhos Relativos são relativos ao diretório de trabalho atual, conforme relatado pelo comando pwd. Esses comandos não começam com /, mas contêm pelo menos um /.

É possível usar caminhos absolutos, independentemente do diretório de trabalho atual, mas você provavelmente usará caminhos relativos apenas quando um comando estiver perto do seu diretório atual. Suponha que esteja desenvolvendo uma nova versão do programa clássico "Hello World!" em um subdiretório do seu diretório inicial denominado mytestbin. Use o caminho relativo para executar o comando como mytestbin/hello. Há dois nomes especiais que podem ser usados em um caminho; um único ponto (.) se refere ao diretório atual, e um par de pontos (..) se refere ao pai do diretório atual. Como o diretório inicial geralmente não está no PATH (e, normalmente, não deve estar), você precisará fornecer explicitamente um caminho para qualquer executável que deseje executar a partir do diretório inicial. Por exemplo, se houvesse uma cópia do programa hello no diretório inicial, ela poderia ser executada utilizando-se o comando ./hello. É possível usar . and .. como parte de um caminho absoluto, embora um único . não seja muito útil nesse caso. Pode-se usar também um til (~) para indicar seu próprio diretório inicial e ~nomedousuário para indicar o diretório inicial do usuário denominado nomedousuário. Alguns exemplos são mostrados na Listagem 18.

Listagem 18. Caminhos absolutos e relativos
[ian@echidna ~]$ /bin/echo Use echo command rather than builtin
Use echo command rather than builtin
[ian@echidna ~]$ /usr/../bin/echo Include parent dir in path
Include parent dir in path
[ian@echidna ~]$ /bin/././echo Add a couple of useless path components
Add a couple of useless path components
[ian@echidna ~]$ pwd # See where we are
/home/ian
[ian@echidna ~]$ ../../bin/echo Use a relative path to echo
Use a relative path to echo
[ian@echidna ~]$ myprogs/hello # Use a relative path with no dots
-bash: myprogs/hello: No such file or directory
[ian@echidna ~]$ mytestbin/hello # Use a relative path with no dots
Hello world!
[ian@echidna ~]$ ./hello
Hello world!
[ian@echidna ~]$ ~/mytestbin/hello # run hello using ~
Hello world!
[ian@echidna ~]$ ../hello # Try running hello from parent
-bash: ../hello: No such file or directory

Alterando o diretório de trabalho

Assim como é possível executar programas de vários diretórios do sistema, também existe a possibilidade de alterar o diretório de trabalho atual usando o comando cd. O argumento para cd deve ser o caminho absoluto ou relativo para um diretório. Da mesma forma que para os comandos, você pode usar ., .., ~ e ~nomedousuário nos caminhos. Se cd for usado sem nenhum parâmetro, a alteração ocorrerá no diretório inicial. Um único hífen (-) como parâmetro significa mudar para o diretório de trabalho anterior. O diretório inicial é armazenado na variável de ambiente HOME, e o diretório anterior, na variável OLDPWD, para que cd sozinho seja equivalente a cd $HOME, e cd -, a cd $OLDPWD. Normalmente, dizemos alterar diretório no lugar da forma completa alterar diretório de trabalho atual.

Em relação aos comandos, há também uma variável de ambiente, CDPATH, que contém um conjunto de diretórios separado por dois pontos que deve ser pesquisado (além do diretório de trabalho atual) ao se resolver caminhos relativos. Se a resolução tiver usado um caminho de CDPATH, cd imprimirá o caminho completo do diretório de resultado como saída. Normalmente, uma alteração de diretório com êxito resulta em nenhuma saída que não seja um novo prompt, possivelmente alterado. Alguns exemplos são mostrados na Listagem 19.

Listagem 19. Alterando diretórios
[ian@echidna ~]$ cd /;pwd
/
[ian@echidna /]$ cd /usr/local;pwd
/usr/local
[ian@echidna local]$ cd ;pwd
/home/ian
[ian@echidna ~]$ cd -;pwd
/usr/local
/usr/local
[ian@echidna local]$ cd ~ian/..;pwd
/home
[ian@echidna home]$ cd ~;pwd
/home/ian
[ian@echidna ~]$ export CDPATH=~
[ian@echidna ~]$ cd /;pwd
/
[ian@echidna /]$ cd mytestbin
/home/ian/mytestbin

Páginas manuais (man)

Nosso tópico final neste artigo mostra como obter a documentação dos comandos do Linux por meio de páginas manuais e outras fontes de documentação.

Seções e páginas manuais

A fonte principal (e tradicional) de documentação é composta pelas páginas manuais, que podem ser acessadas via comando man. A Figura 1 mostra a página manual do próprio comando man. Use o comando man man para exibir essas informações.

Figura 1. Página man para o comando man
Man page for man command with numbers showing items listed below image

A Figura 1 mostra alguns itens típicos das páginas man:

  • Um cabeçalho com o nome do comando seguido pelo seu número de seção entre parênteses
  • O nome do comando e qualquer comando relacionado descrito na mesma página man
  • Uma sinopse das opções e dos parâmetros aplicáveis ao comando
  • Uma descrição curta do comando
  • Informações detalhadas sobre cada uma das opções

É possível localizar outras seções sobre uso, como relatar erros, informações do autor e uma lista de comandos relacionados. Por exemplo, a página man de man informa que os comandos relacionados (e suas seções manuais) são:

apropos(1), whatis(1), less(1), groff(1) e man.conf(5).

Há oito seções de páginas manuais comuns. As páginas manuais são geralmente instaladas quando se instala um pacote, portanto, se não houver um pacote instalado, provavelmente não existirá uma página manual para ele. Da mesma forma, algumas das seções manuais podem estar vazias ou quase vazias. As seções manuais comuns, com algum conteúdo de exemplo, são:

  1. Comandos do usuário (env, ls, echo, mkdir, tty)
  2. Chamadas de sistema ou funções de kernel (link, sethostname, mkdir)
  3. Rotinas de biblioteca (acosh, asctime, btree, locale, XML::Parser)
  4. Informações relacionadas a dispositivo (isdn_audio, mouse, tty, zero)
  5. Descrições de formato de arquivo (keymaps, motd, wvdial.conf)
  6. Jogos (observe que muitos jogos são agora gráficos e têm ajuda gráfica fora do sistema da página man)
  7. Diversos (arp, boot, regex, unix utf8)
  8. Administração de sistema (debugfs, fdisk, fsck, mount, renice, rpm)

Outras seções que podem ser encontradas incluem 9 para documentação de kernel Linux, n para nova documentação, o para documentação antiga e l para documentação local.

Algumas entradas aparecem em várias seções. Outros exemplos mostram mkdir nas seções 1 e 2 e tty nas seções 1 e 4. É possível especificar uma seção particular, por exemplo, man 4 tty ou man 2 mkdir ou a opção -a para listar todas as seções manuais aplicáveis.

Você pode ter observado na figura que man tem muitas opções que podem ser exploradas por conta própria. Agora, vamos dar uma observada rápida em alguns dos comandos "Consulte também" relacionados a man.

Consulte também

Dois comandos importantes relacionados a man são whatis e apropos. O comando whatis pesquisa páginas man para o nome dado e exibe as informações do nome nas páginas manuais apropriadas. O comando apropos faz uma pesquisa por palavra-chave de páginas manuais e lista as que contêm a palavra-chave. A Listagem 20 mostra esses comandos.

Listagem 20. Exemplos de Whatis e apropos
[ian@echidna ~]$ whatis man
man []               (1)  - format and display the on-line manual pages
man []               (1p)  - display system documentation
man []               (7)  - macros to format man pages
man []               (7)  - pages - conventions for writing Linux man pages
man.config []        (5)  - configuration data for man
man-pages           (rpm) - Man (manual) pages from the Linux Documentation Project
man                 (rpm) - A set of documentation tools: man, apropos and whatis
[ian@echidna ~]$ whatis mkdir
mkdir []             (1)  - make directories
mkdir []             (1p)  - make directories
mkdir []             (2)  - create a directory
mkdir []             (3p)  - make a directory
[ian@echidna ~]$ apropos mkdir
mkdir []             (1)  - make directories
mkdir []             (1p)  - make directories
mkdir []             (2)  - create a directory
mkdir []             (3p)  - make a directory
mkdirat []           (2)  - create a directory relative to a directory file descriptor
mkdirhier []         (1)  - makes a directory hierarchy

À propósito, se não for possível localizar a página manual para man.conf, tente executar man man.config.

As páginas do comando man são exibidas com o uso de um programa de paginação. Na maioria dos sistemas Linux, é provável que seja o programa less. Outra opção pode ser o programa more mais antigo. Se quiser imprimir a página, especifique a opção -t a fim de formatar a página para impressão usando o programa groff ou troff.

A página lesse tem vários comandos que ajudam a pesquisar cadeias de caracteres na saída exibida. Use man less para saber mais sobre / (pesquisar para frente), ? (pesquisar para trás) e n (repetir última pesquisa), entre muitos outros comandos.

Outras fontes de documentação

Além das páginas manuais acessadas por uma linha de comando, a Free Software Foundation criou inúmeros arquivos de informações processados com o programa de informações. Eles oferecem vários recursos de navegação, incluindo a capacidade de pular para outras seções. Tente man info ou info info para obter mais informações. Nem todos os comandos estão documentados com informações, portanto, man e info serão usados caso você se torne um usuário info.

Há também algumas interfaces gráficas para páginas man, como xman (do projeto XFree86) e yelp (o navegador de ajuda Gnome 2.0).

Se não conseguir localizar um comando, tente executar o comando com a opção --help. Isso pode apresentar a ajuda do comando ou informar como obter a ajuda necessária.

Recursos

Aprender

Obter produtos e tecnologias

  • Com o software de teste IBM, disponível para download diretamente no developerWorks, faça seu próximo projeto de desenvolvimento em Linux.

Discutir

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Linux
ArticleID=432437
ArticleTitle=Aprenda Linux, 101: A linha de comando do Linux
publish-date=09252009