Qual a diferença entre more, cat, less, hexdump, xxd, tac?
Ao inspecionar um arquivo texto utilizando o filtro more
na linha de comando Linux, notei que o conteúdo exibido era de comprimento bem inferior ao tamanho listado para o arquivo.
more
more sample.txt
3FBFF4D54AEA8CD5CB530D32D7F57A97
Daí pensei usar o cat
para ver se o conteúdo apareceria e, novamente, o conteúdo exibido não era coerente com o tamanho do arquivo.
cat
cat sample.txt
3FBFF4D54AEA8CD5CB530D32D7F57A97
Recorrí a uma ferramenta mais avançada, o hexdump
para exibir o real conteúdo do arquivo e caracteres imprimíveis. Quem sabe o arquivo continha alguma sequência de zeros, por exemplo, por erro de tamanho registrado no inode do arquivo. Com isso, pude constatar que o arquivo contém várias palavras que não foram apresentadas na tela com os dois primeiros utilitários. Estão todas separadas com retorno de carro (caractere 0x0D).
hexdump
hexdump -Cv sample.txt
00000000 64 69 73 74 61 6e 63 65 0d 7a 65 72 6f 0d 63 72 |distance.zero.cr|
00000010 79 73 74 61 6c 0d 6e 6f 69 73 65 0d 70 6f 74 61 |ystal.noise.pota|
00000020 74 6f 0d 68 65 6c 6d 65 74 0d 63 6f 69 6c 0d 64 |to.helmet.coil.d|
00000030 67 69 61 6e 74 0d 61 64 64 0d 68 69 70 0d 73 74 |giant.add.hip.st|
00000040 69 6e 67 0d 66 61 6e 63 79 0d 30 35 30 39 3b 32 |ing.fancy.0509;2|
00000050 30 34 35 3b 30 34 32 36 3b 31 31 39 38 3b 31 33 |045;0426;1198;13|
00000060 35 30 3b 30 38 35 35 0d 30 33 36 32 3b 30 37 38 |50;0855.0362;078|
00000070 31 3b 30 30 32 35 3b 30 38 36 33 3b 31 37 31 31 |1;0025;0863;1711|
00000080 3b 30 36 36 33 0d 33 46 42 46 46 34 44 35 34 41 |;0663.3FBFF4D54A|
00000090 45 41 38 43 44 35 43 42 35 33 30 44 33 32 44 37 |EA8CD5CB530D32D7|
000000a0 46 35 37 41 39 37 |F57A97|
000000a6
Notando essa surpresa "pregada" pelos utilitários cat
e more
, lembrei-me do less
, afinal, less do more than more. Surpreendentemente os caracteres não imprimíveis bagunçam um pouco a exibição, mas apresentam mais detalhes que more
e cat
revelando parte do conteúdo oculto.
less
less sample.txt
<várias linhas em branco>
distance^Mzero^Mcrystal^Mnoise^Mpotato^Mhelmet^Mcoil^Mdgiant^Madd^Mhip^Msting^Mfancy^M0509;2045;0426;1198;1350;0855^M0362;0781;0025;0863;1711;0663^M3FBFF4D54AEA8CD5CB530D32D7F57A97
sample.txt (END)
Finalmente, vale lembrar que cada classe de sistema operacional entre Linux, Mac, Windows possuem sua própria definição para caracteres terminadores de linha:
- Linux (LF ou 0x0A)
- Mac (CR ou 0x0D)
- Windows (CRLF ou 0x0D0A)
Existem aplicações que realizam a compatiblização desses terminadores de linha: - dos2unix
- mac2unix
- unix2dos
- unix2mac
Prova de conceito
- Criar um arquivo de amostra
echo -ne "distance zero crystal noise potato helmet coil dgiant add hip sting fancy 0509;2045;0426;1198;1350;0855 0362;0781;0025;0863;1711;0663 3FBFF4D54AEA8CD5CB530D32D7F57A97" | sed 's/ /\r/g' > sample.txt
- Listar o tamanho
l
901 4 -rw-rw-r-- 1 1000 1000 1000 ? 166 2024-12-01 03:12:58.290966198 -0300 sample.txt
ou
wc sample.txt
0 15 166 sample.txt
ou
stat sample.txt
File: sample.txt
Size: 166 Blocks: 8 IO Block: 4096 regular file
Device: 1ah/26d Inode: 901 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ usr) Gid: ( 1000/ usr)
Access: 2024-12-01 03:35:15.825149271 -0300
Modify: 2024-12-01 03:12:58.290966198 -0300
Change: 2024-12-01 03:12:58.290966198 -0300
Birth: -
ou várias outras possíveis soluções...
Alias para ls
com parâmetros extras
alias l='alias l='ls -m -tCl --almost-all --author --classify --context --color=always --escape --full-time --group-directories-first --inode --kibibytes --numeric-uid-gid --reverse --size''
- Exibir o conteúdo dos arquivos com os utilitários
cat
cat sample.txt
3FBFF4D54AEA8CD5CB530D32D7F57A97
more
more sample.txt
3FBFF4D54AEA8CD5CB530D32D7F57A97
hexdump
hexdump -Cv sample.txt
00000000 64 69 73 74 61 6e 63 65 0d 7a 65 72 6f 0d 63 72 |distance.zero.cr|
00000010 79 73 74 61 6c 0d 6e 6f 69 73 65 0d 70 6f 74 61 |ystal.noise.pota|
00000020 74 6f 0d 68 65 6c 6d 65 74 0d 63 6f 69 6c 0d 64 |to.helmet.coil.d|
00000030 67 69 61 6e 74 0d 61 64 64 0d 68 69 70 0d 73 74 |giant.add.hip.st|
00000040 69 6e 67 0d 66 61 6e 63 79 0d 30 35 30 39 3b 32 |ing.fancy.0509;2|
00000050 30 34 35 3b 30 34 32 36 3b 31 31 39 38 3b 31 33 |045;0426;1198;13|
00000060 35 30 3b 30 38 35 35 0d 30 33 36 32 3b 30 37 38 |50;0855.0362;078|
00000070 31 3b 30 30 32 35 3b 30 38 36 33 3b 31 37 31 31 |1;0025;0863;1711|
00000080 3b 30 36 36 33 0d 33 46 42 46 46 34 44 35 34 41 |;0663.3FBFF4D54A|
00000090 45 41 38 43 44 35 43 42 35 33 30 44 33 32 44 37 |EA8CD5CB530D32D7|
000000a0 46 35 37 41 39 37 |F57A97|
000000a6
xxd
xxd sample.txt
00000000: 6469 7374 616e 6365 0d7a 6572 6f0d 6372 distance.zero.cr
00000010: 7973 7461 6c0d 6e6f 6973 650d 706f 7461 ystal.noise.pota
00000020: 746f 0d68 656c 6d65 740d 636f 696c 0d64 to.helmet.coil.d
00000030: 6769 616e 740d 6164 640d 6869 700d 7374 giant.add.hip.st
00000040: 696e 670d 6661 6e63 790d 3035 3039 3b32 ing.fancy.0509;2
00000050: 3034 353b 3034 3236 3b31 3139 383b 3133 045;0426;1198;13
00000060: 3530 3b30 3835 350d 3033 3632 3b30 3738 50;0855.0362;078
00000070: 313b 3030 3235 3b30 3836 333b 3137 3131 1;0025;0863;1711
00000080: 3b30 3636 330d 3346 4246 4634 4435 3441 ;0663.3FBFF4D54A
00000090: 4541 3843 4435 4342 3533 3044 3332 4437 EA8CD5CB530D32D7
000000a0: 4635 3741 3937 F57A97
O motivo de compatilhar essa surpresa foi para evidenciar que a inspeção de arquivos na linha de comando simplesmente com os utilitários citados pode causar uma falha nesta inspeção visual.
- Um bom uso desse artifício é esconder as linhas de comentários ou detalhes que não queira exibir considerando que será listado por
more
oucat
ou mesmotac
. Aparentemente, tais utilitários constroem a tela quando exibem arquivos. - Um mau uso (se fosse possível) é explorar o poder dos demais caracteres não imprimíveis para que execute comando ao serem simplesmente listados (algo utópico).
Deixo o relato desta surpresa, evidenciando alguns utilitários bastante úteis para a linha de comando do terminal:
hexdump
: exibição detalhada de um arquivo. Com as chaves adequadas, permite exibições personalizadas em relação à canônica.xxd
: não somente faz a exibição, mas com as chaves adequadas converte um conteúdo para sua representação em bytes ou bits. Possibilita a reversão de uma sequência de bytes para o correspondente binário (não se aplica a bits).