Guia para Domínio Avançado dos Comandos do Linux - Parte 1
Por Arup Nanda ,
Publicado Agosto 2006
No excelente artigo de Sheryl Calish, "Guide to Linux File Command Mastery" (Guia para domínio dos comandos de arquivo do Linux), você aprendeu alguns comandos típicos do Linux, que são valiosos principalmente para quem está começando com esse sistema operacional. Mas agora que você domina os conceitos básicos, vamos progredir para alguns comandos mais sofisticados que você achará extremamente úteis.
Nesta série de quatro partes, você aprenderá alguns truques não tão conhecidos sobre vários comandos típicos, além de variações de utilização que os tornam mais úteis. À medida que a série evoluir, aprenderá comandos cada vez difíceis de dominar.
Observe que eles podem ser diferentes dependendo da versão específica do Linux usada ou do kernel específico compilado, mas, nesse caso, as diferenças deverão ser mínimas.
Alterações Sem Transtornos para o Proprietário, o Grupo e as Permissões
No artigo de Sheryl, você aprendeu como usar os comandos chown e chgrp para alterar a propriedade e o grupo dos arquivos. Vamos supor que haja vários arquivos como este:
# ls -l
total 8
-rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1
-rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file2
-rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file3
-rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file4
-rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file5
-rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file6
e que seja preciso alterar as permissões de todos os arquivos para que correspondam àquelas de file1. É lógico que você poderia emitir chmod 644 * para fazer essa alteração – mas e se estiver escrevendo um script para fazer isso e não souber as permissões de antemão? Ou então, talvez você esteja fazendo várias alterações nas permissões, com base em muitos arquivos diferentes, e ache inviável percorrer as permissões de cada um deles e modificá-las adequadamente.
Uma abordagem mais eficaz é tornar as permissões semelhantes àquelas do outro arquivo. Este comando faz com que as permissões de file2 sejam as mesmas de file1:
chmod --reference file1 file2
Agora, se você conferir:
# ls -l file[12]
total 8
-rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1
-rw-r--r-- 1 oracle dba 132 Aug 4 04:02 file2
As permissões de file2 foram alteradas exatamente como em file1. Você não precisou obter as permissões de file1 antes.
Também pode usar o mesmo truque na associação de grupos dos arquivos. Para fazer com que o grupo de file2 seja o mesmo de file1, você emitiria:
# chgrp --reference file1 file2
# ls -l file[12]
-rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1
-rw-r--r-- 1 oracle users 132 Aug 4 04:02 file2
Evidentemente, o que funciona para alterar os grupos também funcionará para o proprietário. A seguir está o procedimento para usar o mesmo truque em uma alteração de propriedade. Se as permissões tiverem estas características:
# ls -l file[12]
-rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1
-rw-r--r-- 1 oracle dba 132 Aug 4 04:02 file2
Você poderá alterar a propriedade assim:
# chown --reference file1 file2
# ls -l file[12]
-rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1
-rw-r--r-- 1 ananda users 132 Aug 4 04:02 file2
Observe que o grupo e também o proprietário foram alterados.
Dica para usuários Oracle
Este é um truque que pode ser usado para alterar a propriedade e as permissões de executáveis Oracle em um diretório com base em algum executável de referência. Isso se prova especialmente útil em migrações nas quais você pode (e talvez deva) instalar como um usuário diferente e depois movê-las para seu proprietário de software Oracle regular.
Mais Detalhes Sobre os Arquivos
O comando ls, com seus muitos argumentos, fornece algumas informações muito úteis sobre os arquivos. Um comando diferente e menos conhecido – stat – oferece informações ainda mais úteis.
A seguir está o procedimento para você usá-lo no executável “oracle”, encontrado em $ORACLE_HOME/bin.
# cd $ORACLE_HOME/bin
# stat oracle
File: `oracle'
Size: 93300148 Blocks: 182424 IO Block: 4096 Regular File
Device: 343h/835d Inode: 12009652 Links: 1
Access: (6751/-rwsr-s--x) Uid: ( 500/ oracle) Gid: ( 500/ dba)
Access: 2006-08-04 04:30:52.000000000 -0400
Modify: 2005-11-02 11:49:47.000000000 -0500
Change: 2005-11-02 11:55:24.000000000 -0500
Observe as informações obtidas com esse comando: além do tamanho de arquivo normal (que de qualquer maneira pode ser obtido de ls -l), é obtida a quantidade de blocos que esse arquivo ocupa. O tamanho de bloco típico do Linux é de 512 bytes, por isso um arquivo de 93.300.148 bytes ocuparia (93300148/512=) 182226,85 blocos. Como os blocos são usados em sua totalidade, esse arquivo usa uma quantidade inteira de blocos. Em vez de adivinhar, é possível simplesmente obter os blocos exatos.
Com o resultado anterior, você também obtém o GID e o UID da propriedade do arquivo e a representação octal das permissões (6751). Se quiser restaurá-lo para as mesmas permissões atuais, você poderá usar chmod 6751 oracle, em vez de explicitamente escrever por extenso as permissões.
A parte mais útil do resultado anterior são as informações de registro de data e hora de acesso a arquivos. Elas mostram que o arquivo foi acessado em 2006-08-04 04:30:52 (conforme mostrado ao lado de “Access:”), ou 04 de agosto de 2006, às 4h30min52s. Essa foi a data e hora em que alguém começou a usar o banco de dados. O arquivo foi modificado em 2005-11-02 11:49:47 (conforme mostrado ao lado de Modify:). Por fim, o registro de data e hora ao lado de “Change:” mostra quando o status do arquivo foi alterado.
-f, um modificador do comando stat, mostra as informações sobre o sistema de arquivos, e não do arquivo:
# stat -f oracle
File: "oracle"
ID: 0 Namelen: 255 Type: ext2/ext3
Blocks: Total: 24033242 Free: 15419301 Available: 14198462 Size: 4096
Inodes: Total: 12222464 Free: 12093976
Outra opção, -t, oferece exatamente as mesmas informações, mas em uma única linha:
# stat -t oracle
oracle 93300148 182424 8de9 500 500 343 12009652 1 0 0 1154682061
1130950187 1130950524 4096
Isso é muito útil em scripts de shell nos quais um simples comando de recortar pode ser usado para extrair os valores para processamento adicional.
Dica para usuários Oracle
Quando você reconecta o Oracle (geralmente em instalações de patches), ele move os executáveis existentes para um nome diferente antes de criar o novo. Por exemplo, é possível reconectar todos os utilitários por
relink utilities
Ele recompila, entre outras coisas, o executável sqlplus. Move o executável sqlplus existente para sqlplusO. Se a recompilação falhar por algum motivo, o processo de reconexão renomeará sqlplusO como sqlplus e as alterações serão canceladas. Da mesma maneira, se você descobrir um problema de funcionalidade após aplicar um patch, poderá desfazê-lo rapidamente renomeando o arquivo manualmente.
A seguir está o procedimento para usar stat nesses arquivos:
# stat sqlplus*
File: 'sqlplus'
Size: 9865 Blocks: 26 IO Block: 4096 Regular File
Device: 343h/835d Inode: 9126079 Links: 1
Access: (0751/-rwxr-x--x) Uid: ( 500/ oracle) Gid: ( 500/ dba)
Access: 2006-08-04 05:15:18.000000000 -0400
Modify: 2006-08-04 05:15:18.000000000 -0400
Change: 2006-08-04 05:15:18.000000000 -0400
File: 'sqlplusO'
Size: 8851 Blocks: 24 IO Block: 4096 Regular File
Device: 343h/835d Inode: 9125991 Links: 1
Access: (0751/-rwxr-x--x) Uid: ( 500/ oracle) Gid: ( 500/ dba)
Access: 2006-08-04 05:13:57.000000000 -0400
Modify: 2005-11-02 11:50:46.000000000 -0500
Change: 2005-11-02 11:55:24.000000000 -0500
Vemos que sqlplusO foi modificado em 11 de novembro de 2005, enquanto sqlplus foi modificado em 04 de agosto de 2006, o que também corresponde à hora de alteração do status de sqlplusO . Também vemos que a versão original de sqlplus esteve em vigor de 11 de novembro de 2005 a 04 de agosto de 2006. Se você quiser diagnosticar alguns problemas de funcionalidade, esse será um bom ponto de partida. Além das alterações nos arquivos, como você sabe a hora de alteração da permissão, pode correlacioná-la a quaisquer problemas de funcionalidade percebidos.
Outro resultado importante é o tamanho do arquivo, que é diferente – 9865 bytes do sqlplus, em contraste com 8851 do sqlplusO – indicando que as versões não são meras recompilações; elas na verdade foram alteradas com as bibliotecas adicionais (talvez). Isso também indica uma possível causa de alguns problemas.
Tipos de Arquivos
Resumo dos comandos desta parte da série
Comando | Uso |
---|---|
chmod | Para alterar as permissões de um arquivo, usando o parâmetro - -reference |
chown | Para alterar o proprietário de um arquivo, usando o parâmetro - -reference |
chgrp | Para alterar o grupo de um arquivo, usando o parâmetro - -reference |
stat | Para descobrir os atributos estendidos de um arquivo, como a data do último acesso |
file | Para descobrir o tipo do arquivo, como ASCII, de dados e assim por diante |
diff | Para ver a diferença entre os dois arquivos |
cmp | Para comparar os dois arquivos |
comm | Para ver os pontos em comum entre dois arquivos, com o resultado em três colunas |
md5sum | Para calcular o valor de hash de MD5 dos arquivos, usados para determinar se um arquivo foi alterado |
Ao ver um arquivo, como saber que tipo de arquivo é? O comando file informa isso. Por exemplo:
# file alert_DBA102.log
alert_DBA102.log: ASCII text
O arquivo alert_DBA102.log é um arquivo de texto ASCII. Vamos ver outros exemplos:
# file initTESTAUX.ora.Z
initTESTAUX.ora.Z: compress'd data 16 bits
O código informa que o arquivo está compactado, mas como saber o tipo do arquivo que foi compactado? Uma opção é descompactá-lo e executar o arquivo com ele; mas isso seria praticamente impossível. Uma opção mais eficiente é usar o parâmetro -z:
# file -z initTESTAUX.ora.Z
initTESTAUX.ora.Z: ASCII text (compress'd data 16 bits)
Outra peculiaridade é a presença de links simbólicos:
# file -z initTESTAUX.ora.Z
initTESTAUX.ora.Z: ASCII text (compress'd data 16 bits)
Isso é útil, mas para qual tipo de arquivo está sendo apontado? Em vez de executar o arquivo novamente, é possível usar a opção -l:
# file -L spfile+ASM.ora.ORIGINAL
spfile+ASM.ora.ORIGINAL: data
Vemos claramente que o arquivo é um arquivo de dados. Observe que o spfile é um arquivo binário, em contraste com init.ora; por isso o arquivo aparece como arquivo de dados.
Dica para usuários Oracle
Vamos supor que você esteja analisando um arquivo de rastreamento no diretório de destino de depuração do usuário, mas não tem certeza se o arquivo está localizado em outro diretório e meramente existe como um link simbólico, ou se alguém o compactou (ou mesmo renomeou). Uma coisa você sabe: com certeza é um arquivo ASCII. Eis o que você pode fazer:
file -Lz * | grep ASCII | cut -d":" -f1 | xargs ls -ltr
Esse comando verifica os arquivos ASCII, mesmo se estiverem compactados, e os lista em ordem cronológica.
Comparando Arquivos
Como saber se dois arquivos – file1 e file2 – são idênticos? Há várias abordagens e cada uma tem suas vantagens.
diff. O comando mais simples é diff, que mostra a diferença entre dois arquivos. A seguir está o conteúdo de dois arquivos:
# cat file1
In file1 only
In file1 and file2
# cat file2
In file1 and file2
In file2 only
Se você usar o comando diff, poderá ver a diferença entre os arquivos conforme a seguir:
# diff file1 file2
1d0
< In file1 only
2a2
> In file2 only #
No resultado, um sinal "<" na primeira coluna indica que a linha existe no arquivo mencionado primeiramente – ou seja, file1. Um sinal ">" nesse lugar indica que a linha existe no segundo arquivo (file2). Os caracteres 1d0 na primeira linha do resultado mostram o que precisa ser feito em sed para operar no arquivo file1 para torná-lo idêntico a file2.
Outra opção, -y, mostra o mesmo resultado, mas lado a lado:
# diff -y file1 file2 -W 120
In file1 only < In file1 and file2
In file1 and file2 > In file2 only
A opção -W é facultativa; ela meramente instrui o comando para que use uma tela com largura de 120 caracteres, o que é útil para arquivos com linhas longas.
Se você quer apenas saber se, e não necessariamente como, os arquivos são diferentes, pode usar a opção -q.
# diff -q file3 file4
# diff -q file3 file2
Files file3 and file2 differ
Os arquivos file3 e file4 são os mesmos, portanto não há resultado; no outro caso, relata-se o fato de que os arquivos são diferentes.
Se você está escrevendo um script de shell, talvez seja útil produzir os resultados de maneira que possam ser analisados. A opção -u faz isso:
# diff -u file1 file2
--- file1 2006-08-04 08:29:37.000000000 -0400
+++ file2 2006-08-04 08:29:42.000000000 -0400
@@ -1,2 +1,2 @@
-In file1 only
In file1 and file2
+In file2 only
O resultado mostra o conteúdo de ambos os arquivos, mas suprime as duplicidades; os sinais + e – na primeira coluna indicam as linhas dos arquivos. Nenhum caractere na primeira coluna indica a presença em ambos os arquivos.
O comando leva em consideração o espaço em branco. Se quiser ignorar o espaço em branco, use a opção -b. Use a opção -B para ignorar as linhas em branco. Por fim, use -i para ignorar a diferenciação de maiúsculas e minúsculas.
O comando diff também pode ser aplicado a diretórios. O comando:
diff dir1 dir2
mostra os arquivos presentes em qualquer um dos diretórios, ou em ambos. Se encontrar um subdiretório no mesmo nome, não fará o detalhamento para ver se algum arquivo individual é diferente. A seguir está um exemplo:
# diff DBA102 PROPRD
Common subdirectories: DBA102/adump and PROPRD/adump
Only in DBA102: afiedt.buf
Only in PROPRD: archive
Only in PROPRD: BACKUP
Only in PROPRD: BACKUP1
Only in PROPRD: BACKUP2
Only in PROPRD: BACKUP3
Only in PROPRD: BACKUP4
Only in PROPRD: BACKUP5
Only in PROPRD: BACKUP6
Only in PROPRD: BACKUP7
Only in PROPRD: BACKUP8
Only in PROPRD: BACKUP9
Common subdirectories: DBA102/bdump and PROPRD/bdump
Common subdirectories: DBA102/cdump and PROPRD/cdump
Only in PROPRD: CreateDBCatalog.log
Only in PROPRD: CreateDBCatalog.sql
Only in PROPRD: CreateDBFiles.log
Only in PROPRD: CreateDBFiles.sql
Only in PROPRD: CreateDB.log
Only in PROPRD: CreateDB.sql
Only in DBA102: dpdump
Only in PROPRD: emRepository.sql
Only in PROPRD: init.ora
Only in PROPRD: JServer.sql
Only in PROPRD: log
Only in DBA102: oradata
Only in DBA102: pfile
Only in PROPRD: postDBCreation.sql
Only in PROPRD: RMANTEST.sh
Only in PROPRD: RMANTEST.sql
Common subdirectories: DBA102/scripts and PROPRD/scripts
Only in PROPRD: sqlPlusHelp.log
Common subdirectories: DBA102/udump and PROPRD/udump
Observe que os subdiretórios comuns são relatados simplesmente como tais, mas não é feita nenhuma comparação. Se quiser fazer o detalhamento adicional e comparar os arquivos nesses subdiretórios, você deverá usar o comando a seguir:
diff -r dir1 dir2
Esse comando recursivamente entra em cada subdiretório para comparar os arquivos e relata a diferença entre os arquivos de mesmo nome.
Dica para usuários Oracle
Um uso comum do diff é distinguir entre diferentes arquivos init.ora. Como melhor prática, sempre copio o arquivo com um novo nome – por exemplo, initDBA102.ora como initDBA102.080306.ora (para indicar 03 de agosto de 2006) – antes de fazer alguma alteração. Um simples diff entre todas as versões do arquivo informa rapidamente o que foi alterado e quando.
Esse é um comando bastante poderoso para gerenciar o Oracle Home. Como melhor prática, nunca atualizo um Oracle Home ao aplicar patches. Por exemplo, vamos supor que a versão atual do Oracle seja 10.2.0.1. O ORACLE_HOME poderia ser /u01/app/oracle/product/10.2/db1. Quando chega a hora de aplicar um patch nele para o 10.2.0.2, eu não aplico o patch nesse Oracle Home. Em vez disso, começo uma instalação nova em /u01/app/oracle/product/10.2/db2 e aplico patch nesse Home. Depois de pronto, eu uso este código:
# sqlplus / as sysdba
SQL> shutdown immediate
SQL> exit
# export ORACLE_HOME=/u01/app/oracle/product/10.2/db2
# export PATH=$ORACLE_HOME/bin:$PATH
# sqlplus / as sysdba
SQL> @$ORACLE_HOME/rdbms/admin/catalog
...
e assim por diante.
A finalidade dessa abordagem é que o Oracle Home original não seja atrapalhado e eu possa facilmente reverter a situação em caso de problema. Isso também significa que o banco de dados sai do ar e volta novamente, quase que instantaneamente. Se eu instalasse o patch diretamente no Oracle Home, teria de encerrar o banco de dados por bastante tempo – durante toda a aplicação do patch. Além disso, se a aplicação do patch tivesse falhado por algum motivo, eu não teria um Oracle Home limpo.
Agora que tenho vários Oracle Homes, como posso ver o que foi alterado? É bem simples, pois posso usar:
diff -r /u01/app/oracle/product/10.2/db1 /u01/app/oracle/product/10.2/db2 |
grep -v Common
O código informa as diferenças entre os dois Oracle Homes e entre os arquivos de mesmo nome. Alguns arquivos importantes como tnsnames.ora, listener.ora e sqlnet.ora não devem mostrar grandes diferenças, mas se mostrarem, precisarei entender o porquê.
cmp. O comando cmp é semelhante a diff:
# cmp file1 file2
file1 file2 differ: byte 10, line 1
O resultado é retornado como o primeiro sinal de diferença. Você pode usar isso para identificar os possíveis pontos diferentes dos arquivos. Como diff, cmp tem muitas opções, sendo a mais importante delas a opção -s, que meramente retorna um código:
- 0, se os arquivos forem idênticos
- 1, se forem diferentes
- Algum outro número diferente de zero, se não for possível fazer a comparação
A seguir está um exemplo:
# cmp -s file3 file4
# echo $?
0
A variável especial $? indica o código de retorno do último comando executado. Nesse caso, é 0, o que significa que os arquivos file1 e file2 são idênticos.
# cmp -s file1 file2
# echo $?
1
significa que file1 e file2 não são os mesmos.
Essa propriedade de cmp pode se provar útil em script de shell, em que você meramente quer verificar se dois arquivos são diferentes de alguma maneira, mas não necessariamente verificam qual é a diferença. Outro uso importante desse comando é comparar arquivos binários, em que diff pode não ser confiável.
Dica para usuários Oracle
Lembre-se de uma dica anterior: ao reconectar executáveis Oracle, a versão mais antiga é mantida antes de ser sobrescrita. Assim, ao se reconectar, o executável sqlplus é renomeado como “sqlplusO” e o recém-compilado sqlplus é colocado em $ORACLE_HOME/bin. Então, como garantir que o sqlplus recém-criado seja de alguma maneira diferente? Basta usar:
# cmp sqlplus sqlplusO
sqlplus sqlplusO differ: byte 657, line 7
Se você verificar o tamanho:
# ls -l sqlplus*
-rwxr-x--x 1 oracle dba 8851 Aug 4 05:15 sqlplus
-rwxr-x--x 1 oracle dba 8851 Nov 2 2005 sqlplusO
Mesmo que o tamanho seja igual em ambos os casos, cmp provou que os dois programas são diferentes.
comm. O comando comm é semelhante aos outros, mas o resultado aparece em três colunas, separadas por tabulações. A seguir está um exemplo:
# comm file1 file2
In file1 and file2
In file1 only
In file1 and file2
In file2 only
Esse comando é útil quando se quer ver o conteúdo de um arquivo não no outro, e não apenas uma diferença – uma espécie de utilitário MINUS na linguagem SQL. A opção -1 suprime o conteúdo encontrado no primeiro arquivo:
# comm -1 file1 file2
In file1 and file2
In file2 only
md5sum. Este comando gera um valor hash de MD5 de 32 bits dos arquivos:
# md5sum file1
ef929460b3731851259137194fe5ac47 file1
Dois arquivos com a mesma soma de verificação podem ser considerados idênticos. Entretanto, a utilidade desse comando vai além da mera comparação de arquivos. Ele também pode oferecer um mecanismo para garantir sua integridade.
Vamos supor que você tenha dois arquivos importantes – file1 e file2 – que precisam ser protegidos. Você pode usar a verificação da opção --check para confirmar que os arquivos não foram alterados. Primeiro, crie um arquivo de soma de verificação para esses dois arquivos importantes e mantenha-o em local seguro:
# md5sum file1 file2 > f1f2
Depois, ao verificar se os arquivos ainda estão intactos:
# md5sum --check f1f2
file1: OK
file2: OK
Vemos claramente que eles não foram modificados. Agora altere um deles e verifique o MD5:
# cp file2 file1
# md5sum --check f1f2
file1: FAILED
file2: OK
md5sum: WARNING: 1 of 2 computed checksums did NOT match
O resultado mostra claramente que file1 foi modificado.
Dica para usuários Oracle
O md5sum é um comando extremamente poderoso para implementações de segurança. Alguns dos arquivos de configuração que você gerencia, como listener.ora, tnsnames.ora e init.ora, são cruciais em uma infra-estrutura Oracle bem-sucedida e qualquer modificação pode resultar em tempo de inatividade. Em geral eles fazem parte de seu processo de controle de alterações. Em vez de apenas confiar na palavra de terceiros de que esses arquivos não foram alterados, comprove usando a soma de verificação de MD5. Crie um arquivo de soma de verificação e sempre que fizer uma alteração planejada, recrie-o. Como parte da compliance, verifique esse arquivo usando o comando md5sum. Se alguém sem querer atualizou um dos arquivos cruciais, você imediatamente detectará a alteração.
Na mesma linha, você também pode criar somas de verificação de MD5 para todos os executáveis em $ORACLE_HOME/bin e compará-las periodicamente para modificações não-autorizadas.
Conclusão
Até agora você aprendeu somente alguns dos comandos Linux que achará úteis para executar seu trabalho com eficácia. Na próxima parte da série, descreverei alguns comandos mais sofisticados porém úteis, como strace, whereis, renice, skill e muitos outros.
Arup Nanda ( arup@proligence.com) é DBA Oracle há mais de 12 anos, lidando com todos os aspectos de gerenciamento de banco de dados – como ajuste de performance, segurança e recuperação de catástrofes, dentre outros. É co-autor de PL/SQL for DBAs (O'Reilly Media, 2005), foi “DBA do Ano” da Oracle Magazine em 2003 e é ACE Oracle.