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

21

Eu sei que rm -f file1 removerá com vigor file1 sem me avisar.

Eu também sei que rm -i file1 me avisará antes de remover file1

Agora, se você executar rm -if file1 , isso também removerá com vigor file1 sem me avisar.

No entanto, se você executar rm -fi file1 , ele me avisará antes de remover file1 .

Então, é verdade que ao combinar opções de comando, a última terá precedência? como rm -if , então -f terá precedência, mas rm -fi , em seguida, o -i terá precedência.

O comando ls , por exemplo, não importa se você disse ls -latR ou ls -Rtal .

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

    
por alkabary 10.08.2015 / 21:22

3 respostas

23

Ao usar rm com as opções -i e -f , o primeiro será ignorado. Isto 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 no GNU info page:

‘-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ô:

rm processa sua opção com getopt(3) , especificamente getopt_long . Esta função irá processar os argumentos da opção na linha de comando ( **argv ) em ordem de aparição:

If getopt() is called repeatedly, it returns successively each of the option characters from each of the option elements.

Essa função é normalmente chamada em um 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 rm e i e f options, eles sobrescrevem-se 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;

Ambas as opções definem as mesmas variáveis, e o estado dessas variáveis será a última opção na linha de comando. O efeito disso está em linha com o padrão POSIX e a documentação rm .

    
por 10.08.2015 / 21:46
7

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

‘-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. Equivalent to ‘--interactive=always’.

Como uma dica geral: info geralmente é mais detalhado que man , que geralmente é mais detalhado que a opção --help .

    
por 10.08.2015 / 21:48
7

Não há "precedência" para os sinalizadores, cada programa os manipula da maneira que desejar. A maioria faz algum esforço para coletar todos os sinalizadores e verificar conflitos, para ferramentas padrão (como o referenciado rm(1) ) os padrões relevantes podem exigir alguma coisa (mas, novamente, sua versão particular pode ser desleixada na interpretação de casos de canto do padrão) ser especificamente testado para eles).

Para o programador que escreve o programa, é mais fácil considerar os argumentos (sinalizadores e outros) na ordem estrita da esquerda para a direita, e talvez resgatar ao atingir 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).

    
por 11.08.2015 / 03:38