Por que eu preciso do traço duplo antes do argumento passado para sh por xargs -I para que ele funcione corretamente?

5

Desculpe pelo título de bocado. Aqui está o comando em questão

 find . -name "*.txt" | xargs -Ifile sh -c 'echo $(basename $1) ' -- file

Portanto, sem o traço duplo, o file não é passado para sh e, em seguida, é reconhecido como $1 . Por que é que? Eu sei que -- impede que o argumento consequente seja reconhecido como opções de linha de comando. Mas como file não é prefixado com um traço, parece que não há razão para que ele seja reconhecido como uma opção de linha de comando.

    
por Forethinker 06.08.2013 / 00:49

2 respostas

8

O primeiro argumento não opcional para sh se torna $0 . Quando sh é invocado em um script, esse é o caminho para o script. Quando você executa sh -c SOMECOMMAND , o shell não usa o argumento para nada além de colocar em $0 . Convencionalmente, seria um nome para o script passado para -c , por analogia com o sh /path/to/script caso em que $0 é o nome ou caminho do script.

Diferentemente da maioria dos comandos, -- é tratado como um argumento comum, não como um marcador de finalidade especial. Então é realmente -- que é usado como $0 e não o próximo argumento.

$ sh -c 'echo $1' hello            

$ sh -c 'echo $0' hello
hello
$ sh -c 'echo $0; echo $1' hello world
hello
world
$ sh -c 'echo $0; echo $1' -- hello
--
hello

Isso não tem nada a ver com xargs , está passando todos os argumentos após sh para o comando sh .

    
por 06.08.2013 / 02:54
0

No exemplo acima, o -- está atuando como um bloqueador entre sh -c 'echo $(basename $1) ' e file . está forçando a string file a ser o argumento $1 para sh .

O texto acima poderia ter sido simplificado para isso:

$ find . -name "*.txt" | xargs -Ifile sh -c 'echo $(basename file) '
    
por 06.08.2013 / 02:55