Vorrang von Befehlsoptionen?

21

Ich weiß, das rm -f file1wird gewaltsam entfernt, file1ohne mich dazu aufzufordern.

Ich weiß auch, dass rm -i file1mich das zuerst auffordert, bevor es entfernt wirdfile1

Wenn Sie jetzt ausführen rm -if file1, wird dies auch mit Gewalt entfernt, file1ohne mich dazu aufzufordern.

Wenn Sie jedoch ausführen rm -fi file1, werde ich vor dem Entfernen dazu aufgefordert file1.

Stimmt es, dass beim Kombinieren von Befehlsoptionen die letzte Priorität hat? wie rm -if, dann -fwird Vorrang haben, aber -fidann -iwird der Vorrang haben.

Dem lsBefehl zum Beispiel ist es egal, ob Sie ls -latRoder sagten ls -Rtal.

Also denke ich, dass es nur wichtig ist, wenn Sie widersprüchliche Befehlsoptionen haben rm -if, ist das richtig?

alkabary
quelle
Siehe auch: cp -f kann cp -i alias nicht überschreiben
Stéphane Chazelas

Antworten:

23

Bei der Verwendung rmmit beiden -iund -f Optionen, wird die erste ignoriert. Dies ist im POSIX- Standard dokumentiert :

    -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.

und auch auf der GNU infoSeite:

‘-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.

Mal sehen, was unter der Haube passiert:

rmverarbeitet seine Option mit getopt(3), speziell getopt_long. Diese Funktion verarbeitet die Optionsargumente in der Befehlszeile ( **argv) in der angegebenen Reihenfolge:

Wenn getopt () wiederholt aufgerufen wird, werden nacheinander alle Optionszeichen der einzelnen Optionselemente zurückgegeben.

Diese Funktion wird normalerweise in einer Schleife aufgerufen, bis alle Optionen verarbeitet wurden. Aus Sicht dieser Funktionen werden die Optionen der Reihe nach abgearbeitet. Was jedoch tatsächlich passiert, ist anwendungsabhängig, da die Anwendungslogik auswählen kann, ob widersprüchliche Optionen erkannt, überschrieben oder ein Fehler angezeigt werden soll. Für den Fall rmund die iund f-Optionen überschreiben sie sich perfekt. Von 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;

Beide Optionen setzen die gleichen Variablen und der Status dieser Variablen ist die letzte Option in der Befehlszeile. Die Auswirkung entspricht dem POSIX-Standard und der rmDokumentation.

casey
quelle
3
Die meisten Befehle verarbeiten ihre Argumente der Reihe nach und nehmen entweder Fehler bei Konflikten oder die letzte Einstellung (wie rm) vor. Ich denke, es ist selten, dass ein Befehl jemals die erste Einstellung einer Option annimmt und Argumente ignoriert, die eine bereits festgelegte Option ändern würden.
Peter Cordes
7

Ja, rmdas ist gültig. Ob die letzte Option die vorherigen überschreibt, hängt jedoch vom jeweiligen Programm ab. Aus ´info rm´

'-f' '--force' Ignoriert nicht vorhandene Dateien und fehlende Operanden und fordert den Benutzer niemals dazu auf. Ignorieren Sie alle vorherigen Optionen '--interactive' ('-i').

'-i' Abfrage, ob die einzelnen Dateien entfernt werden sollen. Wenn die Antwort nicht positiv ist, wird die Datei übersprungen. Ignorieren Sie alle vorherigen '--force'-Optionen (' -f '). Entspricht "--interactive = always".

Als genereller Hinweis: Ist in der infoRegel detaillierter als man, was selbst in der Regel detaillierter als die --helpOption ist.

Fiximan
quelle
7

Es gibt keine "Priorität" für Flags, jedes Programm behandelt sie so, wie es es wünscht. Die meisten bemühen sich, alle Flags zu sammeln und auf Konflikte zu prüfen. Für Standardwerkzeuge (wie die referenzierten rm(1)) schreiben die relevanten Standards möglicherweise etwas vor (Ihre spezielle Version kann jedoch bei der Interpretation von Eckfällen des Standards schlampig sein / nicht speziell getestet werden für Sie).

Für den Programmierer, der das Programm schreibt, ist es am einfachsten, die Argumente (Flags und andere) in strikter Reihenfolge von links nach rechts zu betrachten und möglicherweise auszusteigen, wenn er einen Haken trifft. Wenn Sie eine Bibliothek verwenden, um mit Flags umzugehen (zum Beispiel getopt(3), es gibt mehrere Versionen, die im Umlauf sind), tut der Programmierer vermutlich das, was am einfachsten / natürlichsten ist. Programmierer sind Menschen, Menschen sind faul (oder denken zumindest nicht gern über die kombinatorische Explosion nach).

vonbrand
quelle