staging.inyokaproject.org

Shell/Tipps_und_Tricks

Status: Gelöst | Ubuntu-Version: Ubuntu
Antworten |
Dieses Thema ist die Diskussion des Artikels Shell/Tipps_und_Tricks.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17432

und genauso für alle anderen Konstrukte, wo Subshells erzeugt werden wie z.B . ${}, Pipes, Backticks, &

Ok. Also separate Subshell - da muß man sich auch auf einem Uraltrechner keine Gedanken um Speicherplatz und Initialisierungsdauer machen - separate Subshell bedeutet nur, aber immerhin - dass dort gemachte Zuweisungen im aufrufenden Kontext nicht zur Verfügung stehen.

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2503

Nochmal zum „bork“-Beispiel und dem Unterschied der beiden Aufrufe.

So, wie ich den Quellcode der Dash bisher „verstehe“ (sagen wir besser: „erahne“ – so viele Gotos habe ich schon lange nicht mehr gesehen), ist der Unterschied zwischen deinem „sh -c mein_alias“ und „echo $(mein_alias)“ folgender:

  1. sh -c mein_alias“ startet einen neuen Prozess mit einem neuen Programm. Das heißt, erst „fork()“, dann im Kind „exec*()“. Durch das „exec*()“ verlierst du natürlich Dinge wie Aliases und Funktionen, denn das sind ja nur innerhalb der aufrufenden Shell definierte Konstrukte. Durch das „exec*()“ fliegt das alles über Bord, der Speicher des neuen Prozesses ist „leer“. Lediglich Grundlegendes wie die Umgebungsvariablen bleiben erhalten. Dieses Fork-Exec-Paar macht deine Shell im Terminal und für die sieht das alles wie ein ganz normaler Aufruf aus. Da könnte auch „ls“ stehen.

  2. echo $(mein_alias)“ macht erst einmal nur einen „fork()“ und in diesem Fork läuft dann die Subshell – unabhängig davon, was diese Subshell im nächsten Moment ausführen wird. Dadurch bleiben natürlich die Variablen, aber eben auch Aliases und so weiter erhalten, da durch den Fork nur eine Kopie des Prozesses erstellt wird und nichts weiter. Die dann ausführende Subshell sieht als Befehl dann „mein_alias“ und kann das auch korrekt als Alias erkennen und ausführen. Zack.

So käme das doch ganz gut hin, oder?

Und ich finde, an folgendem Beispiel sieht man das auch etwas schöner:

1
2
pstree -p
echo "$(pstree -p; echo hi)"

(Das „echo“ ist dazu da, damit die Shell nicht merkt: „Oh, da kommt ja nur ein Programmaufruf, na dann kann ich auch nur „exec*()“ machen, ohne für den Befehl nochmal zu forken.)

Ob ich das jetzt mit Dash oder Bash aufrufe, der erste Teilbaum sieht so aus:

...---dash(2433)---pstree(2435)

und der zweite so:

...---dash(2433)---dash(2436)---pstree(2437)

In der Hoffnung, es weder verfriemelt noch zusätzliche Verwirrung gestiftet zu haben. ☺

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17432

Vain schrieb:

(Das „echo“ ist dazu da, damit die Shell nicht merkt: „Oh, da kommt ja nur ein Programmaufruf, na dann kann ich auch nur „exec*()“ machen, ohne für den Befehl nochmal zu forken.)

Ja, ja. Das wäre aber für eine Aussage der Kategorie 'immer' eben auch interessant - ob eben nicht immer, sondern nur wenn da mit (foo1; bar2) operiert wird, geforkt wird. ☺

Btw.: Ist es eigentlich normal, wenn console-kit 63x im pstree auftaucht?

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2503

user unknown schrieb:

Vain schrieb:

(Das „echo“ ist dazu da, damit die Shell nicht merkt: „Oh, da kommt ja nur ein Programmaufruf, na dann kann ich auch nur „exec*()“ machen, ohne für den Befehl nochmal zu forken.)

Ja, ja. Das wäre aber für eine Aussage der Kategorie 'immer' eben auch interessant - ob eben nicht immer, sondern nur wenn da mit (foo1; bar2) operiert wird, geforkt wird. ☺

Stimmt. Hm.

Btw.: Ist es eigentlich normal, wenn console-kit 63x im pstree auftaucht?

Wenn du den Kram nutzt, dann ja. Bei den „großen“ Desktop Environments kommst du da wohl nicht drumherum. Das sollten aber eigentlich nur Threads sein und keine 63 Prozesse, also „halb so schlimm“. 😉

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17432

Wenn du den Kram nutzt, dann ja.

Explizit nutzt man das ja nicht, und wann man es implizit nutzt ist kaum feststellbar. Unser Wiki, Wikipedia.de und ~.en liefern keine oder spärlichste Informationen, man liefert nichts, nur in Synaptic finde ich

ConsoleKit is a system daemon for tracking what users are logged into the system and how they interact with the computer (e.g. which keyboard and mouse they use).

It provides asynchronous notification via the system message bus.

This package provides the system daemon and tools to interact with it.

Nachdem ich das gelesen habe weiss ich zumindest, dass ich weiss, dass ich nichts weiss. ☺ Klingt nicht, als könne man es eben mal über Bord kippen.

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2503

Details über ConsoleKit hab ich im Web auch nie gefunden, ich weiß aber, dass das Teil noch vor ein paar Monaten unerlässlich war, sobald du ein Desktop Environment mit Auto-Mounting oder ähnlichem hast (namentlich vorallem GNOME oder Xfce, pcmanfm von LXDE hat das auch so gemacht). Sprich, USB-Stick anstecken, Dateimanager öffnen, Icon des Sticks anklicken und dann ist der Stick gemountet. Sowas. Oder ein Knopf zum Herunterfahren des Rechners wurde häufig auch damit realisiert. Im Endeffekt ging es also um die Vergabe von Berechtigungen für bestimmte Aktionen und mir kam das wie ein viel zu kompliziert geratenes sudo vor.

Zu dem Framework gehörte auch noch PolicyKit und/oder PolKit und lange Zeit auch HAL (was später wegfiel). Mir ging das irgendwann auf die Nerven, weil der ganze Kram extrem unübersichtlich ist und es häufig Konfigurationsprobleme gab (durfte auf nach einem Update keinen Stick mehr mounten o.ä.). Es war sehr schlecht dokumentiert und in den Foren wusste auch keiner so richtig Bescheid. Lösungen, die bei Person A funktioniert haben, hatten bei Person B gar keinen Effekt. Da hab ich’s über Bord gekippt, ja – aber so Dinge wie USB-Sticks mounten mache ich seitdem auch wieder an der Shell und nicht über einen Dateimanager. So schwer ist das nun auch nicht und vor allem ist es robust und funktioniert.

Ich weiß aber nicht, wie die Situation heute aussieht. Da gab es viele Änderungen in letzter Zeit, die ich mangels Bedarf nicht so recht verfolgt habe. Aber wenn du die ganzen *Kits überhaupt loswerden kannst, dann nur mit der neuesten Software. Wobei zum Beispiel auch Xfce 4.8 zumindest in Arch Linux immernoch von PolKit abhängt… Was mit GNOME 3 sein wird, keine Ahnung.

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2503

Nachdem ich deinen Link von hier drüben (namentlich Eintrag 50 in Greg's Wiki) nochmal gelesen habe, ist mir klar geworden, dass meine Idee mit den Arrays zum Speichern von Befehlen Mumpitz ist. Warum ich nicht gleich auf Funktionen gekommen bin, ist mir gerade auch nicht klar.

Den neuen Abschnitt hab’ ich daher auf die Verwendung von Funktionen hin umgebaut.

Relationalist

Anmeldungsdatum:
17. Juni 2008

Beiträge: 1131

Ich schlage unter "Tipps und Tricks" eine Anleitung zur Verwendung der Kommandozeile zur Stapelverarbeitung vor. Dies nämlich scheint mir eine der sehr praktischen Anwendungen der Konsole zu sein, die nicht vollständig durch die einzelnen und je anderen GUI-Lösungen ersetzt wird.

Eine Zeile mit for ... do BEFEHL würde vielleicht genügen. Ich schreibe das nicht einfach mit meiner Lösung, die ich bei ffmpeg oder ImageMagick verwende, in den Artikel rein, da ich nicht weiß, wie universell sie funktioniert.

noisefloor Team-Icon

Ehemaliger
Avatar von noisefloor

Anmeldungsdatum:
6. Juni 2006

Beiträge: 28316

Hallo,

Eine Zeile mit for ... do BEFEHL würde vielleicht genügen.

Solange du das done; nicht vergisst 😉. Kannst du gerne hinzufügen. Im Artikel Audiodateien umwandeln wird das auch mehrfach verwendet.

Gruß, noisefloor

wxpte

Avatar von wxpte

Anmeldungsdatum:
20. Januar 2007

Beiträge: 1004

Aus dem Wiki:

Regulärer Ausdruck und .*

(weitergehende Informationen gibt es unter grep)

.* könnte man auch umschreiben mit "alles oder nichts". Das ist der reguläre Ausdruck, der immer wahr ist.

. ist das Jokerzeichen, steht also für irgendein Zeichen.

  • steht für kein Mal oder beliebig oft.

Ein beliebiges Zeichen, kein Mal oder beliebig oft, trifft auf alles zu. Wenn statt des * ein + verwendet wird, ergibt es Sinn. Das + steht für wenigstens ein Mal.

So sinnlos, wie hier beschrieben, finde ich diesen regulären Ausdruck aber nicht. Spontan fällt mir dazu ein Beispiel ein:

Ich möchte den Namen Müller in einer csv-Datei finden. Mit dem Befehl

grep Müller datei.csv

erziele ich kein Ergebnis. Nun denke ich mir, dass der Name irgendwie anders hinterlegt ist und gebe statt dessen

grep Mu.*ller datei.csv

ein. Als Ergebnis erhalte ich unter anderem "Mueller", "Mu[irgendein Umsetzungscode]ller", aber eben auch "Muller" - was ja durchaus vorkommen kann, wenn der Name durch jemanden, der an einer Tastatur ohne Umlaute sitzt und auch die Ersetzung von "ü" durch "ue" nicht kennt, eingegeben wurde. Für den regulären Ausdruck ".+" benötigt man darüber hinaus noch das eher selten benutzte egrep. Wozu also die Umstände?

Daher bin ich dafür, diesen Absatz herauszunehmen. Gibt es dagegen Einwände?

noisefloor Team-Icon

Ehemaliger
Avatar von noisefloor

Anmeldungsdatum:
6. Juni 2006

Beiträge: 28316

Hallo,

Daher bin ich dafür, diesen Absatz herauszunehmen. Gibt es dagegen Einwände?

Ja. Im Kontext ist der Absatz schon richtig. Also die Warnung, dass man in der Regel nicht gegen etwas matchen sollte, was immer wahr ist.

Gruß, noisefloor

noisefloor Team-Icon

Ehemaliger
Avatar von noisefloor

Anmeldungsdatum:
6. Juni 2006

Beiträge: 28316

Hallo,

Nachtrag, zu deinem Beispiel: Das würde auch gegen z.B. "Mueller-Meiller" matchen - was du ja nicht suchst. Du suchst ja nur "Müller" (bzw. Muller, Mueller etc.).

Gruß, noisefloor

wxpte

Avatar von wxpte

Anmeldungsdatum:
20. Januar 2007

Beiträge: 1004

Hallo noisefloor,

Bei deinem Beispiel im Nachtrag ergibt sich aber kein Unterschied, wenn ich

egrep Mu.+ller datei.csv

eingebe. Und gerade in dem Kontext "Tipps und Tricks" finde ich den Absatz verkehrt: ich benötige dann ja auch die weitere Suche mit

grep Muller datei.csv

, um dann auch wirklich "Muller" zu finden. Das macht es also eher umständlicher.

wxpte

Avatar von wxpte

Anmeldungsdatum:
20. Januar 2007

Beiträge: 1004

Nachtrag: Wenn ich "Mueller-Meiller" ausschließen wollte, würde ich in einer csv eher

grep "Mu.*ller\;" datei.csv

eingeben.

noisefloor Team-Icon

Ehemaliger
Avatar von noisefloor

Anmeldungsdatum:
6. Juni 2006

Beiträge: 28316

Hallo,

das matcht aber auch auf Mueller-Meiler:

1
2
3
4
>>> import re
>>> name='Mueller-Meiller;'
>>> re.match('Mu.*ller\;', name)
<_sre.SRE_Match object at 0x7f9b25816920>

(matcht übrigens auch außerhalb von Python ☺ )

Gruß, noisefloor