Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Wrapper-Shell-Skripte (was: [flnews] Schwierigkeiten mit dem externen Editor)

1 view
Skip to first unread message

Helmut Waitzmann

unread,
May 14, 2023, 4:14:15 PM5/14/23
to
Michael Bäuerle <michael....@gmx.net> in der Gruppe
«de.comm.software.newsreader»:

[Es geht um ein Wrapper‐Skript, das vom newsreader «flnews»
gestartet werden soll, um einen externen Editor – hier
«/usr/pkg/bin/xnedit» – zu starten.]

> Ich hatte gerade folgendes Script getestet:
>
> -----------------------------------------------------------------------
> #! /bin/sh
>
> /usr/pkg/bin/xnedit -geometry 70x50+0+85 -- $@
> -----------------------------------------------------------------------
>
> Das hat auch funktioniert.
>

Aber bitte in Shell‐Skripten «$@» immer in Anführungszeichen
setzen – es sei denn, man will, dass die Werte des Parameters «@»
nach dem Auswerten noch überall da zerbrochen werden, wo sie ein
in der Shell‐Variablen «IFS» enthaltenes Zeichen enthalten, und,
dass anschließend auch noch in den Bruchstücken zufällig
enthaltene (aber hier nicht so gemeinte) Dateinamensmuster («?»,
«*», «[…]») durch entsprechende gefundene Dateinamen ersetzt
werden.

Des weiteren empfiehlt es sich, bei Wrapper‐Shell‐Skripten das
gewrappte Programm, das am Ende gestartet werden soll, mittels
«exec» zu starten, damit es in der Prozess‐Baum‐Struktur den
Platz des Wrapper‐Skripts einnimmt und nicht etwa einen weiteren
Prozess erzeugt.

Beispielsweise könnte es ja sein, dass «flnews» in gewissen
Fällen gewisse Signale (beispielsweise ein Hangup‐, Interrupt‐
oder Stop‐Signal) an den von ihm gestarteten Editor schicken
möchte.  Würde das Wrapper‐Skript einen eigenen Prozess
spendieren, würden diese Signale nur das Wrapper‐Skript statt den
von ihm gestarten Editor erreichen.  (Dass Signale an einen
Prozess auch dessen Prozess‐Kinder erreichen, ist ein Märchen,
das sich leider hartnäckig hält.)


Die erste Zeile


#! /bin/sh

in einer lesbaren und ausführbaren Shell‐Skript‐Datei ist für den
Shell «/bin/sh», der die Datei lesen und interpretieren wird, nur
ein Kommentar (denn sie beginnt mit einem «#»).  Ihre
Sonderbedeutung erhält sie erst von den in der
Laufzeitfunktionsbibliothek enthaltenen Funktionen der
«exec»‐Familie:

Wenn so eine Funktion eine Datei, die kein echtes
(Maschinen‐)Programm ist, als Programm zu starten versucht,
scheitert das zunächst, weil ein Shell‐Skript kein
Maschinen‐Programm ist.  Die Funktion unternimmt dann einen
zweiten Versuch:  Sie öffnet das Shell‐Skript zum Lesen und
schaut nach, ob die erste Zeile mit der Zeichenfolge «#!»
beginnt.  Ist das der Fall, liest sie den Rest der Zeile.  Sie
erwartet in dieser Zeile den Namen eines Shells und optional noch
einen Parameter.  Dann startet sie den Shell und übergibt ihm den
optionalen Parameter (falls vorhanden) und den Namen des
Shell‐Skripts als (weiteren) Parameter.

Der gestartete Shell liest das Shell‐Skript und arbeitet den in
ihr stehenden Text als Shell‐Kommandos ab.

Sollte der Dateiname dieses Shell‐Skripts mit einem Minuszeichen
(«-») oder einem Pluszeichen («+») beginnen, würde der Shell den
Namen nicht als Dateinamen sondern als Shell‐Aufruf‐Option
missverstehen.  Um das zu verhindern, empfiehlt es sich, in die
«#!»‐Zeile als optionalen Parameter den Parameter «-» (ein
einzelnes Minuszeichen) zu stellen.  Er sorgt dafür, dass die
Funktion aus der Laufzeitbibliothek dem Shell als ersten
Parameter «-» und erst als zweiten Parameter den Namen des
Shell‐Skripts mitgibt.  Der Parameter «-» teilt dem Shell mit,
dass alle weiteren Parameter keine Shell‐Optionsparameter sind,
auch wenn sie mit einem Minus‐ oder Plus‐Zeichen beginnen
sollten.

In der Summe würde ich das Shell‐Skript so formulieren:


#! /bin/sh -
exec /usr/pkg/bin/xnedit -geometry 70x50+0+85 -- "$@"


Wenn «flnews» es dann beispielsweise mit dem Parameter
«ein Dateiname» startet, bewirkt das, dass «/bin/sh» mit den
Parametern «-», «das_Shell‐Skript» und «ein Dateiname» gestartet
wird.  «/bin/sh» liest dann das Shell‐Skript ein, ignoriert die
Kommentarzeile und interpretiert die zweite Zeile, nachdem er den
Parameter «@» durch den übergebenen Parameter «ein Dateiname»
ersetzt hat, so, als hätte man die Kommandozeile

exec /usr/pkg/bin/xnedit -geometry 70x50+0+85 -- \
'ein Dateiname'

ins Shell‐Skript geschrieben.


Das hat denselben Effekt, als hätte man «flnews» mitteilen
können, das Programm «/usr/pkg/bin/xnedit» mit (neben dem
Dateinamen noch) den zusätzlichen Parametern «-geometry»,
«70x50+0+85», «--» zu starten:  Das Shell‐Skript bewirkt in der
Summe nur eine Hinzunahme der Parameter «-geometry», «70x50+0+85»
und «--».  Es entsteht kein weiterer Prozess, und es wird auch
nichts am übergebenen Dateinamen herumgefummelt – genau das, was
hier gewünscht ist.


Merksätze für Wrapper‐Skripte:


Man verwendet zum Weiterreichen der Parameter, die das
Wrapper‐Skript vom Aufrufer erhalten hat, den Parameter «@»,
nicht etwa «*», und man verwendet ihn in Anführungszeichen, also
«"$@"», damit die vom Aufrufer dem Wrapper‐Skript übergebenen
Parameter unverfälscht an das gewrappte Programm weitergereicht
werden.

Das gewrappte Programm, das vom Wrapper‐Skript schließlich
gestartet werden soll, startet man mit dem Shell‐Kommando «exec»,
damit der Wrapper‐Skript‐Prozess keinen neuen Prozess erzeugt, um
das gewrappte Programm zu starten, sondern jetzt das gewrappte
Programm selber ausführt.  So sorgt man dafür, dass das gewrappte
Programm im Prozess‐Baum genau dort steht, wo der Aufrufer (hier:
«flnews») das Wrapper‐Skript hingestellt hatte.

Mein Vorschlag wäre, Wrapper‐Shell‐Skripte in der Gruppe
«de.comp.os.unix.shell» zu diskutieren.  Deshalb mache ich 'mal
ein Crossposting mit Followup‐To dorthin.  Bei Bedarf bitte
seinerseits anpassen.
--
Hat man erst verstanden, wie Unix funktioniert, ist auch
das Shell-Handbuch kein Buch mit sieben Siegeln mehr.

Peter J. Holzer

unread,
May 14, 2023, 4:50:37 PM5/14/23
to
On 2023-05-14 20:09, Helmut Waitzmann <nn.th...@xoxy.net> wrote:
> Michael Bäuerle <michael....@gmx.net> in der Gruppe
> «de.comm.software.newsreader»:
>
> [Es geht um ein Wrapper‐Skript, das vom newsreader «flnews»
> gestartet werden soll, um einen externen Editor – hier
> «/usr/pkg/bin/xnedit» – zu starten.]
>
>> Ich hatte gerade folgendes Script getestet:
>>
>> -----------------------------------------------------------------------
>> #! /bin/sh
>>
>> /usr/pkg/bin/xnedit -geometry 70x50+0+85 -- $@
>> -----------------------------------------------------------------------
>>
>> Das hat auch funktioniert.
>>
>
> Aber bitte in Shell‐Skripten «$@» immer in Anführungszeichen
> setzen

Prinzipiell ja. Bei Michael als Autor von flnews kann man natürlich
davon ausgehen, dass er weiß, welche Filenamen sein Programm erzeugt,
aber er gibt damit ein schlechtes Beispiel.


> Die erste Zeile
>
>
> #! /bin/sh
>
> in einer lesbaren und ausführbaren Shell‐Skript‐Datei ist für den
> Shell «/bin/sh», der die Datei lesen und interpretieren wird, nur
> ein Kommentar (denn sie beginnt mit einem «#»).  Ihre
> Sonderbedeutung erhält sie erst von den in der
> Laufzeitfunktionsbibliothek enthaltenen Funktionen der
> «exec»‐Familie:

Das ist seit ca. 30 Jahren nicht mehr der Fall. In Linux (und allen
anderen Unixen, mit denen ich ab Mitte der 1990er-Jahre zu tun hatte),
wird #! vom *Kernel* interpretiert, nicht von der libc-Funktion.

hp

Michael Bäuerle

unread,
May 15, 2023, 7:08:06 AM5/15/23
to
Helmut Waitzmann wrote:
> Michael Bäuerle <michael....@gmx.net> in der Gruppe «de.comm.software.newsreader»:
> >
> [Es geht um ein Wrapper‐Skript, das vom newsreader «flnews» gestartet
> werden soll, um einen externen Editor – hier «/usr/pkg/bin/xnedit» – zu
> starten.]
>
> > Ich hatte gerade folgendes Script getestet:
> > -----------------------------------------------------------------------
> > #! /bin/sh
> >
> > /usr/pkg/bin/xnedit -geometry 70x50+0+85 -- $@
> > -----------------------------------------------------------------------
> >
> > Das hat auch funktioniert.
>
> Aber bitte in Shell‐Skripten «$@» immer in Anführungszeichen setzen – es
> sei denn, man will, dass die Werte des Parameters «@» nach dem Auswerten
> noch überall da zerbrochen werden, wo sie ein in der Shell‐Variablen
> «IFS» enthaltenes Zeichen enthalten, und, dass anschließend auch noch in
> den Bruchstücken zufällig enthaltene (aber hier nicht so gemeinte)
> Dateinamensmuster («?», «*», «[…]») durch entsprechende gefundene
> Dateinamen ersetzt werden.

Letzteres kann hier nicht passieren, aber "IFS" könnte ein Problem sein.
Ich habe Anführungszeichen hinzugefügt.

> Des weiteren empfiehlt es sich, bei Wrapper‐Shell‐Skripten das gewrappte
> Programm, das am Ende gestartet werden soll, mittels «exec» zu starten,
> damit es in der Prozess‐Baum‐Struktur den Platz des Wrapper‐Skripts
> einnimmt und nicht etwa einen weiteren Prozess erzeugt.
>
> Beispielsweise könnte es ja sein, dass «flnews» in gewissen Fällen
> gewisse Signale (beispielsweise ein Hangup‐, Interrupt‐ oder
> Stop‐Signal) an den von ihm gestarteten Editor schicken möchte.  Würde
> das Wrapper‐Skript einen eigenen Prozess spendieren, würden diese
> Signale nur das Wrapper‐Skript statt den von ihm gestarten Editor
> erreichen.  (Dass Signale an einen Prozess auch dessen Prozess‐Kinder
> erreichen, ist ein Märchen, das sich leider hartnäckig hält.)

Ja, "exec" wird hier benötigt.
Danke für deine Hinweise.

Helmut Waitzmann

unread,
May 15, 2023, 5:14:38 PM5/15/23
to
Michael Bäuerle <michael....@stz-e.de>:
> Helmut Waitzmann wrote:
>> Michael Bäuerle <michael....@gmx.net> in der Gruppe
>> «de.comm.software.newsreader»:
>>>
>> [Es geht um ein Wrapper‐Skript, das vom newsreader «flnews»
>> gestartet werden soll, um einen externen Editor – hier
>> «/usr/pkg/bin/xnedit» – zu starten.]
>>
>>> Ich hatte gerade folgendes Script getestet:
>>> -----------------------------------------------------------------------
>>> #! /bin/sh
>>>
>>> /usr/pkg/bin/xnedit -geometry 70x50+0+85 -- $@
>>> -----------------------------------------------------------------------
>>>
>>> Das hat auch funktioniert.
>>>
>>
>> Aber bitte in Shell‐Skripten «$@» immer in Anführungszeichen
>> setzen – es sei denn, man will, dass die Werte des Parameters
>> «@» nach dem Auswerten noch überall da zerbrochen werden, wo
>> sie ein in der Shell‐Variablen «IFS» enthaltenes Zeichen
>> enthalten, und, dass anschließend auch noch in den Bruchstücken
>> zufällig enthaltene (aber hier nicht so gemeinte)
>> Dateinamensmuster («?», «*», «[…]») durch entsprechende
>> gefundene Dateinamen ersetzt werden.
>
> Letzteres kann hier nicht passieren,
>

Du als Entwickler von «flnews» kannst das natürlich
sicherstellen, und du kannst diese Zusicherung auch in die
Dokumentation schreiben.  Nur, wozu?

Es könnte einerseits sein, dass die Zusicherung dir eines Tages
zum Klotz am Bein würde, beispielsweise, weil du den Ort der
Datei vom Inhalt der vom Anwender eingestellten
Umgebungsvariablen «TMPDIR» bestimmen lassen möchtest; und
andererseits bringt sie dem Anwender nichts Essentielles:  «"$@"»
ist genau dafür da, Ärger zu vermeiden, egal, ob diese
Zusicherung gegeben wird oder nicht.

Michael Uplawski

unread,
May 16, 2023, 1:16:12 AM5/16/23
to
Helmut Waitzmann hat geschrieben:


> Merksätze für Wrapper‐Skripte:

Ich musste früher aufstehen, konnte aber jetzt Punkt für Punkt alles
nachvollziehen, inklusive der Kritik von Peter Holzer. Schreibe doch bitte
alle man-pages nochmal neu. ;)

„Wissen wo's steht” funktioniert mit mir nicht mehr. Solche Postings dagegen
oft.

Herzlichen Dank
--
Es ist an der Zeit

Michael Bäuerle

unread,
May 17, 2023, 5:08:07 AM5/17/23
to
Helmut Waitzmann wrote:
> Michael Bäuerle <michael....@stz-e.de>:
> > Helmut Waitzmann wrote:
> > >
> > > [...]
> > > Aber bitte in Shell‐Skripten «$@» immer in Anführungszeichen setzen – es
> > > sei denn, man will, dass die Werte des Parameters «@» nach dem Auswerten
> > > noch überall da zerbrochen werden, wo sie ein in der Shell‐Variablen
> > > «IFS» enthaltenes Zeichen enthalten, und, dass anschließend auch noch in
> > > den Bruchstücken zufällig enthaltene (aber hier nicht so gemeinte)
> > > Dateinamensmuster («?», «*», «[…]») durch entsprechende gefundene
> > > Dateinamen ersetzt werden.
> >
> > Letzteres kann hier nicht passieren,
>
> Du als Entwickler von «flnews» kannst das natürlich sicherstellen, und
> du kannst diese Zusicherung auch in die Dokumentation schreiben.  Nur,
> wozu?
>
> Es könnte einerseits sein, dass die Zusicherung dir eines Tages zum
> Klotz am Bein würde, beispielsweise, weil du den Ort der Datei vom
> Inhalt der vom Anwender eingestellten Umgebungsvariablen «TMPDIR»
> bestimmen lassen möchtest;

Ich meinte den Dateinamen, TMPDIR wird unterstützt und der Pfad kann
damit problematische Zeichen enthalten. Die Anführungszeichen werden
daher benötigt.

> und andererseits bringt sie dem Anwender
> nichts Essentielles:  «"$@"» ist genau dafür da, Ärger zu vermeiden,
> egal, ob diese Zusicherung gegeben wird oder nicht.

Ich stimme deiner Argumentation zu (auch bezüglich "exec" und "--").
Das Script hatte ich ja bereits geändert.
0 new messages