Aprenda Linux, 101: Gerenciamento de arquivo e diretório

Familiarizando-se com arquivos e diretórios Linux

Provavelmente, você já ouviu falar que tudo no Linux é um arquivo, portanto comece no caminho certo com um sólido fundamento em gerenciamento de arquivo e diretório – localizar, listar, mover, copiar e arquivar. O material desse artigo pode ser utilizado para o exame LPI®101 para certificação de administrador de sistema Linux, ou apenas para aprender.

Ian Shields, Senior Programmer, IBM

Ian ShieldsIan Shields trabalha em vários dos projetos Linux para a zona Linux do developerWorks. Ele é um programador senior da IBM em Research Triangle Park, NC. Ele iniciou na IBM em Canberra, Austrália, como um Engenheiro de Sistemas em 1973 e, desde então, trabalhou em sistemas de comunicações e computação disseminada em Montreal, no Canadá, e em RTP na Carolina do Norte, nos Estados Unidos. Ele possui diversas patentes. Sua graduação é em matemática pura e filosofia na Australian National University. Ele possui mestrado em ciências e é doutor em ciências da computação na Universidade do Estado da Carolina do Norte.



10/Nov/2009

Sobre esta série

Esta série de artigos ajuda a aprender tarefas de administração de sistema Linux. O material desses artigos também pode ser usado para preparação para Exames de Certificação de nível 1 do Linux Professional Institute (LPIC-1).

Veja nossa series roadmap para descrição e link de cada artigo nesta série. O roteiro está em andamento e reflete os recentes (abril de 2009) objetivos para o exame LPIC-1: assim que concluirmos os artigos, eles serão adicionados ao roteiro. Enquanto isso, é possível encontrar versões mais recentes de material similar, suportando prévios objetivos LPIC-1, anterior a abril de 2009, em nosso LPI certification exam prep tutorials.

Pré-requisitos

Para obter o melhor dos artigos nessas séries, é necessário ter o conhecimento básico do Linux e um sistema Linux funcionando, no qual você pode praticar os comandos abordados neste artigo. Às vezes, versões diferentes de um programa podem formatar o resultado de maneira diferente, portanto seus resultados podem não ficar exatamente parecidos com os das listagens e números mostrados aqui.

Visão geral

Este artigo fundamenta você nos comandos básicos do Linux para manipulação de arquivos e diretórios. Aprenda como:

  • Listar conteúdo de diretório
  • Criar, mover ou remover arquivos e diretórios
  • Manipular diversos arquivos e diretórios recursivamente
  • Usar padrões curinga para manipular arquivos
  • Usar o comando find para localizar e agir em arquivos baseados em tipo, tamanho ou tempo.
  • Comprimir e descomprimir arquivos usando gzip e bzip2
  • Arquivar arquivos usando tar, cpio e dd

Esse artigo ajuda a preparar para o Objetivo 103.2 no Tópico103 do exame 101 de Administração Nível Júnior do Linux Professional Institute (LPIC-1). O objetivo tem peso 4.


Listando diretórios

Todos os arquivos em sistemas Linux e UNIX® são acessados como parte de um grande sistema de arquivos estruturado em árvore que em root em /. Podem ser adicionadas mais ramificações a esta árvore ao montar essa ramificações e depois removê-las aodesmontar. Montar e desmontar serão cobertos neste artigo em Montagem e desmontagem de sistemas de arquivos (consulte roteiro das séries).

Listando entradas de diretório

Neste artigo, praticaremos os comandos usando os arquivos criados no artigo "Aprenda Linux 101: Fluxos e filtros de texto." Se você acompanhou esse artigo, você criou um diretório, lpi103-2, em seu diretório doméstico. Se não, use outro diretório em seu sistema para praticar os comandos abordados neste artigo.

Nomes de arquivo e diretório ou são absolutos, o que significa que começam com a /, ou são relativos ao atual diretório de trabalho, o que significa que não começam com a /. O caminho absoluto para um arquivo ou diretório consiste de a / seguido de séries de zero ou mais nomes de diretório, cada um seguido por outro / e então um nome final.

Dado a um arquivo ou diretório um nome relativo ao atual diretório de trabalho, basta simplesmente concatenar o nome absoluto do diretório, uma /, e o nome relativo Por exemplo, o diretório lpi103-2, criado no artigo anterior, foi criado no meu diretório home, /home/ian, portanto seu caminho total ou absoluto é /home/ian/lpi103-2.

Para exibir o nome do atual diretório de trabalho, use o comando pwd. Em geral, está disponível na variável de ambiente PWD. A Listagem 1 mostra o uso do comando pwd, e três modos diferentes de usar o comando ls para listar os arquivos nesse diretório.

Listagem 1. Listando entradas de diretório
 [ian@echidna lpi103-2]$ pwd
                /home/ian/lpi103-2 [ian@echidna lpi103-2]$ echo "$PWD"
                /home/ian/lpi103-2 [ian@echidna lpi103-2]$ ls sedtab text1 text2
                text3 text4 text5 text6 xaa xab yaa yab [ian@echidna lpi103-2]$ ls
                    "$PWD" sedtab text1 text2 text3 text4 text5 text6 xaa xab yaa yab
                [ian@echidna lpi103-2]$ ls /home/ian/lpi103-2 sedtab text1 text2
                text3 text4 text5 text6 xaa xab yaa yab

Como se vê, é possível dar um nome de diretório relativo ou absoluto como parâmetro para o comando ls que será listado o conteúdo deste diretório.

Listando detalhes

Em um dispositivo e armazenamento, um arquivo ou diretório está contido em um conjunto de blocos. Informações sobre um arquivo estão contidas em um inode que registra informações como o proprietário, quando o arquivo foi acessado pela última vez, qual seu tamanho, se é um diretório ou não, e quem pode ler ou escrever nele. O número inode também é conhecido como o número serial de arquivo e é único dentro de um determinado sistema de arquivo.. Podemos usar a opção -l (ou --format=long) para exibir algumas informações armazenadas no inode.

Por padrão, o comando ls não lista arquivos especiais, cujos nomes começam com um ponto (.). Todo diretório, a não ser o diretório e root, tem pelo menos duas entradas especiais: o próprio diretório (.) e o diretório-pai (..). O diretório de root não tem um diretório-pai.

A Listagem 2 usa as opções -l e -a para exibir uma longa listagem de formato de todos os arquivos, incluindo as entradas de diretório . e .. .

Listagem 2. Exibindo uma longa listagem de diretório
[ian@echidna lpi103-2]$ ls -al
total 52
drwxrwxr-x.  2 ian ian 4096 2009-08-11 21:21 .
drwx------. 35 ian ian 4096 2009-08-12 10:55 ..
-rw-rw-r--.  1 ian ian    8 2009-08-11 21:17 sedtab
-rw-rw-r--.  1 ian ian   24 2009-08-11 14:02 text1
-rw-rw-r--.  1 ian ian   25 2009-08-11 14:27 text2
-rw-rw-r--.  1 ian ian   63 2009-08-11 15:41 text3
-rw-rw-r--.  1 ian ian   26 2009-08-11 15:42 text4
-rw-rw-r--.  1 ian ian   24 2009-08-11 18:47 text5
-rw-rw-r--.  1 ian ian   98 2009-08-11 21:21 text6
-rw-rw-r--.  1 ian ian   15 2009-08-11 14:41 xaa
-rw-rw-r--.  1 ian ian    9 2009-08-11 14:41 xab
-rw-rw-r--.  1 ian ian   17 2009-08-11 14:41 yaa
-rw-rw-r--.  1 ian ian    8 2009-08-11 14:41 yab

Na Listagem 2, a primeira linha mostra o número total de blocos de disco (52) utilizados pelos arquivos listados. As linhas restantes indicam as entradas de diretório.

  • O primeiro campo (drwxrwxr-x ou -rw-rw-r-- neste caso) diz se o arquivo é um diretório (d) ou um arquivo regular (-). Também é possível ver links simbólicos (l) ou outros valores para alguns arquivos especiais (como os arquivos em /dev filesystem). Você aprenderá mais sobre links simbólicos no artigo Criar e hard links e links simbólicos (consulte o roteiro das séries). O tipo é seguido por três conjuntos de permissões (como rwx or r--) para o proprietário, os membros do grupo do proprietário, e todo e qualquer indivíduo. Os três valores indicam, respectivamente, se o usuários, grupo ou alguém leu (r), escreveu (w) ou executou (x) permissão. Outros usos como setuid serão discutidos no artigo Gerencie permissões de arquivo e propriedade (consulte o roteiro das séries).
  • O próximo campo é um número que diz o número de hard links para o arquivo. Dissemos que o inode contém informações sobre o arquivo. A entrada de diretório do arquivo contém um hard link (ou apontador) para o arquivo, portanto cada entrada listada deve ter pelo menos um hard link. Entradas de diretório têm um hard link adicional para a entrada . e um para cada entrada de subdiretório. Portanto, podemos ver na Listagem 2 que meu diretório doméstico, representado por .. tem alguns subdiretórios e 35 hard links.
  • Os próximos dois campos são do proprietário do arquivo e do grupo principal do proprietário. Alguns sistemas, como o Red Hat ou Fedora, não podem fornecer um grupo separado para cada usuário. Em outros sistemas, todos os usuários devem estar em um ou em alguns grupos.
  • O campo seguinte contém o comprimento do arquivo em bytes.
  • O penúltimo campo contém o registro de data e hora da última modificação.
  • E o último campo contém o nome do campo ou diretório.

A opção -i do ls exibirá os números inode. Você verá inodes outra vez mais tarde neste artigo e também no artigo Criar e mudar hard links e links simbólicos (consulte o roteiro das séries).

Múltiplos arquivos

Também é possível especificar diversos parâmetros para o comando ls, onde cada nome é de um arquivo ou de um diretório. Para nomes de diretório, o comando ls lista o conteúdo do diretório e não da informação sobre o próprio diretório. Em nosso exemplo, vamos supor que queremos informações sobre a entrada do próprio diretório lpi103-2 conforme está listado no diretório-pai. O comando ls -l ../lpi103-2 nos daria uma listagem como a do exemplo anterior. A Listagem 3 mostra como adicionar a opção -d para listar informações sobre entradas de diretório e não o conteúdo de diretórios e também como listar entradas para múltiplos arquivos ou diretórios.

Listagem 3. Usando ls -d
[ian@echidna lpi103-2]$ ls -ld ../lpi103-2 sedtab xaa
drwxrwxr-x. 2 ian ian 4096 2009-08-12 15:31 ../lpi103-2
-rw-rw-r--. 1 ian ian    8 2009-08-11 21:17 sedtab
-rw-rw-r--. 1 ian ian   15 2009-08-11 14:41 xaa

Observe que o horário de modificação para lpi103-2 é diferente daquele da listagem anterior. Além disso, como na listagem anterior, é diferente dos registros de data e hora de qualquer arquivo no diretório. É o que se deveria esperar? Normalmente, não. No entanto, ao desenvolver este artigo, criei alguns exemplos extras e depois excluí, portanto os registros de data e hora do diretório refletem esse fato. Falaremos mais um pouco depois sobre horários de arquivoManipulando diversos artigos e diretórios.

Classificando o resultado

Por padrão, ls lista arquivos alfabeticamente. Há diversas opções para classificar o resultado. Por exemplo, ls -t classificará por horário de modificação (do mais recente para o mais antigo) enquanto ls -lS produzirá uma longa listagem classificada por tamanho (da maior para a menor). Adicionar -r inverterá a ordem de classificação. Por exemplo, use ls -lrt para produzir uma longa listagem classificada do mais antigo para o mais recente. Consulte a página de manual para outras maneiras de listar arquivos e diretórios.


Copiando, movendo e excluindo arquivos

Já aprendemos algumas maneiras de criar arquivos, mas vamos supor que queremos fazer cópias de arquivos, renomear arquivos e mover arquivos pela hierarquia sistema de arquivos, ou até mesmo excluí-los. Usamos três pequenos comandos para isso.

cp
é usado para fazer uma cópia de um ou mais arquivos ou diretórios. Você deve dar um (ou mais) nomes de origem e um nome de destino. Nomes de origem ou destino podem incluir uma especificação de caminho. Se o destino é um diretório existente, todas as origens são copiadas para o destino. Se o destino é um diretório que não existe, a origem (única) também deve ser um diretório e uma cópia do diretório de origem e seu conteúdo é feito com o nome de destino como o novo nome. Se o destino é um arquivo, a única origem também deve ser um arquivo e uma cópia do arquivo de origem é feita com o nome de destino como o novo nome, substituindo qualquer arquivo existente com o mesmo nome. Observe que não há premissa padrão do destino sendo o atual diretório como os sistemas operacionais DOS e Windows.
mv
é usado para mover ou renomear um ou mais arquivos e diretórios. Em geral, os nomes que a serem usados seguem as mesmas regras de cópias com cp; é possível renomear um único arquivo ou mover um conjunto e arquivos para um novo diretório. Já que o nome é apenas uma entrada de diretório que se conecta a um inode, não é nenhuma surpresa que o número de inode não mude a menos que o arquivo seja movido para um outro sistema de arquivos, e nesse caso, mover tem o comportamento mais como uma cópia seguida da exclusão do original.
rm
é usado para remover um ou mais arquivos. Veremos como remover diretórios em breve.

Onde está o comando rename ?

Se você está costumado com um sistema DOS ou Windows®, pode achar estranho usar mv para renomear um arquivo. Linux tem um comando rename, mas tem uma sintaxe diferente dos comandos DOS e Windows com o mesmo nome. Consulte a página de manual para detalhes de como usar esse comando.

A Listagem 4 demonstra o uso de cp e mv para fazer algumas cópias de backup de arquivos de texto. Também usamos ls -i para mostrar inodes para alguns dos nossos arquivos.

  1. Primeiro fazemos uma cópia do nosso arquivo text1 como text1.bkp.
  2. Decidimos então criar um subdiretório de backup usando o comando mkdir
  3. Fazemos uma segunda cópia de backup de text 1, dessa vez no diretório de backup, e mostramos que todos os três arquivos têm diferentes inodes.
  4. Movemos nosso text1.bkp para o diretório de backup sendo renomeado para ficar mais consistente com o segundo backup. Podemos fazer isso com um único comando, mas aqui usamos dois como demonstração.
  5. Verificamos outra vez os inodes e confirmamos que text1.bkp com inode 934193 não está mais no diretório lpi103-2, mas que o inode é o do text1.bkp.1 no diretório de backup.
Listagem 4. Copiando e movendo arquivos
[ian@echidna lpi103-2]$ cp text1 text1.bkp
[ian@echidna lpi103-2]$ mkdir backup
[ian@echidna lpi103-2]$ cp text1 backup/text1.bkp.2
[ian@echidna lpi103-2]$ ls -i text1 text1.bkp backup
933892 text1  934193 text1.bkp

backup:
934195 text1.bkp.2
[ian@echidna lpi103-2]$ mv text1.bkp backup
[ian@echidna lpi103-2]$ mv backup/text1.bkp backup/text1.bkp.1

[ian@echidna lpi103-2]$ ls -i text1 text1.bkp backup
ls: cannot access text1.bkp: No such file or directory
933892 text1

backup:
934193 text1.bkp.1  934195 text1.bkp.2

Normalmente, o comando cp copia um arquivo sobre uma cópia já existente, se o arquivo existente for gravável. Por outro lado, mv não move nem renomeia um arquivo se houver uma tag. Há diversas opções úteis relativas a este comportamento decp e mv.

-f ou --force
fazem com que cp tente remover um arquivo de destino existente mesmo não sendo gravável.
-i ou --interactive
pedirá confirmação antes de tentar substituir um arquivo existente
-b ou --backup
fará um backup de qualquer arquivo substituído

Como sempre, consulte as páginas de manual para detalhes sobre essas e outras opções para copiar e mover.

A Listagem 6 mostra cópias com backup e exclusão de arquivo

Listagem 5. Fazendo cópias de backup e excluindo arquivos
[ian@echidna lpi103-2]$ cp text2 backup
[ian@echidna lpi103-2]$ cp --backup=t text2 backup
[ian@echidna lpi103-2]$ ls backup
text1.bkp.1  text1.bkp.2  text2  text2.~1~
[ian@echidna lpi103-2]$ rm backup/text2 backup/text2.~1~
[ian@echidna lpi103-2]$ ls backup
text1.bkp.1  text1.bkp.2

Observe que o comando rm também aceita o -i (interativo) e -f (opções de força). Ao remover um arquivo usando rm, o sistema de arquivos não tem mais acesso a ele. Alguns sistemas não conseguem definir um alias alias rm='rm -i' para o usuário de root evitar a exclusão de arquivo involuntária. Esta também é uma boa ideia para usuários usuais, se não ficarem nervosos com o que podem acidentalmente excluir.

Antes de deixarmos esta discussão, devemos observar que o comando cp não consegue criar um novo registro de data e hora para o novo arquivo. O proprietário e o grupo também são definidos para o proprietário e o grupo do usuário que está fazendo a cópia. A opção -p pode ser usada para preservar atributos selecionados. Observe que o usuário de root pode ser o único usuário a preservar propriedade. Consulte as páginas iniciais para detalhes.


Criando e removendo diretórios

Já vimos como criar um diretório com mkdir. Agora além disso vamos ver também mkdir e apresentar rmdir, seu análogo para remover diretórios.

Mkdir

Suponha que estamos no diretório lpi103-2 e queremos criar subdiretórios dir1 e dir2. mkdir, como os comandos que acabamos de rever, serão manipuladas solicitações de criação de diretório em uma etapa conforme mostra a Listagem 6.

Listagem 6. Criando múltiplos diretórios
 [ian@echidna lpi103-2]$ mkdir dir1 dir2

Repare que não há saída em uma conclusão bem sucedida, embora possa ser usado o echo $? para confirmar que o código de saída é realmente 0.

Se, em vez disso, quisermos criar um subdiretório aninhado, como d1/d2/d3, não seria possível porque os diretórios d1 e d2 não existem. Felizmente, mkdir tem uma opção -p que permite criar qualquer diretório-pai necessário, conforme demonstrado na Listagem 7.

Listagem 7. Criando diretórios-pai
[ian@echidna lpi103-2]$ mkdir d1/d2/d3
mkdir: cannot create directory `d1/d2/d3': No such file or directory
[ian@echidna lpi103-2]$ echo $?
1
[ian@echidna lpi103-2]$ mkdir -p d1/d2/d3
[ian@echidna lpi103-2]$ echo $?
0

Rmdir

Remover diretórios usando o comando rmdir é o oposto de criar um diretório. Mais uma vez, há uma opção -p para remover pais também. É possível remover um diretório com rmdir apenas se estiver vazio, sem nenhuma opção que obrigue a remoção. Veremos um outro meio de concluir esse truque ao analisarmos manipulação recursiva. Depois de aprender isso, é provável que quase nunca você use rmdir na linha de comando, mas é bom ficar conhecendo.

Para demonstrar a remoção de diretório, copiamos nosso arquivo text1 para o diretório d1/d2 para que não fique mais vazio. Usamos rmdir para remover todos os diretórios que acabamos de criar com mkdir. Como podemos ver, d1 e d2 não foram removidos porque d2 não estava vazio. Os outros diretórios foram removidos. Depois de remover a cópia de text1 de d2, podemos remover d1 e d2 com uma simples invocação de rmdir -p.

Listagem 8. Removendo diretórios
[ian@echidna lpi103-2]$ cp text1 d1/d2
[ian@echidna lpi103-2]$ rmdir -p d1/d2/d3 dir1 dir2
rmdir: failed to remove directory `d1/d2': Directory not empty
[ian@echidna lpi103-2]$ ls . d1/d2
.:
backup  sedtab  text2  text4  text6  xab  yab
d1      text1   text3  text5  xaa    yaa

d1/d2:
text1
[ian@echidna lpi103-2]$ rm d1/d2/text1
[ian@echidna lpi103-2]$ rmdir -p d1/d2

Manipulando diversos arquivos e diretórios

Até agora, os comandos que usamos operavam em um único arquivo ou talvez alguns poucos arquivos nomeados individualmente. Neste artigo, examinaremos diversas operações para manipular múltiplos arquivos, manipulando recursivamente parte de uma árvore de diretório e salvando e restaurando múltiplos arquivos ou diretórios.


Manipulação recursiva

Listagem recursiva

O comando ls tem uma opção -R (observe que é "R" maiúsculo) para listar um diretório e todos os seus subdiretórios. A opção recursiva se aplica apenas a nomes de diretórios; todos os arquivos não vão se chamar 'text1', por exemplo, em uma árvore de diretório. Podemos usar outras opções que já foram vistas junto com -R. Uma listagem recursiva do nosso diretório lpi103-2, incluindo números inode, é exibida na Listagem 9.

Listagem 9. Exibindo listagens de diretório recursivamente
[ian@echidna lpi103-2]$ ls -iR
.:
934194 backup  933892 text1  933898 text3  933900 text5  933894 xaa  933896 yaa
933901 sedtab  933893 text2  933899 text4  933902 text6  933895 xab  933897 yab

./backup:
934193 text1.bkp.1  934195 text1.bkp.2

Cópia recursiva

Use a opção -r (ou a opção -R ou --recursive) para fazer o comando cp descer para diretórios de origem e copiar o conteúdo recursivamente. Para evitar uma recursão infinita, o próprio diretório de origem não deve ser copiado. A Listagem 10 mostra como copiar tudo no nosso diretório lpi103-2 para um subdiretório copy1. Usamos ls -R para mostrar a árvore de diretório resultante.

Listagem 10. Copiando recursivamente
[ian@echidna lpi103-2]$ cp -pR . copy1
cp: cannot copy a directory, `.', into itself, `copy1'
[ian@echidna lpi103-2]$ ls -R
.:
backup  copy1  sedtab  text1  text2  text3  text4  text5  text6  xaa  xab  yaa  yab

./backup:
text1.bkp.1  text1.bkp.2

./copy1:
text2  text3  text5  xaa  yaa  yab

Exclusão de maneira repetitiva

Falamos anteriormente que rmdir apenas remove diretórios vazios. Podemos usar a opção -r (ou -R ou --recursive) para fazer com que o comando rm remova os dois arquivos e diretórios, conforme mostrado na Listagem 11 onde removemos o diretório copy1 que acabamos de criar, junto com seu conteúdo, incluindo o subdiretório de backup e seu conteúdo.

Listagem 11. Excluindo recursivamente
[ian@echidna lpi103-2]$ rm -r copy1
[ian@echidna lpi103-2]$ ls -R
.:
backup  sedtab  text1  text2  text3  text4  text5  text6  xaa  xab  yaa  yab

./backup:
text1.bkp.1  text1.bkp.2

Se você tem arquivos que não podem ser gravados, é necessário adicionar a opção -f para forçar a remoção. Geralmente isso é feito pelo root ao limpar, mas preste atenção para não perder dados valiosos caso não tome cuidado.


Curingas e globbing

Em geral, é necessário realizar uma única operação em diversos objetos de sistema de arquivos, sem operar na árvore toda, conforme feito nas operações recursivas. Por exemplo, se quiser localizar os horários de modificação de todos os arquivos de texto criados em lpi103-2, sem listar os arquivos divididos. Embora seja fácil com nosso pequeno diretório, é bem difícil em um grande sistema de arquivos.

Para resolver esse problema, use o suporte curinga que foi construído no shell bash. Esse suporte, também chamado "globbing" (porque foi originalmente implementado como um programa chamado /etc/glob), permite especificar diversos artigos usando o padrão curinga.

Uma cadeia contendo algum dos caracteres '?', '*' ou '[', é um padrão curinga. Globbing é o processo pelo qual o shell (ou possivelmente outro programa) expande esses padrões pra uma lista de nomes de caminho que correspondam ao padrão. A correspondência é feita como se segue:

?
corresponde a qualquer caractere único
*
corresponde a qualquer cadeia, incluindo uma cadeia vazia.
[
introduz uma classe de caractere. Uma classe de caractere é uma cadeia não vazia, terminada em "]". Uma correspondência significa corresponder a qualquer caractere único dentro dos colchetes. Existem algumas considerações especiais.
  • Os caracteres '*' and '?' se correspondem entre si Se forem utilizados em nomes de arquivos, é preciso ter cuidado sobre a colocação de aspas ou escape.
  • Se a cadeia deve ser não vazia e terminada em ']', coloque ']' primeiro na cadeia que deseja corresponder.
  • O caractere '-' entre os outros dois representa uma abrangência que inclui os outros dois caracteres e todos os caracteres entre eles na sequência de intercalação. Por exemplo, [0-9a-fA-F] representa qualquer dígito hexadecimal e letra maiúscula ou minúscula. Você pode corresponder '-' se for colocado no começo ou no fim de um intervalo.
  • O caractere '!' especificado como primeiro caractere de um intervalo complementa o intervalo de forma a corresponder com qualquer caractere, exceto os caracteres restantes. Por exemplo, [!0-9] significa qualquer caractere exceto os dígitos de 0 a 9. Um '!' em qualquer posição exceto a primeira corresponde a si mesmo. Lembre-se que '!' também é usado com a função de histórico de shell, portanto é preciso ter cuidado para que ocorra o escape apropriado.

Nota: Padrões curinga e padrões de expressão regular compartilham as mesmas caracterísitcas, mas não são os mesmos. Preste bastante atenção.

Globbing é aplicado separadamente a cada componente de um nome de caminho. Não é possivel corresponder um '/', nem incluir em um intervalo. Pode ser usado em qualquer lugar onde seja possível especificar diversos nomes de arquivo ou de diretório, como por exemplo nos comandos ls, cp, mv, ou rm. Na Listagem 12, primeiro criamos um par de arquivos nomeados diferentemente e então usamos os comandos ls e rm com padrões curinga.

Listagem 12. Exemplos de modelo de caractere curinga
[ian@echidna lpi103-2]$ echo odd1>'text[*?!1]'
[ian@echidna lpi103-2]$ echo odd2>'text[2*?!]'
[ian@echidna lpi103-2]$ ls
backup  text1       text2       text3  text5  xaa  yaa
sedtab  text[*?!1]  text[2*?!]  text4  text6  xab  yab
[ian@echidna lpi103-2]$ ls text[2-4]
text2  text3  text4
[ian@echidna lpi103-2]$ ls text[!2-4]

text1  text5  text6
[ian@echidna lpi103-2]$ ls text*[2-4]*
text2  text[2*?!]  text3  text4
[ian@echidna lpi103-2]$ ls text*[!2-4]* # Surprise!
text1  text[*?!1]  text[2*?!]  text5  text6
[ian@echidna lpi103-2]$ ls text*[!2-4] # Another surprise!
text1  text[*?!1]  text[2*?!]  text5  text6
[ian@echidna lpi103-2]$ echo text*>text10
[ian@echidna lpi103-2]$ ls *\!*
text[*?!1]  text[2*?!]
[ian@echidna lpi103-2]$ ls *[x\!]*

text1  text[*?!1]  text10  text2  text[2*?!]  text3  text4  text5  text6  xaa  xab
[ian@echidna lpi103-2]$ ls *[y\!]*
text[*?!1]  text[2*?!]  yaa  yab
[ian@echidna lpi103-2]$ ls tex?[[]*
text[*?!1]  text[2*?!]
[ian@echidna lpi103-2]$ rm tex?[[]*
[ian@echidna lpi103-2]$ ls *b*
sedtab  xab  yab

backup:
text1.bkp.1  text1.bkp.2
[ian@echidna lpi103-2]$ ls backup/*2
backup/text1.bkp.2
[ian@echidna lpi103-2]$ ls -d .*

.  ..

Notas:

  1. Complementação junto com '*' pode levar a algumas surpresas. O padrão '*[!2-4]' corresponde à maior parte de um nome que não tem 2, 3, ou 4 seguinte, e que é correspondido por ambos text[*?!1] e text[2*?!]. Agora as duas surpresas devem estar claras.
  2. Assim como nos exemplos anteriores de ls, se a expansão de padrões resulta em um nome que é um nome de diretório e a opção -d não está especificada, o conteúdo de tal diretório será listado (como em nosso exemplo acima para o padrão '*b*').
  3. Se um nome de arquivo começa com ponto(.), tal caractere deve ser correspondido explicitamente. Observe que apenas o último comando ls listou as duas entradas especiais de diretório (. e ..).

Lembre-se que quaisquer caracteres curinga em um comando estão sujeitos a ser expandidos pelo shell, o que pode levar a resultados inesperados. Além disso, se for especificado o padrão que não corresponde a qualquer objeto de sistema de arquivo, o POSIX solicita que a sequência de padrão original seja passada ao comando. Algumas implementações anteriores passaram uma lista nula ao comando, assim você pode executar em scripts antigos que permitem comportamento incomum. Demonstramos esses pontos na Listagem 13.

Listagem 13. Surpresas do padrão curinga
[ian@echidna lpi103-2]$ echo text*
text1 text10 text2 text3 text4 text5 text6
[ian@echidna lpi103-2]$ echo "text*"
text*
[ian@echidna lpi103-2]$ echo text[[\!?]z??
text[[!?]z??

Para mais informações sobre globbing, verifique man 7 glob. Você vai precisar do número de seção, visto que também há informação de glob na seção 3. O melhor meio de entender todas as diversas interações de shell é pela prática, portanto, experimente esses curingas sempre que tiver uma chance. Lembre-se de experimentar ls para verificar seu padrão curinga antes de permitir cp, mv, ou pior, rm de fazer algo de modo inesperado.


Criando arquivos com o touch

Vamos analisar agora o comando touch que pode atualizar o acesso ao arquivo e horários de modificação, ou criar arquivos vazios. Na próxima parte, veremos como usar essa informação para localizar arquivos e diretórios. Continuaremos a usar o diretório lpi103-2 para nossos exemplos Também abordaremos as diversas maneiras de especificar registros de data e hora.

touch

O comando touch sem opções adota um ou mias nomes de arquivo como parâmetros e atualiza o tempo de modificação dos arquivos. É o mesmo registro de data e hora exibido com uma longa listagem de diretório. Na Listagem 14, usaremos nosso velho amigo echo para criar um pequeno arquivo chamado f1, apara então usar uma longa listagem de diretório para exibir o tempo de modificação (ou mtime). Nesse caso, também acontece ser o horário em que o arquivo foi criado. Usamos o comando sleep para esperar por 60 segundos e executar ls outra vez. Observe que o registro de data e hora mudou em um minuto.

Listagem 14. Atualizando horário de modificação com touch
[ian@echidna lpi103-2]$ echo xxx>f1; ls -l f1; sleep 60; touch f1; ls -l f1
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:24 f1
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:25 f1

Ao especificar um nome de arquivo para um arquivo que não existe, touch normalmente cria um arquivo vazio, a menos que você fique especificada a opção -c ou --no-create. A Listagem 15 mostra esses dois comandos. Observe que apenas f2 foi criado.

Listagem 15. Criando arquivos vazios com touch
[ian@echidna lpi103-2]$ touch f2; touch -c f3; ls -l f*
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:25 f1
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:27 f2

O comando touch também pode determinar um horário de modificação do arquivo (também conhecido como mtime) para data e hora específicas, usando as opções -d ou -t. O -d é muito flexível nos formatos data e hora que aceitará, enquanto a opção -t precisa de pelo menos um tempo MMDDhhmm com valores opcionais de ano e segundos. A Listagem 16 mostra alguns exemplos.

Listagem 16. Configurando mtime com touch
[ian@echidna lpi103-2]$ touch -t 200908121510.59 f3
[ian@echidna lpi103-2]$ touch -d 11am f4
[ian@echidna lpi103-2]$ touch -d "last fortnight" f5
[ian@echidna lpi103-2]$ touch -d "yesterday 6am" f6
[ian@echidna lpi103-2]$ touch -d "2 days ago 12:00" f7
[ian@echidna lpi103-2]$ touch -d "tomorrow 02:00" f8

[ian@echidna lpi103-2]$ touch -d "5 Nov" f9
[ian@echidna lpi103-2]$ ls -lrt f*
-rw-rw-r--. 1 ian ian 0 2009-07-31 18:31 f5
-rw-rw-r--. 1 ian ian 0 2009-08-12 12:00 f7
-rw-rw-r--. 1 ian ian 0 2009-08-12 15:10 f3
-rw-rw-r--. 1 ian ian 0 2009-08-13 06:00 f6
-rw-rw-r--. 1 ian ian 0 2009-08-14 11:00 f4
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:25 f1
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:27 f2
-rw-rw-r--. 1 ian ian 0 2009-08-15 02:00 f8
-rw-rw-r--. 1 ian ian 0 2009-11-05 00:00 f9

Se você não tem certeza para qual data um expressão de data deve resolver, use o comando date para descobrir Isso também aceita a opção -d e pode resolver o mesmo tipo de formatos de dados que touch.

Use a opção -r (ou--reference) junto com um nome de arquivo de referênciapara indicar que touch (ou date) deve usar o registro de data e hora de um arquivo existente. A Listagem 17 mostra alguns exemplos.

Listagem 17. Registros de data e hora de arquivos de referência
[ian@echidna lpi103-2]$ date
Fri Aug 14 18:33:48 EDT 2009
[ian@echidna lpi103-2]$ date -r f1
Fri Aug 14 18:25:50 EDT 2009
[ian@echidna lpi103-2]$ touch -r f1 f1a
[ian@echidna lpi103-2]$ ls -l f1*
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:25 f1
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:25 f1a

O sistema Linux registra os arquivos de horário da modificaçãoe o arquivo de horário do acesso. Estes também são conhecidos, respectivamente, como mtime e atime. Os dois registros de data e hora são definidos para o mesmo valor quando o arquivo é criado, e ambos são redefinidos quando o arquivo é modificado. Se, de qualquer forma, um arquivo é acessado, o horário de acesso é atualizado, mesmo que o arquivo não seja modificado. Para nosso último exemplo com touch, vejamos os horários de acessoacesso do arquivo. A opção -a (ou --time=atime, --time=access ou --time=use) especifica que o horário de acesso deve ser atualizado. A Listagem 18 usa o comando cat para acessar o arquivo f1 e exibe seu conteúdo. Usamos então ls -l e ls -lu para exibir a modificação e horários de acesso respectivamente para f1 e f1a, que criamos usando f1 como arquivo de referência. Redefinimos o horário de acesso de f1 para f1a usando touch -a e verificando que foi redefinido.

Listagem 18. Período de acesso e modificação do tempo de acesso
[ian@echidna lpi103-2]$ ls -lu f1*
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:39 f1
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:25 f1a
[ian@echidna lpi103-2]$ ls -l f1*
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:25 f1
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:25 f1a
[ian@echidna lpi103-2]$ touch -a -r f1a f1
[ian@echidna lpi103-2]$ ls -lu f1*
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:25 f1
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:25 f1a

Para informações mais completas sobre especificações de hora e data disponíveis, consulte a pagina principal ou de informações para os comandos touch e date.


Localizando arquivos

Agora que já cobrimos o tópico arquivos e diretórios com o grande martelo recursivo que bate em tudo, e o martelo globbing que bate mais seletivamente, vamos examinar o comando find, que parece mais com um bisturi. O comando find é usado para localizar arquivos em uma ou mais árvores de diretório, com base em critérios como nome, registro de data e hora ou tamanho. Mais uma vez, usaremos o diretório lpi103-2.

find

O comando find vai procurar arquivos ou diretórios usando todo o nome ou parte dele, ou através de outros critérios de busca, como tamanho, proprietário do arquivo, data de criação ou data do último acesso. A find mais básico é uma procura por nome ou parte do nome. A Listagem 19 mostra um exemplo de nosso diretório lpi103-2 onde a primeiro vamos fazer um busca em todos os arquivos que têm '1' ou 'k' no nome, para depois realizar algumas buscas de caminho que são explicadas nas notas abaixo.

Listagem 19. Localizando arquivos por nome
[ian@echidna lpi103-2]$ find . -name "*[1k]*"
./f1a
./f1
./text10
./backup
./backup/text1.bkp.1
./backup/text1.bkp.2
./text1
[ian@echidna lpi103-2]$ find . -ipath "*ACK*1"
./backup/text1.bkp.1
[ian@echidna lpi103-2]$ find . -ipath "*ACK*/*1"
[

Notas:

  1. Os padrões que podem ser utilizados são padrões curinga de shell como os que vimos anteriormente em Curingas e globbing.
  2. Use -path em vez de -name para corresponder caminhos completos em vez de apenas nomes de arquivo básicos. Neste caso, o padrão pode ultrapassar os componentes de caminho, diferente de correspondências de curinga comuns, que correspondem somente a um única parte de um caminho.
  3. Se quiser uma busca que não diferencie maiúsculas e minúsculas, como demonstrado no uso de ipath acima, preceda as opções find que fazem busca em um cadeia ou padrão com 'i'.
  4. Querendo localizar um arquivo ou diretório cujo nome começa com um ponto, como .bashrc u o atual diretório (.), você deve especificar um ponto de orientação como parte do padrão. Ou então, buscas de nomes vão ignorar esses arquivos ou diretórios.

No primeiro exemplo acima, encontramos os dois arquivos e um diretório (./backup). Use o parâmetro -type junto com tipo de uma letra para restringir a busca. Use 'f' para arquivos regulares, 'd' para diretórios e 'l' para links simbólicos. Consulte a página principal para find outros tipos possíveis. A Listagem 20 mostra o resultado de busca de diretórios (-type d) sozinhos e com nome de arquivo (*, ou tudo, neste caso).

Listagem 20. Localizando arquivos por tamanho
[ian@echidna lpi103-2]$ find . -type d
.
./backup
[ian@echidna lpi103-2]$ find . -type d -name "*"
.
./backup

Observe que a especificação -type d sem qualquer forma de especificação de nome exibe diretórios que têm um ponto de orientação em seus nomes (neste caso, apenas o diretório em uso), como faz o curinga "*".

Também podemos fazer a busca por tamanho de arquivo, ou para um tamanho específico (n) ou para arquivos que são maiores (+n) ou menores que um determinado valor (-n). Ao usar limites de tamanho superiores e inferiores, podemos localizar arquivos com tamanho dentro de uma determinada abrangência. Por padrão, a opção -size de find presume uma unidade de 'b' para blocos de 512 bytes. Entre outras opções, especifique 'c' para bytes, ou 'k' para kilobytes. Na Listagem 21, primeiro localizamos todos os arquivos com tamanho 0, e depois todos com tamanho de 24 ou 25 bytes. Observe que especificar -empty em vez de -size 0 também localiza arquivos vazios.

Listagem 21. Localizando arquivos por tamanho
[ian@echidna lpi103-2]$ find . -size 0
./f1a
./f6
./f8
./f2
./f3
./f7
./f4
./f9
./f5
[ian@echidna lpi103-2]$ find . -size -26c -size +23c -print
./text2
./text5
./backup/text1.bkp.1
./backup/text1.bkp.2
./text1

O segundo exemplo na Listagem 21 apresenta a opção -print, que é um exemplo de uma ação que pode ser tomada em relação aos resultados fornecidos pela busca. No shell bash Esta é a ação padrão se nenhuma ação for especificada. Em alguns sistemas e alguns shells, é necessária uma ação; senão, não há resultado

Outras ações incluem -ls, que imprime informações de arquivo equivalentes às do comando ls -lids e -exec, que executa um comando para cada arquivo. A ação -exec deve terminar com ponto e vírgula, que deve escapar para evitar que o shell a interprete primeiro. Também especifique {} em qualquer lugar onde você deseja o arquivo de retorno usado no comando. Lembre-se que as chaves também têm significado para o shell e devem ser escapadas (ou ficar entre aspas). A Listagem 22 mostra como as opções -ls e -exec podem ser usadas para listar informações de arquivo. Observe que a segunda forma não lista as informações de inode.

Listagem 22. Localizando e agindo nos arquivos
[ian@echidna lpi103-2]$ find . -size -26c -size +23c -ls
933893    4 -rw-rw-r--   1 ian      ian            25 Aug 11 14:27 ./text2
933900    4 -rw-rw-r--   1 ian      ian            24 Aug 11 18:47 ./text5
934193    4 -rw-rw-r--   1 ian      ian            24 Aug 12 15:36 ./backup/text1.bkp.1
934195    4 -rw-rw-r--   1 ian      ian            24 Aug 12 15:36 ./backup/text1.bkp.2
933892    4 -rw-rw-r--   1 ian      ian            24 Aug 11 14:02 ./text1
[ian@echidna lpi103-2]$ find . -size -26c -size +23c -exec ls -l '{}' \;
-rw-rw-r--. 1 ian ian 25 2009-08-11 14:27 ./text2
-rw-rw-r--. 1 ian ian 24 2009-08-11 18:47 ./text5
-rw-rw-r--. 1 ian ian 24 2009-08-12 15:36 ./backup/text1.bkp.1
-rw-rw-r--. 1 ian ian 24 2009-08-12 15:36 ./backup/text1.bkp.2
-rw-rw-r--. 1 ian ian 24 2009-08-11 14:02 ./text1

A opção -exec pode ser usada para os mais diversos objetivos que a sua imaginação puder inventar. Por exemplo:

find . -empty -exec rm '{}' \;

remove todos os arquivos vazios em uma árvore de diretório, enquanto

find . -name "*.htm" -exec mv '{}' '{}l' \;

renomeia todos os arquivos .htm para .html.

Para nossos exemplos finais de find, usamos os registros de data e hora descritos no comando touch para localizar arquivos com registros de data e hora específicos. A Listagem 23 mostra três exemplos:

  1. Quando usado com -mtime -2, o comando find localiza todos os arquivos modificados nos últimos dois dias.s. Neste caso, um dia é um período de 24 horas relativo à data e hora atual. Veja que você pode usar -atime se quiser encontrar arquivos com base em horário de acesso e não por horário de modificação.
  2. Adicionar a opção -daystart significa que queremos considerar dias como dias corridos, iniciando à meia-noite. Agora o arquivo f3 é excluído da lista.
  3. Finalmente, vamos mostrar como usar um período de tempo em minutos em vez de dias para localizar arquivos modificados entre uma hora (60 minutos) e 10 horas (600 minutos) atrás.
Listagem 23. Localizando arquivos por registro de data e hora
[ian@echidna lpi103-2]$ date
Sat Aug 15 00:27:36 EDT 2009
[ian@echidna lpi103-2]$ find . -mtime -2 -type f -exec ls -l '{}' \;
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:25 ./f1a
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:25 ./f1
-rw-rw-r--. 1 ian ian 0 2009-08-13 06:00 ./f6
-rw-rw-r--. 1 ian ian 0 2009-08-15 02:00 ./f8
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:27 ./f2
-rw-rw-r--. 1 ian ian 58 2009-08-14 17:30 ./text10
-rw-rw-r--. 1 ian ian 0 2009-08-14 11:00 ./f4
-rw-rw-r--. 1 ian ian 0 2009-11-05 00:00 ./f9
[ian@echidna lpi103-2]$ find . -daystart -mtime -2 -type f -exec ls -l '{}' \;
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:25 ./f1a
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:25 ./f1
-rw-rw-r--. 1 ian ian 0 2009-08-15 02:00 ./f8
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:27 ./f2
-rw-rw-r--. 1 ian ian 58 2009-08-14 17:30 ./text10
-rw-rw-r--. 1 ian ian 0 2009-08-14 11:00 ./f4
-rw-rw-r--. 1 ian ian 0 2009-11-05 00:00 ./f9
[ian@echidna lpi103-2]$ find . -mmin -600 -mmin +60 -type f -exec ls -l '{}' \;
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:25 ./f1a
-rw-rw-r--. 1 ian ian 4 2009-08-14 18:25 ./f1
-rw-rw-r--. 1 ian ian 0 2009-08-14 18:27 ./f2
-rw-rw-r--. 1 ian ian 58 2009-08-14 17:30 ./text10

As páginas de manual para o comando find podem ajudar a entender a extensa gama de opções que não podem ser abordadas nesta breve introdução.


Identificando arquivos

Nomes de arquivos em geral têm um sufixo como gif, jpeg ou html que dão uma dica do que o arquivo pode conter. O Linux não requer tais sufixos e geralmente não os usa para identificar um tipo de arquivo. Saber qual o tipo de arquivo que você está lidando ajuda a saber qual programa utilizar para exibir ou manipular tal arquivo. O comando file diz alguma coisa sobre o tipo de dados em um ou mias arquivos. A Listagem 24 mostra alguns exemplos do comando file.

Listagem 24. Identificando conteúdos de arquivo
[ian@echidna lpi103-2]$ file backup text1 f2 ../p-ishields.jpg /bin/echo
backup:            directory
text1:             ASCII text
f2:                empty
../p-ishields.jpg: JPEG image data, JFIF standard 1.02
/bin/echo:         ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically 
linked (uses shared libs), for GNU/Linux 2.6.18, stripped

O comando file tenta classificar cada arquivo usando três tipos de teste. Testes de sistema de arquivos usam os resultados do comando stat para determinar, por exemplo, se um arquivo está vazio, ou um diretório. Testes conhecidos como magic verificam um arquivo para o conteúdo específico que o identifique. Essas assinaturas também são conhecidas como magic numbers. Por fim, testes de linguagem verificam o conteúdo dos arquivos de texto para tentar determinar se um arquivo está em um arquivo XML, origem de linguagem C ou C++, um arquivo troff ou algum outro arquivo considerado origem para algum tipo de processador de linguagem. O primeiro tipo encontrado é relatado a menos que a opção -k ou --keep-going esteja especificada.

O comando file tem muitas opções que você conhecerá mais ao ler as páginas man. A Listagem 25 mostra como usar a opção -i (or --mime) para exibir o tipo de arquivo como cadeia MIME em vez do resultado normal possível de leitura humana.

Listagem 25. Identificando conteúdos de arquivo como MIME
[ian@echidna lpi103-2]$ file -i backup text1 f2 ../p-ishields.jpg /bin/echo
backup:            application/x-directory; charset=binary
text1:             text/plain; charset=us-ascii
f2:                application/x-empty; charset=binary
../p-ishields.jpg: image/jpeg; charset=binary
/bin/echo:         application/x-executable; charset=binary

Os arquivos magic number também são gerenciados pelo comando file. Mais uma vez, as páginas do manual fornecem mais informações.

Nota: O comando identify que faz parte do pacote ImageMagick, é uma ferramenta adicional que fornece mais detalhes ao identificar tipos de arquivo de imagem.


Comprimindo arquivos

Ao fazer backup, arquivar, ou transmitir arquivos, é comum comprimir os arquivos. Em um ambiente Linux, dois programas populares de compressão são o gzip e o bzip2. O comando gzip usa o algoritmo Lempel-Ziv, enquanto bzip2 usa o algoritmo Burrows-Wheeler de ordenação de blocos.

Usando gzip e gunzip

Em geral a compressão funciona bem em arquivos de texto. Muitos formatos de imagem já comprimem os dados, portanto a compressão não funciona tão bem nesses e em outros arquivos binários. Para ilustrar a compressão em um arquivo de texto razoavelmente grande, vamos copiar /etc/services para o diretório que está sendo usado e comprimir este arquivo usando gzip conforme mostra a Listagem 26. Usamos a opção -p de cp para preservar o registro de data e hora de /etc/services. Observe que o arquivo comprimido tem o mesmo registro de data e hora e tem um sufixo .gz.

Listagem 26. Comprimindo com gzip
[ian@echidna lpi103-2]$ cp -p /etc/services .
[ian@echidna lpi103-2]$ ls -l serv*
-rw-r--r--. 1 ian ian 630983 2009-04-10 04:42 services
[ian@echidna lpi103-2]$ gzip services
[ian@echidna lpi103-2]$ ls -l serv*
-rw-r--r--. 1 ian ian 124460 2009-04-10 04:42 services.gz

Para descomprimir um arquivo gzip use a opção -d de gzip ou, o que é mais comum, usando o comando gunzip. A listagem 27 mostra a primeira dessas opções. Veja que o arquivo descomprimido agora tem o nome e registro de data e hora originais.

Listagem 27. Descomprimindo com gzip
[ian@echidna lpi103-2]$ gzip -d services.gz
[ian@echidna lpi103-2]$ ls -l serv*
-rw-r--r--. 1 ian ian 630983 2009-04-10 04:42 services

Usando bzip2 e bunzip2

O comando bzip2 opera de maneira similar ao gzip conforme mostra a Listagem 28.

Listagem 28. Comprimindo com bzip2
[ian@echidna lpi103-2]$ ls -l serv*
-rw-r--r--. 1 ian ian 630983 2009-04-10 04:42 services
[ian@echidna lpi103-2]$ bzip2 services
[ian@echidna lpi103-2]$ ls -l serv*
-rw-r--r--. 1 ian ian 113444 2009-04-10 04:42 services.bz2
[ian@echidna lpi103-2]$ bunzip2 services.bz2
[ian@echidna lpi103-2]$ ls -l serv*
-rw-r--r--. 1 ian ian 630983 2009-04-10 04:42 services

Diferenças entre gzip e bzip2

Por projeto, muitas dessa opções bzip2 são as mesmas do gzip, mas os dois comandos não têm opções idênticas. Você deve ter percebido que nos dois exemplos o arquivo descomprimido tinha o mesmo nome e registro de data e hora que o original. No entanto, renomear ou atualizar com touch o arquivo comprimido pode alterar esse comportamento. O comando gzip tem a opção -N ou--name para obrigar a preservar nome e registro de data e hora, mas bzip2 não tem. O comando gzip também tem uma opção -l para exibir informações sobre o arquivo comprimido, incluindo o nome que será usado quando for descomprimido. A Listagem 29 mostra algumas dessas diferenças entre os dois comandos.

Listagem 29. Algumas diferenças entre gzip e bzip2
[ian@echidna ~]$ ls -l serv*
-rw-r--r--. 1 ian ian 630983 2009-04-10 04:42 services
[ian@echidna ~]$ gzip -N services
[ian@echidna ~]$ touch services.gz
[ian@echidna ~]$ mv services.gz services-x.gz
[ian@echidna ~]$ ls -l serv*
-rw-r--r--. 1 ian ian 124460 2009-09-23 14:08 services-x.gz
[ian@echidna ~]$ gzip -l services-x.gz

         compressed        uncompressed  ratio uncompressed_name
             124460              630983  80.3% services-x
[ian@echidna ~]$ gzip -lN services-x.gz
         compressed        uncompressed  ratio uncompressed_name
             124460              630983  80.3% services
[ian@echidna ~]$ gunzip -N services-x.gz
[ian@echidna ~]$ ls -l serv*
-rw-r--r--. 1 ian ian 630983 2009-04-10 04:42 services
[ian@echidna ~]$
[ian@echidna ~]$ bzip2 services
[ian@echidna ~]$ mv services.bz2 services-x.bz2

[ian@echidna ~]$ touch services-x.bz2
[ian@echidna ~]$ ls -l serv*
-rw-r--r--. 1 ian ian 113444 2009-09-23 14:10 services-x.bz2
[ian@echidna ~]$ bunzip2 services-x.bz2
[ian@echidna ~]$ ls -l serv*
-rw-rw-r--. 1 ian ian 630983 2009-09-23 14:10 services-x
[ian@echidna ~]$ rm services-x # Don't need this any more

Tanto gzip como bzip2 aceitarão informação de stdin. Ambos suportam a opção -c para direcionar informação para stdout.

Há dois outros comandos associados a bzip2

  1. O comando bzcat descomprime arquivos para stdout e é equivalente a bzip2 -dc.
  2. O comando bzip2recover tenta recuperar dados de arquivos bzip2 corrompidos.

As páginas do manual ajudam a entender mais sobre as opções de gzip e bzip2.

Outras ferramentas de compressão

Dois antigos programas, compress e uncompress, ainda são frequentemente encontrados nos sistemas Linux e UNIX.

Além disso, os comandos zip e unzip do projeto Info-ZIP foram implementados para Linux. Isso fornece funções de compressão entre plataformas que estejam disponíveis nos mais variados e inúmeros hardware e sistemas operacionais. Atenção por que nem todos os sistemas operacionais suportam os mesmos atributos de arquivo ou recursos de sistema de arquivos; Se for feito um download de um arquivo de produto comprimido (zip) para ser descomprimido (unzip) em um sistema Windows, e os arquivos resultantes transferidos para um CD ou DVD para instalação no Linux, você pode ter problemas de instalação porque, por exemplo, o sistema Windows não suporta links simbólicos que faziam parte do conjunto original de arquivo descomprimido.

Para mais informações sobre este ou outros programas de descompressão, consulte as páginas do manual.


Arquivos do archive

Os comandos tar, cpio, e dd são comumente usados para fazer backup de grupos ou arquivos, ou até mesmo partições inteiras, seja para arquivamento ou para transmissão para outro usuário ou site. O Exam 201, que faz parte da certificação LPIC-2, se concentra nas considerações de backup com bastante detalhe.

Há três abordagens gerais para backup:

  1. Um backup diferencial ou cumulativo é um backup de todas as coisas que foram mudadas desde o último backup total. A recuperação exige o último backup total mais o último backup diferencial.
  2. Um backup incremental é um backup somente daquelas mudanças desde o último backup incremental. A recuperação exige o último backup total mais todos os backups incrementais (em ordem) desde o último backup total.
  3. Um backup total é um backup completo, geralmente de um sistema de arquivo inteiro, diretório ou grupo de arquivos relacionados. Isso leva um tempo maior para ser criado, portanto geralmente é usado com uma das outras duas abordagens.

Esses comandos, junto com os outros comandos que você conheceu neste artigo, fornece as ferramentas que realizam qualquer uma dessas tarefas de backup.

Usando tar

O tar (originalmente de Tape ARchive) cria um arquivo de archive, ou tarfile ou tarball, a partir de um conjunto de arquivos de entrada ou diretórios; também recupera arquivos de tal archive. Se um diretório é dado como entrada para tar, todos os arquivos e subdiretórios estão automaticamente incluídos, o que torna tar muito conveniente para subárvores de archive da sua estrutura de diretório.

A saída pode ser para um arquivo, um dispositivo como fita ou disquete, oustdout. O local de saída é especificado com a opção -f. Outras opções comuns são -c para criar um archive, -x para extrair um archive, -v para resultado muito detalhado, que lista os arquivos que estão sendo processados, -z para usar compressão gzip, e -j para usar compressão bzip2. A maioria das opções tar tem uma forma reduzida usando um único hífen e uma forma longa usando um par de hífens. As formas reduzidas são mostradas aqui. Consulte as páginas do manual para a forma longa e opções adicionais.

A Listagem 30 mostra como criar um backup do nosso diretório lpi103-2 usando tar.

Listagem 30. Fazendo backup do nosso diretório lpi103-2 usando tar
[ian@echidna lpi103-2]$ tar -cvf ../lpitar1.tar .
./
./text3
./yab
...
./f5

Em geral os arquivos de archive são comprimidos para economizar espaço ou reduzir o tempo de transmissão. A versão GNU do comando tar permite fazer isso com uma única opção—-z para compressão usando gzip e -b para compressão bzip2. A Listagem 31mostra o uso da opção -z e a diferença de tamanho entre os dois archives.

Listagem 31. Comprimindo o archive tar com gzip
[ian@echidna lpi103-2]$ tar -zcvf ../lpitar2.tar ~/lpi103-2/
tar: Removing leading `/' from member names
/home/ian/lpi103-2/
/home/ian/lpi103-2/text3
/home/ian/lpi103-2/yab
...
/home/ian/lpi103-2/f5
[ian@echidna lpi103-2]$ ls -l ../lpitar*
-rw-rw-r--. 1 ian ian 30720 2009-09-24 15:38 ../lpitar1.tar
-rw-rw-r--. 1 ian ian   881 2009-09-24 15:39 ../lpitar2.tar

A Listagem 31 também mostra outro importante recurso de tar. Usamos um caminho de diretório absoluto, e a primeira linha de saída diz que tar está removendo a barra (/) de orientação dos nomes de membro. Isso permite que arquivos sejam recuperados para algum outro local para verificação e pode ser bem importante se você estiver tentando recuperar arquivos de sistema. Se você quer mesmo armazenar nomes absolutos, use a opção -p. Também é uma boa ideia evitar misturar nomes de caminho absolutos com nomes de caminho relativos ao criar um archive, visto que todos são relativos ao recuperar o archive.

O comando tar pode anexar arquivos adicionais a um archive usando a opção -r ou --append. Isso pode levar a muitas cópias de um arquivo no archive. Nesse caso, o último será recuperado durante a operação de restauração. Use a opção --occurrence para selecionar um arquivo específico entre vários. Se o archive está em um sistema de arquivos regular e não em fita, use a opção -u ou --update para atualizar um archive. Isso funciona como anexar a um archive, exceto que os registros de data e hora dos arquivos no archive são comparados aos do sistema de arquivos, e somente arquivos que foram modificados desde a versão de archive são anexados. Conforme dito, isso não funciona para arquivos de fita.

O comando tar também pode comparar archives com o atual sistema de arquivos e recuperar arquivos de archives. Use a opção -d, --compare, ou --diff para fazer as comparações. O resultado mostrará arquivos cujo conteúdo difere, bem como arquivos cujos registros de data e hora diferem. Normalmente, somente arquivos que diferem, se houver, estão listados. Use a opção -v discutida anteriormente para resultado detalhado. A opção -C ou --directory diz tar para iniciar uma operação começando do diretório especificado e não do diretório atual.

A Listagem 32 mostra alguns exemplos. Usamos touch para modificar o registro de data e hora do arquivo f1, e depois mostramos comparações de tar antes de recuperar f1 de um dos nossos archives. Usamos uma série de formas de opção para ilustração.

Listagem 32. Comparando e restaurando usando tar
[ian@echidna lpi103-2]$ touch f1
[ian@echidna lpi103-2]$ tar --diff --file ../lpitar1.tar .
./f1: Mod time differs
[ian@echidna lpi103-2]$ tar -df ../lpitar2.tar -C /
home/ian/lpi103-2/f1: Mod time differs
[ian@echidna lpi103-2]$ tar -xvf ../lpitar1.tar ./f1 # See below
./f1
[ian@echidna lpi103-2]$ tar --compare -f ../lpitar2.tar --directory

Os arquivos ou diretórios especificados para restauração devem corresponder ao nome no archive. Tentar restaurar apenas f1 em vez de ./f1 neste caso não funciona. É possível usar globbing, mas é necessário ter cuidado e evitar restaurar mais ou menos que o desejado. Use a opção --list ou -t para listar conteúdo de archive caso não tenha certeza do que está no arquivo. A Listagem 33 mostra um exemplo de especificação curinga que poderia restaurar mais arquivos do que apenas ./f1.

Listagem 33. Listando conteúdo de archive com tar
[ian@echidna lpi103-2]$ tar -tf ../lpitar1.tar "*f1*"
./f1a
./f1

Use o comando find para selecionar os arquivos para archive e redirecione o resultado para tar. Abordaremos essa técnica como parte da discussão de cpio, mas o mesmo método funciona para tar.

Assim como com os outros comandos que estudamos, há várias opções que não foram abordadas nesta rápida introdução. Consulte as páginas do manual para mais detalhes.

Usando cpio

O comando cpio opera em modo copy-out para criar um archive, em modo copy-in para restaurar um archive, ou modo copy-pass para copiar um conjunto de arquivos de um local para outro. Use a opção -o ou --create para o modo copy-out, -i ou a opção --extract para o modo copy-in, e a opção -p ou --pass-through para o modo copy-pass. A entrada é uma lista de arquivos fornecidos em stdin. A saída é ou para stdout ou para um dispositivo ou arquivo especificado com a opção -f ou --file.

A Listagem 34 mostra como gerar uma lista de arquivos usando o comando find e redirecionando a lista para cpio. Veja que o uso da opção -print0 em find para gerar cadeias terminadas em nulo para nomes de arquivos, e a opção correspondente --null em cpio para ler este formato. Isso vai manipular corretamente os nomes de arquivo que tem caracteres em branco ou caracteres newline. A opção -depth diz find para listar entradas de diretório antes do nome do diretório. Neste exemplo, simplesmente listamos dois archives do nosso diretório lpi103-2, um com nomes relativos e um com nomes absolutos. Não usamos os muitos recursos de find para restringir os arquivos selecionados, como localizar apenas os arquivos modificados nesta semana.

Listagem 34. Fazendo backup de um diretório usando cpio
[ian@echidna lpi103-2]$ find . -depth -print0 | cpio --null -o > ../lpicpio.1
3 blocks
[ian@echidna lpi103-2]$ find ~/lpi103-2/ -depth -print0 | cpio --null -o > ../lpicpio.2
4 blocks

Se quiser ver os arquivos listados conforme estão em archive, adicione a opção -v ao cpio.

O comando cpio no modo copy-in (opção -i ou --extract) pode listar o conteúdo de um archive ou restaurar arquivos selecionados. Listar os arquivos, especificando a opção --absolute-filenames reduz o número de mensagens externas que algumas versões mais antigas de cpio por sua vez emite conforme retira qualquer orientação/ caracteres de cada caminho que tenha uma. Essa opção é calmamente ignorada em muitas implementações atuais. O resultado de seletivamente listar nossos archives anteriores está na Listagem 35.

Listagem 35. Listando e restaurando arquivos selecionados usando cpio
[ian@echidna lpi103-2]$ cpio  -i --list  "*backup*" < ../lpicpio.1
backup
backup/text1.bkp.1
backup/text1.bkp.2
3 blocks
[ian@echidna lpi103-2]$ cpio  -i --list absolute-filenames "*text1*" < ../lpicpio.2
/home/ian/lpi103-2/text10
/home/ian/lpi103-2/backup/text1.bkp.1
/home/ian/lpi103-2/backup/text1.bkp.2
/home/ian/lpi103-2/text1
4 blocks

A Listagem 36 mostra como restaurar todos os arquivos com "text1" no caminho em um subdiretório temporário. Alguns estão em subdiretórios. Diferente de tar, é necessário especificar a opção -d ou --make-directories explicitamente se a sua árvore de diretório não existe. Além disso, cpio não substitui nenhum arquivo mais recente no sistema de arquivos com cópias de archive a menos que a opção -u ou --unconditional seja especificada.

Listagem 36. Recuperando arquivos selecionados usando cpio
[ian@echidna lpi103-2]$ mkdir temp
[ian@echidna lpi103-2]$ cd temp
[ian@echidna temp]$ cpio  -idv "*f1*" "*.bkp.1" < ../../lpicpio.1
f1a
f1
backup/text1.bkp.1
3 blocks
[ian@echidna temp]$ cpio  -idv "*.bkp.1" < ../../lpicpio.1

cpio: backup/text1.bkp.1 not created: newer or same age version exists
backup/text1.bkp.1
3 blocks
[ian@echidna temp]$ cpio  -id --no-absolute-filenames "*text1*" < ../../lpicpio.2
cpio: Removing leading `/' from member names
4 blocks
./home/ian/lpi103-2/backup/text1.bkp.1
./home/ian/lpi103-2/backup/text1.bkp.2
./home/ian/lpi103-2/text1
./backup/text1.bkp.1
[ian@echidna temp]$ cd ..
[ian@echidna lpi103-2]$ rm -rf temp # You may remove these after you have finished

Para detalhes e outras opções, consulte a página de manual.

O comando dd

Em sua forma mais simples, o comando dd copia um arquivo de entrada para um arquivo de saída. Você já viu o comando cp, portanto deve estar se perguntando por que outro comando para copiar arquivos. O comando dd pode fazer algumas coisas que o cp regular não pode. Em especial, pode realizar conversões no arquivo, tais como converter letras minúsculas em maiúsculas ou ASCII para EBCDIC. Também pode reblocar um arquivo, o que pode ser útil ao transferir este arquivo para uma fita. Pode ignorar ou incluir somente blocos selecionados de um arquivo. E, finalmente, pode ler e gravar em dispositivos brutos, tais como /dev/sda, que permite criar ou restaurar um arquivo que é uma imagem da partição inteira. Gravar para dispositivos em geral exige autoridade de root.

Começaremos com um simples exemplo de conversão de arquivo para letra maiúscula usando a opção conv conforme a Listagem 37. Usamos a opção if para especificar o arquivo de entrada em vez de usar o padrão de stdin. Uma opção similar de of está disponível para substituir a saída padrão para stdout. Para fins de demonstração, especificamos diferentes tamanhos de bloco de entrada e saída usando as opções ibs e obs. Para grandes arquivos pode ser mais prático usar tamanhos maiores de bloco para agilizar operações aos transferir de disco para disco. Por outro lado, tamanhos de blocos são mais usados com fitas magnéticas. Observe as três linhas de status no final da listagem mostrando quantos blocos completos e parciais foram lidos e gravados, e a quantidade total de dados transferidos.

Listagem 37. Convertendo texto para maiúsculas usando dd
[ian@echidna lpi103-2]$ cat text6
1 apple
2 pear
3 banana
9       plum
3       banana
10      apple
1 apple
2 pear
3 banana
9       plum
3       banana
10      apple
[ian@echidna lpi103-2]$ dd if=text6 conv=ucase ibs=20 obs=30
1 APPLE
2 PEAR
3 BANANA
9       PLUM
3       BANANA
10      APPLE
1 APPLE
2 PEAR
3 BANANA
9       PLUM
3       BANANA
10      APPLE
4+1 records in
3+1 records out
98 bytes (98 B) copied, 0.00210768 s, 46.5 kB/s

Cada arquivo pode ser um dispositivo bruto. Em geral é o caso para a fita magnética, mas uma partição de disco inteira, como /dev/hda1 or /dev/sda2, pode fazer backup para um arquivo ou fita. Em teoria, o sistema de arquivos no dispositivo deveria ser desmontado, ou pelo menos montado somente para leitura, para garantir que os dados não mudassem durante o backup. A Listagem 39 mostra um exemplo onde o arquivo de entrada é um dispositivo bruto, dev/sda3, e o arquivo de saída é um arquivo, backup-1, no diretório doméstico de usuário de root. Para fazer o dump do arquivo para fita ou disquete, especifique algo como of=/dev/fd0 ou of=/dev/st0.

Listagem 38. Fazendo o backup de uma partição usando dd
[root@echidna ~]# dd if=/dev/sda2 of=backup-1
1558305+0 records in
1558305+0 records out
797852160 bytes (798 MB) copied, 24.471 s, 32.6 MB/s

Observe que 797.852.160 bytes de dados foram copiados e o arquivo de saída é realmente grande, muito embora apenas cerca de 3% dessa partição em particular seja realmente usada. A menos que se copie uma fita com compressão de hardware, provavelmente o melhor é comprimir os dados. A Listagem 39 mostra uma maneira de fazer isso, junto com a saída de comandos ls e df, que mostram os tamanhos de arquivo e a percentagem de uso do sistema de arquivo em /dev/sda3.

Listagem 39. Fazendo backup com compressão usando dd
[root@echidna ~]# dd if=/dev/sda2 |gzip >backup-2
1558305+0 records in
1558305+0 records out
797852160 bytes (798 MB) copied, 23.4617 s, 34.0 MB/s
[root@echidna ~]# ls -l backup-[12]
-rw-r--r--. 1 root root 797852160 2009-09-25 17:13 backup-1
-rw-r--r--. 1 root root    995223 2009-09-25 17:14 backup-2
[root@echidna ~]# df -h /dev/sda2
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2             755M   18M  700M   3% /grubfile

A compressão gzip reduziu o tamanho do arquivo em cerca de 20% do tamanho não comprimido. No entanto, blocos não usados podem conter dados arbitrários, por isso até mesmo backup comprimido pode ser bem maior que o total de dados na partição.

Se você divivir o total de bytes copiados pelo número de registros processados, verá que dd está gravando blocos de dados de 512 byte. Ao copiar para um dispositivo bruto de saída, como a fita, isso pode resultar em um operação bastante ineficaz. Conforme já dito, especifique a opção obs para mudar o tamanho de saída ou a opção ibs para especificar o tamanho de bloco de entrada. Também é possível especificar apenas bs para definir tamanhos de bloco de entrada e de saída para um valor comum. Ao usar a fita, lembre-se de usar o mesmo tamanho de bloco para leitura de fita que foi usado para gravar a fita.

Se forem necessárias diversas fitas ou outra armazenagem removível para armazenar seu backup, será necessário quebrar em pequenas partes usando um utilitário como split. Se precisar ignorar blocos como etiquetas de disco ou fita, isso pode ser feito com dd. Consulte as páginas de manual para exemplos.

O comando dd não reconhece o sistema de arquivos, portanto é necessário fazer o dump de uma partição para descobrir o que tem nela. A Listagem 40 mostra como restaurar a partição onde houve o dump na Listagem 39 para uma partição, /dev/sdc7, especialmente criada em uma unidade USB removível apenas para essa finalidade.

Listagem 40. Restaurando uma partição usando dd
[root@echidna ~]# gunzip backup-2 -c | dd  of=/dev/sdc7
1558305+0 records in
1558305+0 records out
797852160 bytes (798 MB) copied, 30.624 s, 26.1 MB/s

Você pode querer saber que alguns aplicativos de gravação de CD e DVD usam o comando dd de forma dissimulada para fazer a gravação real do dispositivo. Se o utilitário em uso fornece um log de comandos realmente usados, pode ser instrutivo examinar o log agora que você conhece um pouco mais de dd. Na verdade, se você gravar uma imagem ISO para um disco de CD ou DVD, uma maneira de verificar que não houve erro é usar dd para ler o disco e redirecionar o resultado através do utilitário cmp. A Listagem 41 mostra a técnica geral usando o arquivo de backup que criamos neste artigo e não uma imagem ISO. Observe que calculamos o número de blocos para ler usando o tamanho de arquivo da imagem.

Listagem 41. Comparando uma imagem com um arquivo de sistema.
[root@echidna ~]# ls -l backup-1
-rw-r--r--. 1 root root 797852160 2009-09-25 17:13 backup-1
[root@echidna ~]# echo $(( 797852160 / 512 )) # calculate number of 512 byte blocks
1558305
[root@echidna ~]# dd if=/dev/sdc7 bs=512 count=1558305 | cmp - backup-1
1558305+0 records in
1558305+0 records out
797852160 bytes (798 MB) copied, 26.7942 s, 29.8 MB/s

Recursos

Aprender

Obter produtos e tecnologias

  • Com o IBM trial software, disponível para download diretamente do developerWorks, construa 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=445854
ArticleTitle=Aprenda Linux, 101: Gerenciamento de arquivo e diretório
publish-date=11102009