O arquivo de saída é criado pelo shell antes de ls
começar. Você pode contornar isso usando tee
:
ls | tee list
Para derrotar completamente qualquer condição de corrida, sempre há
ls | grep -vx 'list' > list
Ou se você gostar, tee
exibirá os resultados também:
ls | grep -vx 'list' | tee list
No entanto, como apontado nos comentários, coisas como essa geralmente quebram quando os nomes de arquivos contêm caracteres estranhos. Os nomes de arquivos Unix geralmente podem conter qualquer caractere, exceto NUL
e /
, portanto, analisar a saída de ls
é extremamente difícil:
- A atribuição a uma variável de shell pode falhar se um nome de arquivo terminar em um ou mais
\n
.
- A filtragem com
grep
falha quando o termo de pesquisa está entre \n
.
- Você pode separar nomes de arquivos com
NUL
em vez de \n
usando find
, mas pode ser difícil convertê-los em algo parecido com a saída classificada tradicionalmente separada por nova linha de ls
.
- A remoção do nome do arquivo de saída da lista pode estar incorreta se já existir.
Assim, a única maneira realmente eficaz de fazer isso é criar o arquivo de saída em outro lugar e movê-lo para o lugar. Se você nunca usará ls -a
, isso funciona:
ls > .list && mv .list list
Se você estiver usando ls -a
, .list
poderá aparecer em sua saída, mas não existirá mais no diretório. Então você usaria um diretório diferente, como /tmp
para armazenar o resultado intermediário. Claro, se você sempre usa /tmp
, você tem problemas, então você pode escrever um script:
#!/bin/sh
OUTDIR='/tmp'
if [ "${PWD}" = '/tmp' ]; then
OUTDIR="${HOME}"
fi
ls > "${OUTDIR}/list" && mv "${OUTDIR}/list" list
Isso parece muito complicado para a tarefa, no entanto.
Mas a causa inteira do problema é que o shell está criando o arquivo de saída antes do início do comando. Podemos levar isso em consideração e apenas fazer com que a shell liste os arquivos para nós. Então nós nem sequer precisamos de ls
!
printf '%s\n' * > list
Isso funcionará até que você tenha muitos arquivos no diretório para caber em uma lista de argumentos.