
Estou tentando encontrar uma maneira eficiente de fazer onível 5 do desafio do bandido OverTheWire.
De qualquer forma, tenho vários arquivos e só existe um que atende aos seguintes critérios:
- Legível por humanos
- 1033 bytes de tamanho
- Não executável
No momento, estou usando ofind
comando. Consigo encontrar os arquivos que correspondem aos dois últimos critérios:
find . -size 1033c ! -executable
No entanto, não sei como excluir arquivos não legíveis por humanos. As soluções que encontrei para esse desafio usam o -readable
parâmetro test, mas não acho que funcione. -readable
analisa apenas as permissões dos arquivos, e não seu conteúdo, enquanto a descrição do desafio pede um arquivo ASCII ou algo parecido.
Responder1
Sim, você pode usar find
para procurar arquivos não executáveis do tamanho certo e depois usar file
para verificar ASCII. Algo como:
find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII
A questão, porém, não é tão simples quanto parece. 'Legível por humanos' é um termo terrivelmente vago. Presumivelmente, você quer dizer texto. OK, mas que tipo de texto? Caractere latino apenas ASCII? Unicode completo? Por exemplo, considere estes três arquivos:
$ cat file1
abcde
$ cat file2
αβγδε
$ cat file3
abcde
αβγδε
$ cat file4
#!/bin/sh
echo foo
Tudo isso é texto e legível por humanos. Agora, vamos ver o que file
faz deles:
$ file *
file1: ASCII text
file2: UTF-8 Unicode text
file3: UTF-8 Unicode text
file4: POSIX shell script, ASCII text executable
Portanto, o find
comando acima irá apenas encontrar file1
(para este exemplo, vamos imaginar que esses arquivos tinham 1033 caracteres). Você pode expandir para find
procurar a string text
:
find . -type f -size 1033c ! -executable -exec file {} + | grep -w text
Com o -w
, grep
imprimirá apenas as linhas text
encontradas como uma palavra independente. Quedeveesteja bem próximo do que você deseja, mas não posso garantir que não exista outro tipo de arquivo cuja descrição também possa incluir a string text
.
Responder2
Embora -exec
seja usado principalmente para fazer algo com os arquivos encontrados, também pode funcionar como um teste. Portanto, podemos adicioná-lo aos seus outros critérios:
find . \
-size 1033c \
-not -executable \
-exec sh -c 'file {} | grep "text$"' \;
Lembre-se, grep
retorna diferente de zero quando o padrão não foi encontrado e sh -c "COMMAND"
retornará o resultado da avaliação (desde que seja válido). Portanto, isso imprimirá apenas arquivos onde file <filename>
cospe algo que termina com text
, por exemplo, "Texto Unicode UTF-8" ou "Texto ASCII", mas não "Texto ASCII estendido não ISO, com sequências de escape".
Em uma única linha, acaba até ficando mais curto do que passar por cima xargs
:
find . -size 1033c -not -executable -exec sh -c 'file {} | grep "text$"' \;
Lembre-se de que você pode substituir sh -c 'file {} | grep "text$"'
por qualquer comando personalizado. Se você quiser verificar algo muito complexo, pode ser uma ideia melhor fornecer um script de shell e usá-lo:
find . -size 1033c -not -executable -exec is_human_readable.sh {} \;
que, a longo prazo, é mais fácil de manter do que o histórico do seu shell:
#!/bin/sh
file "$@" | grep "text$" > /dev/null
Responder3
Existe apenas 1 arquivo com 1033
bytes de tamanho.
bandit5@bandit:~$ find -size 1033c
./inhere/maybehere07/.file2
bandit5@bandit:~$
Por que 1033c
e não 1033
? Verifique a man
página
-size n[cwbkMG] File uses n units of space, rounding up. The following suffixes can be used: `b' for 512-byte blocks (this is the default if no suffix is used) `c' for bytes `w' for two-byte words `k' for Kilobytes (units of 1024 bytes) `M' for Megabytes (units of 1048576 bytes) `G' for Gigabytes (units of 1073741824 bytes)
Verifique com ls -l
um file
comando e você obterá todas as respostas.
bandit5@bandit:~$ ls -l ./inhere/maybehere07/.file2
-rw-r----- 1 root bandit5 1033 May 7 20:15 ./inhere/maybehere07/.file2
bandit5@bandit:~$
bandit5@bandit:~$ file ./inhere/maybehere07/.file2
./inhere/maybehere07/.file2: ASCII text, with very long lines
bandit5@bandit:~$
- legível por humanos (
ASCII text
) - 1033 bytes de tamanho (também na
ls -l
saída) - não executável (
-rw-r-----
)
Responder4
find . -size 1033c ! -executable -exec file {} +