"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

Warum werden Programmen Argumente auf so unterschiedliche Art übergeben?

fogerl 19.01.2014 - 21:54 2200 10 Thread rating
Posts

fogerl

Little Overclocker
Registered: Jan 2005
Location: Wien
Posts: 98
Hallo!

Ich habe mittlerweile schon mehrere unterschiedliche Arten gesehen, auf denen Programmen Argumente übergeben werden.

* ./executable -x 1 -y 2 -z 3 foo bar (Beispiel: weiß ich grad keines)
* ./executable -x1 -y2 -z3 foo bar (Beispiel: cut)
* ./executable -x=1 -y=2 foo bar (Beispiel: dd)

Warum gibt es hier unterschiedliche Arten der Argumentübergabe?
* Ist vlt. eines POSIX und das andere nicht?
* Oder gibt's funktionelle Unterschiede?
* Funktionert jede der aufgeführten Arten bei jedem Programm? (Könnte ich eigtl. testen, bin aber grad im Windows. :))


Könnte bei der Gelegenheit vielleicht jemand erklären, wie so eine Argumentsübergabe im Detail funktioniert? Mich würde interessieren, wo da die Shell aufhört und das Programm beginnt.

Danke!
fogerl

Nachtrag: Heißt es korrekt „Argumente“ oder „Parameter“?

d3cod3

Legend
...
Avatar
Registered: Aug 2002
Location: insert location ..
Posts: 15288
das programm schaut einfach was hereinkommt und interpretiert es je nachdem wie es programmiert wurde. "-", "=" oder all diese symbole sind meines wissens oft nur der lesbarkeit halber für menschen dabei.

semteX

Risen from the banned
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14331
true, die programme bekommen den input in nem string array / vektor / you name it rein, wo "space" als trennzeichen verwendet wird. danach hängt es davon ab, wie der entwickler beim implementiern lustig war.

daneben gibts noch recht feine sachen wie bash completion, mit denen ma seine eigenen shell scripts um bash completion (und eben auch optionen, ..) erweitern kann, ohne dass ma komplett vor die hunde geht. die halten sich, was ich bisher gelesen hab an die -k value bzw --key value notation

gabs dafür mal coding guidelines eigenlich? oder hat ma irgendwann eingesehen, dass ma es am besten so wie der nachbar macht?

d3cod3

Legend
...
Avatar
Registered: Aug 2002
Location: insert location ..
Posts: 15288
ich nehme an das ist eine mischung aus "woar immer so" und "den schas moch ma besser" :p

that

Hoffnungsloser Optimist
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11326
Es gibt verschiedene Guidelines und Konventionen, z.B. hier die von POSIX mit GNU-Erweiterungen:

http://www.gnu.org/software/libc/ma...ent-Syntax.html

Dass es überhaupt verschiedene Standards gibt, sollte nicht weiter verwundern, schließlich sind auch bei verschiedenen GUI-Programmen die Buttons immer woanders. :)

fogerl

Little Overclocker
Registered: Jan 2005
Location: Wien
Posts: 98
Danke für eure Antworten!

Insbesondere der letzte Link (http://www.gnu.org/software/libc/ma...ent-Syntax.html) hat mir sehr geholfen!

COLOSSUS

Administrator
Frickler
Avatar
Registered: Dec 2000
Location: ~
Posts: 11898
Zitat von semteX
true, die programme bekommen den input in nem string array / vektor / you name it rein, wo "space" als trennzeichen verwendet wird. danach hängt es davon ab, wie der entwickler beim implementiern lustig war.

Das ist nicht ganz richtig - die Programme kriegen vom Betriebssystem bzw. dem Prozess, der den execve(2)-Syscall aufruft, den Argumentvektor (per Konvention im "empfangenden" bzw. diesen auswertenden Prozess mit dem Namen argv deklariert) als ein durch NUL-Bytes getrenntes Array von char-Arrays durchgereicht. Die Shell benutzt Whitespace (wie auch 0x20/Space) als Seperator fuer Word Splitting, und entscheidet anhand dieses unescapten Whitespace, wie der Argumentvektor fuer execve(2) ausehen soll, bzw. wie der Benutzer diesen gestaltet haben will.

Ein anschauliches Beispiel:

Code:
$ strace -ff -s 1000 -e trace=execve ls / / / >/dev/null
execve("/bin/ls", ["ls", "/", "/", "/"], [/* 35 vars */]) = 0

$ strace -ff -s 1000 -e trace=execve sh -c "/bin/echo hallo welt"
execve("/bin/sh", ["sh", "-c", "/bin/echo hallo welt"], [/* 35 vars */]) = 0
Process 5920 attached
[pid  5920] execve("/bin/echo", ["/bin/echo", "hallo", "welt"], [/* 35 vars */]) = 0
hallo welt
Process 5920 detached
--- SIGCHLD (Child exited) @ 0 (0) ---

(Im zweiten Beispiel erfolgt das Word Splitting des gequoteten Strings erst duch jene Shell, welche als Kind von strace(1) mit der Shortopt -c dazu angewiesen wurde, den Rest ihres Argumentvektors ad hoc als Kommando auszufuehren.)


Die Aufrufsyntax von Programmen ist durch getopt(3) in der Standard-Library von C zwar nicht standardisiert, aber eine Konvention existiert. GNU getopt_long(3) (aus der glibc) erweitert diese Konvention um Longopts (mit Doppel-Dash "--" am Beginn eines zumeiste "sprechenden" Optionsnamens), aber niemand zwingt einen (C-)Programmierer, sich daran auch zu halten.

Nico

former person of interest
Registered: Sep 2006
Location: -
Posts: 4082
warum is das eigentlich eine gnu-frage? Läufts nicht prinzipiell gleich ab auf allen OS?

COLOSSUS

Administrator
Frickler
Avatar
Registered: Dec 2000
Location: ~
Posts: 11898
Kann zumindest ich dir nicht beantworten, da ich nicht "alle OS" kenne ;) GNU (und GNU-Programme, bis auf wenige historisch begruendete Ausnahmen wie bspw. GNU dd und GNU find) verwenden alle die GNU-Konventionen; die BSDs halten sich in ihren Standardanwendungen auch an (ihre jeweils eigenen) Konventionen bzw. nutzen i.A. durchwegs deren eigene getopt(3)-Implementation. Manche Programme benutzen ueberhaupt nichts aus der stdlib zum Parsen des Argumentvektors, und haben einen groszen Loop mit strncmp-Abfragen ueber den Vektor...

Ich kann mir aber durchaus vorstellen, dass es OS gibt oder gab, die einen standardisierten, mandatorischen Parser fuer argv haben. Waere ja durchaus sinnvoll - so gibt es einen Batzen Implementationen, die alle etwas sehr Aehnliches machen, und das noch auf subtil unterschiedliche Art und Weise.

semteX

Risen from the banned
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14331
Zitat von COLOSSUS
Das ist nicht ganz richtig - die Programme kriegen vom Betriebssystem *much more text*
*bow*

GrandAdmiralThrawn

XP Nazi
Avatar
Registered: Aug 2000
Location: BRUCK!
Posts: 3682
Zitat von Nico
warum is das eigentlich eine gnu-frage? Läufts nicht prinzipiell gleich ab auf allen OS?
Schau dir Windows an. Wennst GNU Software drauf baust, dann kriegst da natürlich die üblichen -option und --long-option Params, phasenweise mit = oder auch nicht.

Und ruf ein Windows (oder IBM OS/2 lol) Command Line Binary auf, da kriegst mit an Sicherheit grenzender Wahrscheinlichkeit /option oder sowas wie /option:value.

Soviel zu Standards, kannst vergessen. ;)
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz