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 é 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.
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.
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 escape | Função |
|---|---|
| \a | Alerta (campainha) |
| \b | Backspace |
| \c | Supressão de nova linha à esquerda (mesma função da opção -n) |
| \f | Alimentação de formulário (limpa a tela em um monitor) |
| \n | Nova linha |
| \r | Retorno de linha |
| \t | Tabulaçã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 |
É 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.
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
| Nome | Função |
|---|---|
| USER | O nome do usuário conectado |
| UID | O ID de usuário numérico do usuário conectado |
| HOME | O diretório inicial do usuário |
| PWD | O diretório de trabalho atual |
| SHELL | O nome do shell |
| $ | O ID de processo (ou PID) do processo de bash shell em execução (ou outro processo) |
| PPID | O 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 |
É 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:
- No início dessa sequência, o bash shell tinha PID 2559.
- O segundo bash shell tinha PID 2811, e seu pai é PID 2559, o bash shell original.
- Criamos VAR1, VAR2 e VAR3 no segundo bash shell, mas exportamos apenas VAR2 e VAR3.
- No shell Korn, criamos VAR4. O comando
echoexibiu 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 comandopsinforma o comando real. Observe quepscoloca um hífen (-) diante do primeiro bash shell para indicar que este é o shell de login. - De volta ao segundo bash shell, podemos ver VAR1, VAR2 e VAR3.
- 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-
|
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.
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:
- Quando o bash iniciou, ele definiu a variável SHELL, mas não a exportou automaticamente ao ambiente.
- 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.
- 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.
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
|
| Opção | Descrição |
|---|---|
| -s | Imprime o nome do kernel. Este será o padrão se nenhuma opção estiver especificada. |
| -n | Imprime o nome do nó ou o nome do host. |
| -r | Imprime o release do kernel. Esta opção é geralmente usada com comandos de manipulação de módulo. |
| -v | Imprime a versão do kernel. |
| -m | Imprime o nome do hardware (CPU) da máquina. |
| -o | Imprime o nome do sistema operacional. |
| -a | Imprime 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
|
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:
- Usam echo para o PID do shell atual
- Executam um comando echo em um novo shell que é o PID do shell
- Executam novamente o último comando
- Executam novamente o último comando, começando com 'ec'; isso executa novamente o primeiro comando deste exemplo
- Executam novamente o último comando começando com 'en', mas substitua '$PPID' por '$$', para que o PID pai seja exibido
- Exibem os últimos 6 comandos do histórico
- 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
| Comando | Tecla de PC comum | Descrição |
|---|---|---|
| C-f | Seta para a direita | Move um espaço para a direita |
| C-b | Seta para a esquerda | Move um espaço para a esquerda |
| C-p | Seta para cima | Move para um comando anterior no histórico |
| C-n | Seta para baixo | Move para um comando posterior no histórico |
| C-r | Pesquisa 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-f | Alt-f | Move 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-b | Alt-b | Move para o começo da palavra anterior |
| C-a | Home | Move para o começo da linha |
| C-e | End | Move para o final da linha |
| Backspace | Backspace | Exclui o caractere anterior ao cursor |
| C-d | Del | Exclui o caractere após o cursor (as funções Del e Backspace podem ser configuradas com significados opostos) |
| C-k | Ctrl-k | Exclui (kill) até o final da linha e salva o texto removido para uso posterior |
| M-d | Alt-d | Exclui (kill) até o final da palavra e salva o texto removido para uso posterior |
| C-y | Ctrl-y | Empurra 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.
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 |
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.
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
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:
- Comandos do usuário (env, ls, echo, mkdir, tty)
- Chamadas de sistema ou funções de kernel (link, sethostname, mkdir)
- Rotinas de biblioteca (acosh, asctime, btree, locale, XML::Parser)
- Informações relacionadas a dispositivo (isdn_audio, mouse, tty, zero)
- Descrições de formato de arquivo (keymaps, motd, wvdial.conf)
- Jogos (observe que muitos jogos são agora gráficos e têm ajuda gráfica fora do sistema da página man)
- Diversos (arp, boot, regex, unix utf8)
- 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.
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.
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.
Aprender
- Use o
roteiro para LPIC-1
para localizar os artigos do developerWorks necessários para ajudar na preparação
para a certificação LPIC-1 com base nos objetivos de abril de 2009.
- Veja os objetivos de abril de 2009 para
exame LPI
101 (a página reside fora da ibm.com)
e exame LPI
102 (a página reside fora da ibm.com).
Sempre consulte os objetivos para os requisitos
definitivos.
- Reveja toda a
série preparatória de exame LPI (a página reside fora da ibm.com)
sobre o developerWorks para aprender os conceitos básicos sobre Linux e se
preparar para a certificação de administrador de sistema com base nos
objetivos anteriores a abril de 2009.
- No
Programa LPIC (a página reside fora da ibm.com),
localize listas de tarefas, perguntas de amostra e objetivos detalhados para os
três níveis da certificação de administração de sistema Linux do Linux Professional
Institute.
- Em
"Tarefas básicas para novos desenvolvedores de Linux"
(developerWorks, março de 2005), saiba como abrir uma janela de terminal ou prompt
de shell e muito mais.
- O
Projeto
de Documentação Linux (a página reside fora da ibm.com)
tem uma variedade de documentos úteis, especialmente seus HOWTOs (como fazer).
- Na
zona Linux do developerWorks,
você encontrará mais recursos para desenvolvedores Linux, e poderá ver nossos
artigos e
tutoriais mais populares.
- Veja todas as
dicas
para Linux
e os
tutoriais
de Linux
do developerWorks.
- Fique em dia com os
eventos técnicos e Webcasts do developerWorks.
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
- Participar do fórum de discussão.
- Participe da
comunidade My developerWorks;
com seu perfil pessoal e página inicial customizada, você pode adaptar o
developerWorks aos seus interesses e interagir com outros usuários
developerWorks.
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. 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.