Que tipos de comandos podem ser executados por xargs?

2

Do manual do findutils:

xargs [option...] [command [initial-arguments]]

Estou correto que xargs corre command em várias execuções, cada uma com uma sequência diferente de argumentos?

Se sim, significa que tal comando deve satisfazer esse aplicar uma sequência de argumentos ao comando é efetivamente igual a

  • dividindo a sequência de argumentos em subseqüências e

  • executando o comando com cada subsequência de argumentos em uma execução diferente?

Por exemplo, é correto que se mycommand puder ser executado por xargs , então

mycommand arg1 arg2 arg3

deve ser efetivamente o mesmo que

mycommand arg1
mycommand arg2 arg3

A condição acima é uma condição necessária e suficiente para que um comando seja executado por xargs ?

Existe algum comando que não satisfaz a condição acima? (Não consigo encontrar nenhum.) Se houver, ele pode ser executado por xargs ?

Os argumentos passados por xargs to command podem ser qualquer tipo de argumento: opções, argumentos de opção ou argumentos de não-opção? Acho que essa pergunta é útil para responder às perguntas acima.

E se -i de xargs estiver envolvido?

Obrigado.

    
por Tim 07.06.2018 / 19:47

2 respostas

2

Am I correct that xargs runs command in several run, each of which with different sequence of arguments?

Sim (a menos que a entrada para xargs seja repetida, é claro)

mycommand arg1 arg2 arg3

must be effectively the same as

mycommand arg1
mycommand arg2 arg3

Praticamente, já que, em geral, não podemos saber onde xargs irá dividir a lista. GNU xargs tem --show-limits que pode ser usado para determinar se todas as entradas se encaixam em uma execução do comando.

É claro que se os argumentos devem ser passados para o comando em conjuntos de N , podemos usar -n N para ter algum controle sobre ele (ou -n M com M alguns múltiplos de N ).

Is there any command which doesn't satisfy the above condition? (I can't find any.) If there is, can it be run by xargs?

Kusalananda mencionou mv , que tem a questão de que o último argumento é tratado de forma diferente dos outros. Com efeito, os argumentos adicionados por xargs precisariam ir para o meio e não há uma maneira padrão de fazer isso. (O FreeBSD xargs tem -J {} que faz isso e o GNU mv tem a opção -t dir para passar o diretório de destino no início da lista de argumentos. cp é similar.)

Então, algo como tar -czf foo.tar.gz não funcionaria, pois -c (create) sobrescreve o arquivo em cada execução. Isso poderia ser evitado usando -r (append) em vez de -c , mas pelo menos o tar do GNU não suporta anexar a um archive compactado.

Felizmente, a maioria dos utilitários trabalha arquivo por arquivo e foi projetada para aceitar uma lista de arquivos no final.

Can the arguments passed by xargs to command be any kind of arguments: options, option arguments, or nonoption arguments?

Eles são apenas strings, xargs não sabe o que eles significam. Se você tivesse um utilitário que não aceitasse a lista usual de arquivos, mas aceitasse uma opção -f filename , você poderia organizar o xargs para obter entradas como -f file1 -f file2 ... e seria muito bom passar adiante. Embora com muita entrada, o limite de tamanho poderia causar novamente uma divisão entre um -f e um nome de arquivo, mas adicionar algo como -n 100 tornaria isso improvável (dependendo do tamanho dos arquivos e do limite de tamanho real). / p>

What if -i of xargs is involved?

-i no GNU xargs é o mesmo que -I {} , e de forma um tanto enfadonha torna xargs executar o comando uma vez para cada argumento de entrada. Ajuda se você precisar colocar o argumento no meio do comando, mas realmente não ajuda a reduzir o número de invocações para o comando.

    
por 08.06.2018 / 00:04
1

A ferramenta xargs lê (por padrão) tokens delimitados por espaços da entrada padrão e os transforma em opções de linha de comando para o programa especificado. Por padrão, ele levará quantos tokens puderem caber em uma linha de comando e executar o comando uma vez com esses tokens:

echo 1 2 3 | xargs echo "-"
- 1 2 3

Aqui, xargs lê 1, 2 e 3 e executa echo "-" 1 2 3 . Estou incluindo o "-" para ajudar a esclarecer quantas vezes echo está sendo invocado.

Você pode limitar o número de argumentos que ele passará para o comando usando a opção -n :

echo 1 2 3 | xargs -n2 echo "-"
- 1 2
- 3

Aqui, xargs lê 2 tokens (o máximo) de seu fluxo de entrada padrão e executa o comando com esses tokens como parâmetros de linha de comando: echo "-" 1 2 . Como ainda não tinha terminado de ler os tokens da entrada padrão, ele continuou lendo 3, encontrou EOF e executou o comando novamente com os parâmetros restantes: echo "-" 3 .

Ajustar o valor de n fornecerá um comportamento diferente:

echo 1 2 3 | xargs -n1 echo "-"
- 1
- 2
- 3

Edit: Tim comentou que eu não respondi as perguntas dele. Não concordo e tentarei explicitar as respostas abaixo:

Am I correct that xargs runs command in several run, each of which with different sequence of arguments?

Eu abordei essa questão. Pode executar o comando em uma ou várias execuções. Por padrão, ele tenta executar command o menor número de vezes possível (limitado pelo tamanho do argumento).

If yes, does it mean that such a command must satisfy that applying a sequence of arguments to the command is effectively the same as (x) splitting the sequence of arguments into subsequences, and (x) running the command with each subsequence of arguments in a different run?

Eu abordei essa questão. Se os tokens são muito longos (ou são limitados pela opção -n , então xargs os divide em subseqüências e executa o comando com as subsequências. Eu até dou exemplos disso acontecendo.

Is the above condition a necessary and sufficient condition for a command to be executed by xargs?

Embora eu não tenha uma resposta explícita para isso, meu pensamento era que a semântica poderia ser inferida a partir dos exemplos. Se os argumentos para command tiverem um significado especial com base na posição, então command provavelmente não será um bom candidato para xargs (embora eu tenha certeza que você poderia criar cuidadosamente casos que funcionariam).

Is there any command which doesn't satisfy the above condition? (I can't find any.) If there is, can it be run by xargs?

Mais uma vez, você pode criar cuidadosamente um caso desses (mas eu não recomendaria isso). Um exemplo cuidadosamente criado é (executando mv a.txt b.txt ):

$ ls
a.txt
$ echo a.txt b.txt | xargs mv
$ ls
b.txt

Can the arguments passed by xargs to command be any kind of arguments: options, option arguments, or nonoption arguments? I think this question is helpful for answering the above questions.

Eles são lidos como tokens delimitados por espaços. Eles são passados para o comando como argumentos delimitados por espaço. Isto irá correr ls -l :

$ echo -l | xargs ls
total 0
-rw-r----- 1 user group 0 Jun 7 15:16 b.txt

What if -i of xargs is involved?

Ok, eu não respondi a este, mas não entendo o que você está perguntando neste contexto.

    
por 07.06.2018 / 20:03

Tags