kaputtnik
Anmeldungsdatum: 31. Dezember 2007
Beiträge: 9245
|
RapaNui schrieb: Hallo Wiki-Team,
Servus ☺ sorry für das späte Melden...
ich würde gerne die Tipps und Tricks ergänzen, dazu ein paar Fragen:
Muss der Artikel dafür in die Baustelle?
Nein, ich denke nicht. Für ein C&p muss man keinen Artikel in die Baustelle schieben 😉 Ist die unten angewendete Formatierung so in Ordnung, oder müssen die Veranschaulichungen auch in die Vorlage Befehl?
Da solche Verschachtelungen eigentlich nur in Skriptdateien vorkommen, würde ich den Codeblock "bash" Vorschlagen:
| # printf übergibt 2 Zeilen die mittels read gezählt werden
Zaehler=0
printf "%s\n" foo bar | while read -r line
do
Zaehler=$((Zaehler+1))
echo "Zaehler in der Schleife: $Zaehler" # Ausgabe 2
done
echo "Zaehler nach der Schleife: $Zaehler" # Ausgabe 0
|
Ist der Text so verständlich oder bestehen Änderungswünsche?
Ich bin jetzt nicht so der Skript-Jünger, aber IMHO ok ☺ Wenn das so ok ist, dann sollte Shell/Tipps und Tricks (Abschnitt „Sinnlose-Verwendung-von-Backticks“) komplexerer Befehl auch auf diese Vorgehensweise abgeändert werden.
Jo, sollte vllt wirklich mit #!code bash formatiert werden. Kannst Du das in den anderen Artikeln ändern? Bei der Tabelle musst du ein Leerzeichen einbauen:
{{{#!vorlage Tabelle
<-2 rowclass="titel">[...]
}}}
Danke kaputtnik
|
RapaNui
Anmeldungsdatum: 16. Juli 2007
Beiträge: 1925
Wohnort: Penco / Chile
|
Vorlage geändert Tabelle bereinigt done
|
kaputtnik
Anmeldungsdatum: 31. Dezember 2007
Beiträge: 9245
|
RapaNui schrieb: ? Doch kein {{{#!code bash }}} ?
|
RapaNui
Anmeldungsdatum: 16. Juli 2007
Beiträge: 1925
Wohnort: Penco / Chile
|
Sorry, bin ein wenig übermüdet. Jetzt ja mit #!code bash
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Aus dem Artikel:
Das ist ein Spezialfall der sinnlosen Verwendung von Backticks (weiter unten). Häufig ist folgende (falsche) Verwendung zu sehen: | Kommando `echo $variable`
|
Die Backticks öffnen eine separate Shell, um das Kommando echo auszuführen.
Backticks sind generell veraltet, und sollen nicht benutzt, schon gar nicht unterrichtet werden. Ich habe also den Backticks den Garaus gemacht. Ob Backticks oder nicht - die Erklärung unten ist falsch. Backticks öffnen keine separate Shell, und auch echo ist kein separates Programm. Beweis: | ibmux:~ > alias bork="echo bork"
ibmux:~ > bork
bork
|
Ich definiere einen Alias namens bork, und bork ergibt bork. Soweit, so trivial. Nun die Behauptung: Ein alias wird nicht an die Subshell vererbt. Test:
| ibmux:~ > sh -c "bork"
sh: bork: not found
|
Scheint zu stimmen - die Subshell weiß nichts von bork.
Jetzt der Test: Wenn die Kommandosubstitution eine separate Shell öffnete, dann dürfte ja ein
kein bork bork liefern, sondern nur ein not found. Die Spannung steigt ...
bork bork
q.e.d.: Es wird keine Subshell gestartet. Jetzt frage ich mich: Wo kommt die Behauptung her, wer denkt sich sowas aus? Ich würde das Gerücht gerne weiter Richtung Quelle verfolgen, und dort bekämpfen. ☺ Allgemein möchte ich darauf hinweisen, dass man bitte nicht in einen Shellartikel schreibt, dass $(...) neu sei, und besser als Backticks, um dann konsequent Backticks im Artikel zu verwenden. Es ist kontraproduktiv wenn wir im Shellforum immer wieder von Backticks abraten, und jedes zweite Wikibeispiel Backticks verwendet. Offenbar sind die Wikischreiber und Forenbearbeiter fast disjunkte Mengen - dagegen kann man wohl wenig machen, außer selbst die Wikis zu bearbeiten.
|
cornix
Anmeldungsdatum: 9. März 2007
Beiträge: 4763
Wohnort: Ringenberg
|
@user unknown: Deine Empfehlungen im Bereich "Shell im Wiki", die beispielsweise die Darstellung von Befehlen mit ihren Optionen und Argumenten oder die Verwendung von Backticks angehen, sind nach meinem Kenntnisstand Konsens im Wiki. Das wurde auch mal festgehalten, habe aber nicht recherchiert, warum und wieso das entweder nicht ins Wiki gekommen ist oder gelöscht wurde, denn es ist einfacher es neu zu schreiben. Und zwar in einem eigenen Artikel, mit einer eigenen Diskussion, damit es nicht noch einmal verloren geht. 😉 Gute Nacht, cornix
|
Vain
Anmeldungsdatum: 12. April 2008
Beiträge: 2503
|
Servus, spricht etwas dagegen, diesen Abschnitt unter „Tricks“ mit aufzunehmen?
user unknown schrieb:
q.e.d.: Es wird keine Subshell gestartet. Jetzt frage ich mich: Wo kommt die Behauptung her, wer denkt sich sowas aus? Ich würde das Gerücht gerne weiter Richtung Quelle verfolgen, und dort bekämpfen. ☺
Doch, das ist eine Subshell. Siehe Handbuch:
Command substitution, commands grouped with parentheses, and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment, except that traps caught by the shell are reset to the values that the shell inherited from its parent at invocation.
Und folgendes Beispiel:
| #!/bin/bash
echo $(foo=1; echo hi)
echo $foo
|
Wäre es keine Subshell, wäre $foo hinterher noch definiert. Ist es aber nicht. ☺
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Vain schrieb: user unknown schrieb: q.e.d.: Es wird keine Subshell gestartet. Jetzt frage ich mich: Wo kommt die Behauptung her, wer denkt sich sowas aus? Ich würde das Gerücht gerne weiter Richtung Quelle verfolgen, und dort bekämpfen. ☺
Doch, das ist eine Subshell. Siehe Handbuch:
Command substitution, commands grouped with parentheses, and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment, except that traps caught by the shell are reset to the values that the shell inherited from its parent at invocation.
Und folgendes Beispiel:
| #!/bin/bash
echo $(foo=1; echo hi)
echo $foo
|
Wäre es keine Subshell, wäre $foo hinterher noch definiert. Ist es aber nicht. ☺
Interessant. Aber wieso wird das alias nicht vererbt - das ist doch keine Trap? Aus RapaNuis Text stößt mir noch folgendes auf:
In den meisten Shells wird jedes Kommando einer Pipe in einer separaten Shell (Sub-Shell) ausgeführt,
In einer Pipe ist ja nicht jedes Kommando auf eine Shell angewiesen, sondern kann ein ordinäres Programm sein. Da dies keine Shell benötigt wird es wohl auch nicht in einer neuen Shell gestartet - nicht?
(Ich weiß, useless use of cat) wc braucht hier ja keine Shell (und bekommt auch keine, oder? Ein neuer Prozess (ja, was ist das nun wieder?) ☺ Die Einrückung mit dem vorgezogenen 'Zaehler=' ist unsinnig - die korrigiere ich mal gleich. ☺
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Erledigt: Ein paar Einrückungen korrigiert, und code-bash statt Vorlage-Befehl für mehrzeiligen Code verwendet. Obwohl ich ein fundamental-Gläubiger der Kirche of 8er-Indentation bin habe ich ohne jede Diskussion die Einrückung bei 4 belassen wo sie 4 war, und sogar bei 2 wo sie 2 war (hört, hört!). Nein - ich beginne auch nachträglich keine Grundsatzdiskussion ☺ und es ist auch nicht so, dass man vorsichtig sein muss, wenn die Danaer Geschenke machen. Außerdem bin ich kein Danaer. Stattdessen beginne ich eine Grundsatzdiskussion: Dieser Artikel erfordert mehr Erfahrung im Umgang mit Linux und ist daher nur für fortgeschrittene Benutzer gedacht.
Das steht als Hinweismantra über dem Artikel wie ein Stickdecken bei Oma in der Küche 'eigener Herd - Goldes Wert'. Wir sind doch in erster Linie ein Anfängerforum. Der Artikel richtet sich auch nicht an Profis oder Fortgeschrittene - allenfalls als Schlamper wie mich, die jahrelang Zeuch benutzen was halt funktioniert, weil man wenige Dateien mit Zeilenumbruch hat und so. Aber es nichts dabei was annähernd so schwierig wäre wie ein Dreisatz oder das Lösen eines Gleichungssystems mit 2 Unbekanten - also irgendwie Realschulstoff 8. Klasse - kurz: Von 100 Erwachsenen dürfte das alles nur 10 überfordern. Als ich meinen ersten Rechner bekam habe ich 'help' eingetippt und bekam eine Liste gültiger Kommandos, und habe dann mit 'help attr' bis 'help z' durch alle Möglichkeiten durchgeblättert und alles ausprobiert. Der Artikel ist m.E. genau das: Eine Einsteiger- und Anfängerhilfe. Diese idiotische Assoziation "CLI=schwierig", die als unhinterfragbares Dogma immer wieder kolportiert wird sollten wir aktiv dementieren, wo immer sie auftaucht - rücksichtslos, unerbittlich, kompromisslos!
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29076
Wohnort: WW
|
Hallo, Fortgeschritten-Box raus +1 BTW: Einrücktiefe von 4 Leer ist nur bei Python dogmatisch. In der Shell bin zumindest ich auch flexibel. 😉 Gruß, noisefloor
|
Vain
Anmeldungsdatum: 12. April 2008
Beiträge: 2503
|
user unknown schrieb: Interessant. Aber wieso wird das alias nicht vererbt - das ist doch keine Trap?
Das wird vererbt:
Jetzt der Test: Wenn die Kommandosubstitution eine separate Shell öffnete, dann dürfte ja ein
kein bork bork liefern, sondern nur ein not found. Die Spannung steigt ...
bork bork
In den Subshells innerhalb von $(...) und den Backticks gibt es den/das Alias also noch. Nach meinem Verständnis ist aber das Folgende keine Subshell, sondern ein ganz neuer Prozess, der nur die Umgebungsvariablen mitnimmt:
| ibmux:~ > sh -c "bork"
sh: bork: not found
|
So. An der Stelle kenne ich jetzt aber auch das exakte Vorgehen nicht, wie eine Subshell erzeugt wird (fork ? Ein neuer Thread? Wie was wo?) und wie der Unterschied zwischen Subshell und neuem Prozess im Detail aussieht. Wäre mal interessant, das herauszufinden. ☺
|
barcc
Anmeldungsdatum: 13. Juli 2007
Beiträge: 696
Wohnort: Dortmund
|
Eine Subshell kann ein neuer Prozess sein, muss aber nicht.
( echo $PPID $$; ps -o ppid,pid,cmd )
liefert in der bash und der dash:
barcc:~$ bash -c '( echo $PPID $$; ps -o ppid,pid,cmd )'
3199 6780
PPID PID CMD
2568 3199 bash
3199 6780 bash -c ( echo $PPID $$; ps -o ppid,pid,cmd )
6780 6781 bash -c ( echo $PPID $$; ps -o ppid,pid,cmd )
6781 6782 ps -o ppid,pid,cmd
barcc:~$ dash -c '( echo $PPID $$; ps -o ppid,pid,cmd )'
3199 6788
PPID PID CMD
2568 3199 bash
3199 6788 dash -c ( echo $PPID $$; ps -o ppid,pid,cmd )
6788 6789 ps -o ppid,pid,cmd
Die Bash braucht einen neuen Prozess für die Subshell, die Dash nicht. Für eine Pipeline ist das ähnlich:
barcc:~$ bash -c 'echo $PPID $$ | { cat; echo $PPID $$; ps -o ppid,pid,cmd; }'
3199 6949
3199 6949
PPID PID CMD
2568 3199 bash
3199 6949 bash -c echo $PPID $$ | { cat; echo $PPID $$; ps -o ppid,pid,cmd; }
6949 6951 bash -c echo $PPID $$ | { cat; echo $PPID $$; ps -o ppid,pid,cmd; }
6951 6953 ps -o ppid,pid,cmd
barcc:~$ dash -c 'echo $PPID $$ | { cat; echo $PPID $$; ps -o ppid,pid,cmd; }'
3199 6956
3199 6956
PPID PID CMD
2568 3199 bash
3199 6956 dash -c echo $PPID $$ | { cat; echo $PPID $$; ps -o ppid,pid,cmd; }
6956 6958 ps -o ppid,pid,cmd Führt man den befehl
echo $$ $BASHPID >&2 | /bin/ps -o ppid,pid,cmd $BASHPID >&2 in der bash aus, erhält man:
3199 7034
PPID PID CMD
3199 7035 ps -o ppid,pid,cmd 7035
Anscheinend haben hier die Subshell ($BASHPID) und /bin/ps die gleiche Prozessnummer (7035). Zusammenfassend beschreibt der Begriff "Subshell" einfach die Umgebung, die ein Befehl/Programm vorfindet.
Insofern ist der Satz In den meisten Shells wird jedes Kommando einer Pipe in einer separaten Shell (Sub-Shell) ausgeführt,
schon richtig.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
barcc schrieb: Wie schön, noch ein Forschergeist! ☺
3199 7034
PPID PID CMD
3199 7035 ps -o ppid,pid,cmd 7035
Anscheinend haben hier die Subshell ($BASHPID) und /bin/ps die gleiche Prozessnummer (7035). Zusammenfassend beschreibt der Begriff "Subshell" einfach die Umgebung, die ein Befehl/Programm vorfindet.
Insofern ist der Satz In den meisten Shells wird jedes Kommando einer Pipe in einer separaten Shell (Sub-Shell) ausgeführt,
schon richtig.
Separat heißt aber doch abgesondert, getrennt, eigen - was ist denn dann eigen und abgesondert?
|
barcc
Anmeldungsdatum: 13. Juli 2007
Beiträge: 696
Wohnort: Dortmund
|
user unknown schrieb: Zusammenfassend beschreibt der Begriff "Subshell" einfach die Umgebung, die ein Befehl/Programm vorfindet.
Insofern ist der Satz In den meisten Shells wird jedes Kommando einer Pipe in einer separaten Shell (Sub-Shell) ausgeführt,
schon richtig.
Separat heißt aber doch abgesondert, getrennt, eigen - was ist denn dann eigen und abgesondert?
Änderungen, die in einer Subshell gemacht werden, wirken sich nicht auf die aufrufende Shell aus. Das ist schon getrennt, oder? Beispiel
(cd ..; pwd); pwd
(foo=bar; echo x${foo}y); echo x${foo}y
(set -x; echo foo); echo foo und genauso für alle anderen Konstrukte, wo Subshells erzeugt werden wie z.B . ${} , Pipes, Backticks, &
|
Vain
Anmeldungsdatum: 12. April 2008
Beiträge: 2503
|
Kurz zwischendurch: Da kein Widerspruch kam, hab’ ich jetzt „Bash-Arrays zum Speichern von Befehlen“ in den Artikel mit aufgenommen.
|