Diferença entre xargs / bin / ls e exec ls?

1

Oi, essa pode ser uma pergunta muito novata, mas por que o xargs / bin / ls não funciona neste caso? Eu pensei que deveria ser mais rápido? Além disso, quais são esses diretórios / fd / 3?

sh-3.2# find / -name 'GOALS*' -exec ls -l {} \;
find: /dev/fd/3: Not a directory
find: /dev/fd/4: Not a directory
.... This returns me the expected result....

No entanto, isso retorna toda a lista de arquivos no diretório

sh-3.2# find / -name GOALS* -type f | xargs /bin/ls -l

Estou em um MacOS.

    
por kunj2aaan 17.11.2012 / 15:05

3 respostas

1

  1. você precisa citar o * no segundo comando find ,

  2. os /dev/fd/* são dispositivos que correspondem a stdin , stdout , stderr etc. esses dispositivos são simliados e são diferentes para cada processo,

  3. o -type f diz que o resultado tem que ser um arquivo regular, portanto, os /dev/fd/* não estão no resultado, pois são dispositivos de bloco,

  4. o xargs ls -l faz o mesmo que o seu ls -l {} ... Eu até duvido o melhor desempenho neste caso, mas xargs é mais inteligente e há razões para usá-lo, por exemplo. manipulação correta de arquivos com espaços em branco dentro dele,

Se você estiver depurando a segunda versão do seu find , primeiro veja a saída sem a | xargs ls -l part

    
por 17.11.2012 / 19:46
1

Seu primeiro comando executa um novo comando ls para cada nome de arquivo que corresponda ao nome que você forneceu. Isso inclui diretórios, links simbólicos, dispositivos e qualquer outra coisa que possa ser encontrada. O comando ls é executado quando os arquivos são encontrados, então você verá listagens quando os arquivos forem encontrados.

O segundo comando corresponde apenas ao arquivo com o nome especificado. Como você não citou GOALS* , se você executar a partir de um diretório com uma entrada correspondente, ele substituirá a entrada GOALS* no comando. xargs calls ls será uma longa lista de nomes de arquivos. Você não verá resultados até que o find seja concluído ou uma lista de correspondências suficientemente longa seja encontrada. Por causa das regras de análise, o nome do arquivo que contém espaço em branco causará problemas.

Esses três comandos devem ser equivalentes para arquivos sem espaço em branco no nome. A terceira opção não funciona em todos os sistemas operacionais, mas manipula o espaço em branco no nome.

find / -name 'GOALS*' -type f -exec ls -l {} \;
find / -name 'GOALS*' -type f | xargs /bin/ls -l
find / -name 'GOALS*' -type f -print0 | xargs -0 /bin/ls -l
    
por 17.11.2012 / 19:55
0

O shell (bash) incorporado em exec substitui o shell atual pelo argumento fornecido. Tente exec sleep 1, por exemplo. O executável xargs faz parte do pacote GNU findutils. Ele executará o comando dado a ele como o primeiro argumento com argumento lido da entrada padrão.

Por exemplo:

$ echo -e "calves drink milk\npeople eat cows" | xargs -L1 cowsay
 ___________________
< calves drink milk >
 -------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
 _________________
< people eat cows >
 -----------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

O exemplo que você forneceu "não funciona" porque a lista de argumentos que consiste em todos os arquivos no seu computador e os arquivos especiais em / sys e / proc crescem demais. Você não pode pedir a um comando para trabalhar em uma lista arbitrariamente grande de argumentos porque existe um limite (getconf ARG_MAX - bytes eu acho).

Às vezes, você quer fazer algo com uma grande lista de argumentos, e uma solução é processar partes da lista e não toda a lista de uma só vez.

Por exemplo:

$ cat tmp/moo.sh
#!/bin/sh
echo processing $# arguments

$ seq 0 10000 | xargs -L 1001 sh tmp/moo.sh  | cat -n
     1  processing 1001 arguments
     2  processing 1001 arguments
     3  processing 1001 arguments
     4  processing 1001 arguments
     5  processing 1001 arguments
     6  processing 1001 arguments
     7  processing 1001 arguments
     8  processing 1001 arguments
     9  processing 1001 arguments
    10  processing 992 arguments

A última parte da sua pergunta sobre as pastas "fd" é sobre os descritores f ile d . Quando você executar find, ele irá procurar em / proc e ver os descritores de arquivos (entrada padrão, saída padrão, arquivos regulares para leitura e gravação) dos processos em execução. No momento em que encontrar saídas e xargs assumir, alguns desses processos podem não existir mais. Assim os erros. Arquivos em / dev / fd são, na verdade, apenas links simbólicos:

$ ll /dev/fd/
total 0
lrwx------ 1 jaroslav jaroslav 64 Nov 18 01:57 0 -> /dev/pts/7
lrwx------ 1 jaroslav jaroslav 64 Nov 18 01:57 1 -> /dev/pts/7
lrwx------ 1 jaroslav jaroslav 64 Nov 18 01:57 2 -> /dev/pts/7
lr-x------ 1 jaroslav jaroslav 64 Nov 18 01:57 3 -> /proc/21677/fd
geee: ~
$ file /dev/pts/7
/dev/pts/7: character special
geee: ~
$ sudo echo "MOOOOOOO" >>  /dev/pts/7
Password:
MOOOOOOO

O que eu fiz lá é que eu escrevi para a saída padrão do meu terminal. Eu não tenho idéia do que é o processo 21677, mas pelo tempo find / finishes, tenho certeza que ele será destruído mesmo se estivesse presente no momento em que encontrar scanned / proc.

    
por 18.11.2012 / 01:59