Shell Programmierung - Unterschied FreeBSD/Linux

Midian

Well-Known Member
Ich betreibe ein klein wenig Shellprogrammierung vom Studium aus, dort an Suse Rechnern. Nun wollte ich ein Script auf meinem Rechner (FreeBSD 5.3) schreiben, wobei mir aber aufgefallen ist, dass wohl einige Dinge entweder anders sind, oder nicht funktionieren.


Das Script wurde auf dem Suse Rechner geschrieben, läuft aber nicht bei mir.

Frage: Sind manche Befehle schlicht anders, und ich muss die auswendig wissen/lernen, oder gehen manche Dinge einfach nicht bei FreeBSD, oder ist alles nur eine Einstellungssache ? Benutzt wurde beide Male die Bash Shell.

Danke im Voraus.
 
Zuletzt bearbeitet:
/bin/bash gibt es unter FreeBSD schon mal nicht. Du mußt die bash aus den Ports installieren und /usr/local/bin/bash als Shell angeben. Standard sind unter FreeBSD (t)csh und natürlich die einfache Bourne Shell, sh.

Sobald Du bash am Laufen hast, sind alle Befehle, die von der Shell interpretiert werden, identisch unter Linux und FreeBSD. Wenn jedoch externe Programme aufgerufen werden, so kann deren Befehlssyntax unterschiedlich sein. GNU ist berühmt dafür, inkompatible und undokumentierte Erweiterungen en masse vorzunehmen. So kennt das FreeBSD ls meines Wissens den Parameter --time-style nicht. Du solltest also in den jeweiligen man Pages nachschauen und die Befehlsaufrufe so umschreiben, daß sie sowohl unter Linux als auch FreeBSD gehen - oder für die beiden Betriebssysteme unterschiedliche Codepfade vorsehen.
 
Wenn's portabel sein soll, dann nimm lieber gleich perl/python/ruby/C. Und warum deklarierst du es als bash Skript, obwohl es auch mit der sh tun wuerde?

PS: Das Ausgabe-Format von ls(1) ist nicht standardisiert, sich darauf zu verlassen ist sehr schlechter Stil.
 
undo schrieb:
/bin/bash gibt es unter FreeBSD schon mal nicht. Du mußt die bash aus den Ports installieren und /usr/local/bin/bash als Shell angeben. Standard sind unter FreeBSD (t)csh und natürlich die einfache Bourne Shell, sh.

Sobald Du bash am Laufen hast, sind alle Befehle, die von der Shell interpretiert werden, identisch unter Linux und FreeBSD. Wenn jedoch externe Programme aufgerufen werden, so kann deren Befehlssyntax unterschiedlich sein. GNU ist berühmt dafür, inkompatible und undokumentierte Erweiterungen en masse vorzunehmen. So kennt das FreeBSD ls meines Wissens den Parameter --time-style nicht. Du solltest also in den jeweiligen man Pages nachschauen und die Befehlsaufrufe so umschreiben, daß sie sowohl unter Linux als auch FreeBSD gehen - oder für die beiden Betriebssysteme unterschiedliche Codepfade vorsehen.

[edit] habs zum laufen gebracht :)
 
Zuletzt bearbeitet:
Wer wegen Plattformunabhängigkeit die /bin/sh empfiehlt, hat nicht wirklich Ahnung von der Sache. Wenn man plattformunabhängig programmieren will, dann bleiben eigentlich nur bash und zsh.
 
Hu? /bin/sh ist immer vorhanden, zsh/bash schonmal nicht. Und wenn, dann kann es sonstwo liegen. Prominentes Beispiel: FreeBSD. Da gibts nur /usr/local/bin/bash (wenn ueberhaupt).

Da hast du dich gerade selbst ins Aus gekegelt ...
 
Es ist immer wieder amüsant zu sehen, wie einige Leute hier große Töne spucken ("ins Aus gekegelt", gut gebrüllt!), obwohl sie von der Thematik keine Ahnung haben und dabei nicht merken, wie blamabel ihre Beiträge sind.
  • Portabilität hat nichts damit zu tun, welche Programme im Basissystem enthalten sind, die Verfügbarkeit an sich ist entscheidend (Perl ist heute noch genauso portabel wie zu 4.x-Zeiten, obwohl es seit 5.x nicht mehr im Basissystem enthalten ist).

  • Daß /bin/sh immer /bin/sh heißt, ist so ziemlich die dämlichste Argumentation. /bin/sh ist auf Linux eine bash, auf FreeBSD und NetBSD eine weiterentwickelte ash, auf OpenBSD eine pdksh und auf kommerziellen Unices meist eine ksh. Also was soll das für ein Argument sein?

  • Shell-Skripte können den Pfad zum Kommandointerpreter selbständig ermitteln, solange er im $PATH liegt.
Ich glaube, ich sollte hierfür mal meinen ersten :huth: verteilen.
 
@p.h.
ähm *hust*
(imho) egal ob als 'ash', 'ksh' oder foo, kampatiblität zu 'sh' ist _immer_ da
das eintzige proplem ist, das die aufgerufenen programme nicht immer gleich heißen.
zu perl:
afaik mal eben ein kleines shell script ist einfacher gecodet als ein perl script ;)

MfG
 
hoppel schrieb:
(imho) egal ob als 'ash', 'ksh' oder foo, kampatiblität zu 'sh' ist _immer_ da
Du möchtest dich bitte über den Begriff Portabilität (um den geht es hier nämlich) informieren. Zudem ist 'sh' nur ein Dateiname, der heutzutage nichts über die Shell, die darin steckt, aussagt.
hoppel schrieb:
das eintzige proplem ist, das die aufgerufenen programme nicht immer gleich heißen.
Das ist was anderes und wurde oben schon geklärt. Wenn ich mit Software von Drittanbietern arbeite, muß ich mit sowas rechnen. Aber dafür gibt es case-Konstrukte. Wichtig ist jedoch, daß die Shell das Skript an sich immer gleich abarbeitet, sonst klappt das vorne wie hinten nicht. Und da kann ich mich nicht auf eine /bin/sh verlassen, die auf jedem System was anderes ist und nach Gutdünken mehr oder (eher) weniger Bourne-Shell-kompatibel gemacht wurde. Wenn ich dagegen eine bash oder eine zsh verwende, dann habe ich auf jedem System ein genau definiertes Verhalten.
hoppel schrieb:
zu perl:
afaik mal eben ein kleines shell script ist einfacher gecodet als ein perl script ;)
Schon mal versucht, einen guten Paßwortgenerator mit einem "kleinen" Shell-Skript zu realisieren? Mal ganz davon abgesehen ist dein Können völlig irrelevant für den Begriff der Portablilität.

Ich werde mir übrigens künftig nicht mehr die Mühe machen, deine Posts zu lesen, wenn du dir nicht einmal die Mühe machst, die lesbar auf die Menschheit loszulassen. Ein Grundmaß an Orthographie kann man in einem öffentlichen Forum ja wohl erwarten.
 
p.h. schrieb:
Wichtig ist jedoch, daß die Shell das Skript an sich immer gleich abarbeitet, sonst klappt das vorne wie hinten nicht. Und da kann ich mich nicht auf eine /bin/sh verlassen, die auf jedem System was anderes ist und nach Gutdünken mehr oder (eher) weniger Bourne-Shell-kompatibel gemacht wurde. Wenn ich dagegen eine bash oder eine zsh verwende, dann habe ich auf jedem System ein genau definiertes Verhalten.

Also meine Erfahrung ist, dass man mit POSIX und ein wenig Selbstbeschraenkung (i..e. Umschiffen von "dark corners" der Shell) relativ gut faehrt. KISS ist gerade bei Shellscripten angesagt.

Viel mehr Portabilitaetsprobleme habe ich mit dem "Zubehoer", also den ganzen Tools, die man drumherum verwendet (grep, find, xargs, awk, sed, tail, join, ...).

Da erlebe ich regelmaessig GNUisms in diversen Open-Source-Projekten, die dann z.B. auf BSD in die Hose gehen. Oder die beruehmten Tools unter Solaris, die auch mal eben stillschweigend zu lange Zeilen abschneiden, anstatt einfach mit exit(EXIT_FAILURE) auszusteigen. *Das* ist ekelhaft, und solche Probleme hatte ich mit Shells bisher noch nicht.
 
kili schrieb:
Also meine Erfahrung ist, dass man mit POSIX und ein wenig Selbstbeschraenkung (i..e. Umschiffen von "dark corners" der Shell) relativ gut faehrt. KISS ist gerade bei Shellscripten angesagt.
Gerade bei Shell-Skripten gerät man aber auch schnell in kompliziertere Aufgabenstellungen rein, vor allem, wenn man in Bereiche der Systemadministration vordringt. Entweder verwendet man dann spezielle Features der Shell (aus nun schon mehr als einmal genannten Gründen geht das aber nicht mit /bin/sh, wenn man portabel bleiben will) oder man greift auf externe Anwendungen zurück (das ist eher noch weniger portabel als ein bash/zsh-Skript).

Standards wie POSIX sind schön, aber gerade /bin/sh hält sich bei FreeBSD da nicht wirklich dran:
sh(1) schrieb:
The sh utility is the standard command interpreter for the system. The
current version of sh is in the process of being changed to conform with
the IEEE Std 1003.2 (``POSIX.2'') specification for the shell. This ver-
sion has many features which make it appear similar in some respects to
the Korn shell, but it is not a Korn shell clone like pdksh. Only fea-
tures designated by POSIX, plus a few Berkeley extensions, are being
incorporated into this shell.
Auf Deutsch: "Unsere Shell ist ein Gefrickel aus POSIX-Features und Berkeley-Krempel, sieht fast aus wie eine Korn Shell, ist sie aber nicht. Das mit der POSIX-Konformität klappt noch nicht so, mal schauen, das machen wir vielleicht ein anderes mal."
 
Dann reden wir aneinander vorbei. Ich will sh-Skripte, die ueberall laufen, ohne spezielle Voraussetzungen. Du willst bash/zsh-Skripte, weil zsh eigentlich immer zsh ist und bash immer bash.

Ach uebrigens, habe ich nicht sh(1) empfohlen, sondern Perl/Ruby/Python/C/whatever, genau aus dem Grund, den du angibst.

Den Hut kannst du behalten, das naechste Mal einfach erst Lesen bevor man nen Flame veranstaltet. Danke.
 
MrFixit schrieb:
Ich will sh-Skripte, die ueberall laufen, ohne spezielle Voraussetzungen.
Dazu habe ich mittlerweile dreimal sehr deutlich was geschrieben, wenn du das nicht verstehst, dann laß es meinetwegen.
MrFixit schrieb:
Ach uebrigens, habe ich nicht sh(1) empfohlen, sondern Perl/Ruby/Python/C/whatever, genau aus dem Grund, den du angibst.
Deine Argumentation, sofern man das so nennen kann, ist arg inkonsistent, das widerspricht sich völlig mit deinem vorherigen Post.

Von meiner Seite her EOD, solche Diskussionen, in denen Leute nicht mal ihre eigenen Argumente aus dem letzten Post kennen, sind sinnfrei.
 
p.h. schrieb:
Deine Argumentation, sofern man das so nennen kann, ist arg inkonsistent, das widerspricht sich völlig mit deinem vorherigen Post.
Bitte erst lesen, dann posten. Ich schrieb gleich zu Anfang:
Wenn's portabel sein soll, dann nimm lieber gleich perl/python/ruby/C.
Worauf du mit bash/zsh als Allheilmittel kamst. Nur zu dumm, dass diese auf nicht allen *nix-Systemen installiert sind.

Das Skript des OP waere durch das entfernen von nur zwei Bytes auf fast allen *nix-Systemen lauffaehig (modulo ls(1)), mit der /bin/bash-Zeile hingegen laeuft es out-of-the-box quasi nur mit Linux.

Ich muss schon sagen, du hast eine sehr komische Einstellung zur Shell.

Von meiner Seite her EOD, solche Diskussionen, in denen Leute nicht mal ihre eigenen Argumente aus dem letzten Post kennen, sind sinnfrei.
Tut mir leid, ich wuerde dir den Thread ja gerne vorlesen, wenn dir das Lesen soviel Probleme bereitet. Aber mir wird's inzwischen auch zu doof. Ich brauche mir nicht solche Sachen an den Kop^H^H^HHut werfen zu lassen :)
 
MrFixit schrieb:
Tut mir leid, ich wuerde dir den Thread ja gerne vorlesen, wenn dir das Lesen soviel Probleme bereitet
Hör mal - selbst nach EOD -, verarschen lassen muß ich mich von dir nicht.
MrFixit schrieb:
mit der /bin/bash-Zeile hingegen laeuft es out-of-the-box quasi nur mit Linux.
Was steht eigentlich in Post #10, Punkt c? Wenn du den Punkt nicht verstanden hättest, könntest du nachfragen, so gehe ich davon aus, daß du dir unangenehme Argumente bewußt unter den Tisch fallen läßt, damit du nicht darauf eingehen mußt. Du bist bisher jedenfalls noch auf kein Argument eingegangen, sondern ignorierst sie einfach.
MrFixit schrieb:
Bitte erst lesen, dann posten. Ich schrieb gleich zu Anfang:

Wenn's portabel sein soll, dann nimm lieber gleich perl/python/ruby/C.

Worauf du mit bash/zsh als Allheilmittel kamst.
Diese Behauptung ist schlichtweg falsch und ich möchte dich bitten, sowas zu unterlassen. Mein Einwand mit /bin/sh bezog sich nicht auf perl/python/ruby/C, sondern auf den darauffolgenden Satz sowie auf den Post von Maledictus. Tja, nicht nur lesen, sondern auch zuordnen muß man können.
MrFixit schrieb:
Nur zu dumm, dass diese auf nicht allen *nix-Systemen installiert sind.
Demnach wäre es auch ziemlich dumm, daß perl/python/ruby/C nicht auf allen *nix-Systemen installiert sind. Ein C-Compiler wohl noch am ehesten, aber auch nicht überall. Nur ist das Argument völlig egal, das stand in Post #10, Punkt a. Da frage ich mich doch, wer hier den Thread noch einmal vorgelesen bekommen sollte. Vor allem mal solltest du nicht ständig deine eigenen Argumente widerlegen, was ist das denn für eine Art?
MrFixit schrieb:
Ich muss schon sagen, du hast eine sehr komische Einstellung zur Shell.
Über deine komische Einstellung zu deinen eigenen Posts und Argumenten solltest du dich eher wundern.
 
Also Männer, ihr solltet vielleicht mal von der persönlichen Note runterkommen und das Thema rein sachlich angehen, Begriffsunterschiede mal hin oder her. Wir wollen doch alle nicht, daß dieser imho sehr gute thread ins Persönliche abgleitet? ;)
 
p.h. schrieb:
Gerade bei Shell-Skripten gerät man aber auch schnell in kompliziertere Aufgabenstellungen rein, vor allem, wenn man in Bereiche der Systemadministration vordringt. Entweder verwendet man dann spezielle Features der Shell (aus nun schon mehr als einmal genannten Gründen geht das aber nicht mit /bin/sh, wenn man portabel bleiben will) oder man greift auf externe Anwendungen zurück (das ist eher noch weniger portabel als ein bash/zsh-Skript).

Sure. Allerdings hast Du ein klein wenig zu heftig die Sysadmin bzw. "Ich kenne den Sysadmin"-Brille auf. Es gibt Situationen (und ich schlage mich regelmaessig damit herum), in denen man eben nicht mal eben seine Lieblingsshell installieren kann, sondern mit dem leben muss, was das System, auf dem man gerade (als Otto-Normal-User ohne Rootrechte) bietet. Wenn man es mit Maschinen zu tun hat, die man selbst administriert, ist es natuerlich komplett togal, ob man nun, bash, zsh, pdksh oder whatever bevorzugt.


Standards wie POSIX sind schön, aber gerade /bin/sh hält sich bei FreeBSD da nicht wirklich dran:Auf Deutsch: "Unsere Shell ist ein Gefrickel aus POSIX-Features und Berkeley-Krempel, sieht fast aus wie eine Korn Shell, ist sie aber nicht. Das mit der POSIX-Konformität klappt noch nicht so, mal schauen, das machen wir vielleicht ein anderes mal."

Das kann man ja aendern. Bei der pdksh von OpenBSD gab es bereits ein paar winzige Aenderungen in Richtung POSIX, und es werden demnaechst hoffentlich noch ein paar mehr. Apple verpasst seiner neuen Version von Mac OS X eine bodenstaendige AT&T ksh (ich muss zugeben, dass ich nicht exakt weiss, wie POSIX-konform die wirklich ist).

Insofern besteht Grund zur Hoffnung. Eine Entwicklung in Richtung POSIX halte ich mittelfristig jedendalls besser als die explzite Verwendung von Ablegern wie bash, zsh, foosh, ... (siehe auch oben. Wenn $KUNDE keine bash duldet, hast Du automatisch verloren).

Bis es -- wann auch immer -- soweit ist, kann man eigentlich nur predigen, so wenig Features wie moeglich zu verwenden.
 
kili schrieb:
Eine Entwicklung in Richtung POSIX halte ich mittelfristig jedendalls besser als die explzite Verwendung von Ablegern wie bash, zsh, foosh, ...
Tja, allerdings ist POSIX ein Standard und beim Einhalten gemeinsamer Standards haben sich die Unices in den letzten 30 Jahren nicht gerade mit Ruhm bekleckert. Aber die Hoffnung stibt zuletzt :)
kili schrieb:
(siehe auch oben. Wenn $KUNDE keine bash duldet, hast Du automatisch verloren).
Naja, dann fliegt schon mal automatisch Linux raus, das ist ja schon mal ein Gewinn ;)

Aber normalerweise hat ein Kunde, der Shell-Skripts extern entwickeln läßt, keine Ahnung von der Sache, sonst würde er es selbst machen. Da kommt kein: "Shell XY ist unerwünscht." Wenn in einem Laden so eine Einstellung vorherrscht, dann programmieren die ihre Skripts auch selbst so, wie die das haben wollen, die ideologischen Ansprüche liegen wohl hoch.

Aber selbst, wenn wir annehmen, daß der Kunde sagt: "Ich will ein portables Shell-Skript, aber bash will ich nicht", dann soll er sagen, welche Shell er will. Und dann geht das Problem los. Nehmen wir an, er will ein Korn-Shell-Skript - es gibt zig Korn-Shell-Varianten. Dann muß er eine benennen, meinetwegen die Solaris-Korn-Shell. Dann entwickele ich sein Skript für die Solaris-Korn-Shell. Natürlich schöpfe ich dann auch alle Features dieser Shell aus, soweit sie benötigt werden. Wir reden hier nicht von einem Drei-Zeilen-Skript, wenn man externes Personal braucht, ist das Skript ja wohl schon anspruchsvoller.

Anschließend soll der Kunde eben sehen, wie er das Skript auf seinen verschiedenen Plattformen ans Laufen bekommt. Wenn die FreeBSD-Korn-Shell nicht in allen verwendeten Funktionen mit der Solaris-Korn-Shell kompatibel ist, dann ist das sein Problem. Er hat seine Wunsch-Shell benannt und das Ergebnis für seine Wunsch-Shell auch bekommen. Aber ihm kann geholfen werden: Wenn er irgendwo den Source für die Solaris-Korn-Shell auftreibt, portiere ich sie ihm auf FreeBSD. Das kostet natürlich extra. Jetzt hat der Kunde verloren, oder eher der, welcher die Kostenexplosion vor seinem Vorgesetzten vertreten muß.
 
p.h. schrieb:
Hör mal - selbst nach EOD -, verarschen lassen muß ich mich von dir nicht.
Hehe, irgendwie musste ich dich ja aus der Reserve locken :)
Was steht eigentlich in Post #10, Punkt c? Wenn du den Punkt nicht verstanden hättest, könntest du nachfragen, so gehe ich davon aus, daß du dir unangenehme Argumente bewußt unter den Tisch fallen läßt, damit du nicht darauf eingehen mußt. Du bist bisher jedenfalls noch auf kein Argument eingegangen, sondern ignorierst sie einfach.
/usr/bin/env ist nunmal kein Argument. Das letzte Mal als ich nachgesehen habe, kann env(1) naemlich keine fehlenden Anwendungen nachinstallieren. Aber das willst du anscheinend nicht verstehen. Es soll Systeme geben, auf denen deinen Skripte vielleicht laufen sollen, aber die du nicht administrierst. Damit buerdest du dann dem entsprechenden Admin auf, yet-another-shell zu installieren. Die Verbreitung von Perl und C sollten die Verbreitung von bash um einiges ueberschreiten.

Du ignorierst also das out-of-the-box-Argument, und wirfst mir vor, ich wuerde auf deine Argumente nicht eingehen? Sehr witzig ...

Diese Behauptung ist schlichtweg falsch und ich möchte dich bitten, sowas zu unterlassen. Mein Einwand mit /bin/sh bezog sich nicht auf perl/python/ruby/C, sondern auf den darauffolgenden Satz sowie auf den Post von Maledictus. Tja, nicht nur lesen, sondern auch zuordnen muß man können.
Und genau wo siehst du im nachfolgenden Satz eine Empfehlung fuer sh(1)? Kann sein, dass ich blind bin, aber ich sehe hier keine Empfehlung:
MrFixit schrieb:
Und warum deklarierst du es als bash Skript, obwohl es auch mit der sh tun wuerde?
Ich hatte fuer Plattformunabhaengigkeit Perl/C empfohlen, Maledictus die /bin/sh zum allg. Shell-programmieren. Dein Posting hat das dann wunderbar zusammengemischt.
Demnach wäre es auch ziemlich dumm, daß perl/python/ruby/C nicht auf allen *nix-Systemen installiert sind. Ein C-Compiler wohl noch am ehesten, aber auch nicht überall. Nur ist das Argument völlig egal, das stand in Post #10, Punkt a.
Du gehst davon aus, dass du der Admins des System bist und deine eigenen Skripte laufen. Das ist nicht immer der Fall. Warum denkst du, dass autoconf "bin/sh-Skripte" ausspuckt und nicht bash-Skripte? Soll sich jeder die bash installieren? Sicher waere es einfach, sogar um vieles einfacher, aber es sicher viele Systeme, auf denen eine aktuelle bash sich nicht uebersetzen laesst.
Vor allem mal solltest du nicht ständig deine eigenen Argumente widerlegen, was ist das denn für eine Art?
Es ist schlechter Diskussionstil, den Stil des gegenueber zu kritisieren. Dann werf mir doch gleich vor, dass ich scheisse aussehe, und deshalb nichts zu sagen habe. Desweiteren hast du es noch immer nicht fuer noetig gehalten mir aufzuzueigen, wo ich meine eigenen Argumente widerlege. Ich zaehle sie nochmal auf:

1. Lieber Perl o.ä. verwenden, als komplexe sh-Skripte schreiben (been there, done that).
2. Solange man #!/bin/sh hinschreiben kann, und das Skript auch mit einer "normalen" sh laeuft, sollte man das tun. Anderfalls muessten viele Leute die Shebang-Zeile manuell aendern. Das Argument mit env(1) zaehlt nicht, 90% aller sh/perl/foo-Skripte haben den Pfad zum Interpreter hard kodiert.
 
Zurück
Oben