a posição do parâmetro de comando

0

Acho que a posição do parâmetro de qualquer comando não é fixa.

Por exemplo, cp -r ./abc ./def e cp ./abc ./def -r são iguais, grep -rnH hello . e grep hello . -rnH são iguais ...

No entanto, hoje, quando eu estava usando ldd , descobri que estava errado. Porque ldd -r x.so e ldd x.so -r não são iguais. O segundo comando me deu um erro:

ldd: ./-r: No such file or directory

Por que não podemos mudar a posição do parâmetro ldd ?

    
por Yves 09.05.2018 / 11:50

1 resposta

6

Alguns utilitários GNU reorganizam silenciosamente os parâmetros da linha de comando para que as opções e o argumento-opção sejam apresentados antes dos operandos. Este não é um comportamento padrão.

Utilitários padrão concordam que as opções e os argumentos de opção devem vir primeiro, e quando o analisador de linha de comando encontra o primeiro argumento de não-opção, os demais argumentos são tratados como operandos:

cp -i file1 file2

No acima, o primeiro argumento é uma opção, enquanto os dois últimos argumentos são operandos.

cp file1 file2 -i

O acima tem três operandos, e uma implementação não-GNU de cp poderia copiar file1 e file2 no diretório chamado -i (ou fornecer uma mensagem de erro se tal diretório não existisse). O GNU cp , por outro lado, trata -i como uma opção e pergunta se eu gostaria de sobrescrever file2 se esse arquivo existir.

Esse comportamento é corrigido pela configuração da variável de ambiente POSIXLY_CORRECT :

$ cp file1 file2 -i
cp: overwrite 'file2'? n

$ POSIXLY_CORRECT=1 cp file1 file2 -i
cp: target '-i' is not a directory

Ou você poderia usar -- para explicitamente marcar o fim das opções (o que funcionaria se o comando analisasse suas opções da maneira GNU ou não):

$ cp -- file1 file2 -i
cp: target '-i' is not a directory

Isso é algo para se ter em mente em coisas como:

grep 'PATTERN' *.txt

Qual com o GNU grep você precisa escrever:

grep -- 'PATTERN' *.txt

ou

grep -e 'PATTERN' -- *.txt

No caso de o PATTERN ou o nome de alguns dos arquivos .txt começarem com - .

Seu ldd (que nos sistemas GNU é um script bash que analisa opções manualmente, não usando a API getopt_long() do GNU) não analisa seus argumentos de linha de comando no "modo GNU", que (IMHO ) está fazendo corretamente.

A partir da documentação GNU de getopt_long(3) :

By default, getopt() permutes the contents of argv as it scans, so that eventually all the nonoptions are at the end. [...] If the first character of optstring is + or the environment variable POSIXLY_CORRECT is set, then option processing stops as soon as a nonoption argument is encountered.

    
por 09.05.2018 / 12:01