A precedência das opções de comando?

21

Eu sei que isso rm -f file1será removido com força file1sem me avisar.

Eu também sei que isso rm -i file1irá me avisar antes de removerfile1

Agora, se você executar rm -if file1, isso também será removido com força file1sem avisar.

No entanto, se você executar rm -fi file1, ele será solicitado antes da remoção file1.

Então, é verdade que, ao combinar as opções de comando, a última terá precedência? como rm -if, então -fterá precedência, mas rm -fientão -iterá precedência.

O lscomando, por exemplo, não importa se você disse ls -latRou ls -Rtal.

Então, acho que só importa quando você tem opções de comando contraditórias como rm -if, está correto?

alcabar
fonte
Related: cp -f não pode sobrescrever cp -i alias
Stéphane Chazelas

Respostas:

23

Ao usar rmcom ambos -ie -f opções, o primeiro será ignorado. Isso está documentado no padrão POSIX :

    -f
       Do not prompt for confirmation. Do not write diagnostic messages or modify
       the exit status in the case of nonexistent operands. Any previous
       occurrences of the -i option shall be ignored.
    -i
       Prompt for confirmation as described previously. Any previous occurrences
       of the -f option shall be ignored.

e também na infopágina GNU :

‘-f’
‘--force’

    Ignore nonexistent files and missing operands, and never prompt the user.
    Ignore any previous --interactive (-i) option.

‘-i’
    Prompt whether to remove each file. If the response is not affirmative, the
    file is skipped. Ignore any previous --force (-f) option.

Vamos ver o que acontece sob o capô:

rmprocessa sua opção com getopt(3), especificamente getopt_long. Esta função processará os argumentos das opções na linha de comando ( **argv) na ordem em que aparecer:

Se getopt () for chamado repetidamente, ele retornará sucessivamente cada um dos caracteres de opção de cada um dos elementos de opção.

Essa função é normalmente chamada em loop até que todas as opções sejam processadas. Nesta perspectiva de funções, as opções são processadas em ordem. O que realmente acontece, no entanto, depende do aplicativo, pois a lógica do aplicativo pode optar por detectar opções conflitantes, substituí-las ou apresentar um erro. Para o caso de rme as opções ie f, eles substituem perfeitamente um ao outro. De rm.c:

234         case 'f':
235           x.interactive = RMI_NEVER;
236           x.ignore_missing_files = true;
237           prompt_once = false;
238           break;
239 
240         case 'i':
241           x.interactive = RMI_ALWAYS;
242           x.ignore_missing_files = false;
243           prompt_once = false;
244           break;

As duas opções definem as mesmas variáveis ​​e o estado dessas variáveis ​​será a opção que for a última na linha de comando. O efeito disso está alinhado com o padrão POSIX e a rmdocumentação.

Casey
fonte
3
A maioria dos comandos processa seus argumentos em ordem e os erros em conflitos ou assumem a última configuração (como rm). Eu acho que é raro um comando pegar a primeira configuração de uma opção e ignorar argumentos que alterariam uma opção já definida.
Peter Cordes
7

Sim, pois rmisso é válido. Se a última opção substitui as anteriores, no entanto, depende do programa individual. De "info rm"

'-f' '--force' Ignora arquivos inexistentes e operandos ausentes e nunca solicita ao usuário. Ignore qualquer opção '--interactive' ('-i') anterior.

'-i' Solicita a remoção de cada arquivo. Se a resposta não for afirmativa, o arquivo será ignorado. Ignore qualquer opção '--force' ('-f') anterior. Equivalente a '--interactive = always'.

Como uma dica geral: infogeralmente é mais detalhado que man, o que em si é geralmente mais detalhado que a --helpopção.

Fiximan
fonte
7

Não há "precedência" para sinalizadores, cada programa lida com eles da maneira que desejar. A maioria faz algum esforço para coletar todos os sinalizadores e verificar se há conflitos; para ferramentas padrão (como as mencionadas rm(1)), os padrões relevantes podem exigir algo (mas, novamente, sua versão específica pode ser desleixada na interpretação de casos de canto do padrão / não é testada especificamente para eles).

Para o programador que está escrevendo o programa, é mais fácil considerar os argumentos (sinalizadores e outros) em estrita ordem da esquerda para a direita, e talvez socorrer ao acertar algum obstáculo. Se estiver usando uma biblioteca para manipular sinalizadores (como getopt(3), existem várias versões flutuando), o programador presumivelmente faz o que é mais fácil / natural. Programadores são pessoas, pessoas são preguiçosas (ou pelo menos não gostam de pensar na explosão combinatória).

vonbrand
fonte