rpm -qa|sort|grep lib* bash-newbie
Der Befehl im Betreff gibt eine schön sortierte Liste der installierten Pakete aus. Allerdings befinden sich darin auch viele, die die Zeichen "lib" nicht enthalten. Irgendwas bewirkt grep aber offenbar schon, da eben bei weitem nicht alle installierten rpms angezeigt werden. BTW: Gehe ich recht in der Annahme, daß man beim installieren Yast meiden sollte, wenn man einaml mit rpm selbst (erfolgreich) Hand angelegt hat? Ich habe den Eindruck, daß sowohl rpm, als auch Yast auf eigene db zurückgreift und sich um andere installierte Pakete nicht kümmert. Allerdings habe ich gelesen, daß Yast --force und --nodeps (ich fühle mich diskriminiert) also doch wohl auch rpm verwendet (?). Peter
* Peter Lipp postete am 30. Apr. 2003 folgendes:
Der Befehl im Betreff gibt eine schön sortierte Liste der installierten Pakete aus.
Versuch doch mal folgendes: #!/bin/sh rpm -qa --qf '%{name}-%{version}-%{release}.%{arch}.rpm\n' 2>&1 \ | sort > rpmlist Bye Michael -- I have good hope that there is something after death. -- Plato _______________________________________________________________________ Registered Linux User #228306 AIM & Y! Tuxi70 ICQ #151172379
Am Mittwoch, 30. April 2003 01:59 schrieb Michael Raab:
* Peter Lipp postete am 30. Apr. 2003 folgendes:
Der Befehl im Betreff gibt eine schön sortierte Liste der installierten Pakete aus.
Versuch doch mal folgendes:
#!/bin/sh
rpm -qa --qf '%{name}-%{version}-%{release}.%{arch}.rpm\n' 2>&1 \
| sort > rpmlist
Wow! Danke. Poinlich: Meine Primitivversion hat auch schon gereicht. Bin entweder beim Hochradeln in die vorige Ausgabe von rpm -qa gerutscht, oder xterm spinnt gerade wieder ein bißchen. Peter
I have good hope that there is something after death. -- Plato Der freut sich wohl auch auf die Hölle.
On 30 Apr 2003 at 1:34, Peter Lipp wrote:
Der Befehl im Betreff gibt eine schön sortierte Liste der installierten Pakete aus. Allerdings befinden sich darin auch viele, die die Zeichen "lib" nicht enthalten. Irgendwas bewirkt grep aber offenbar schon, da eben bei weitem nicht alle installierten rpms angezeigt werden.
Falsche Verwendung von '*'! Es reicht ein: "rpm -qa|grep lib|sort". Das liefert alles aus "rpm - qa", was irgendwo das pattern "lib" enthält.
BTW: Gehe ich recht in der Annahme, daß man beim installieren Yast meiden sollte, wenn man einaml mit rpm selbst (erfolgreich) Hand angelegt hat? Ich habe den Eindruck, daß sowohl rpm, als auch Yast auf eigene db zurückgreift und sich um andere installierte Pakete nicht kümmert. Allerdings habe ich gelesen, daß Yast --force und --nodeps (ich fühle mich diskriminiert) also doch wohl auch rpm verwendet (?). Peter
a) yast verwendet rpm b) das mit --force und --nodeps stimmt (IMO) c) yast prüft aber _vor_ dem Instalieren die Abhängigkeiten und fordert Dich auf, diese Aufzulösen. d) ob man yast verwenden will oder nicht, ist Geschmackssache. Du kannst aber ohne Schwierikgkeiten ein rpm manuell installieren und danach wieder yast benutzen. Andreas
* Peter Lipp schrieb am 30.Apr.2003:
Der Befehl im Betreff gibt eine schön sortierte Liste der installierten Pakete aus. Allerdings befinden sich darin auch viele, die die Zeichen "lib" nicht enthalten. Irgendwas bewirkt grep aber offenbar schon, da eben bei weitem nicht alle installierten rpms angezeigt werden.
Was macht dieser Befehl? Lenken wir mal die Aufmerksamkeit auf den letzten Teil: grep lib* Als erstes wird dies von der bash interpretiert. Falls es im aktuellen Verzeichnis eine Datei gibt, die mit lib anfängt, so wird lib* durch diesen Namen ersetzt, und es wird nicht mehr nach lib* gesucht, sondern nach libanon, oder wie immer diese Datei heißt. Gibt es gar mehere Dateien, die mit lib anfangen, so wird lib* durch all diese Namen ersetzt und es grep so übergeben. Dann aber interpretiert grep nur das erste Wort als Suchwort, und alle anderen als Dateien in denen gesucht werden soll, aus der Pipe wird dann nicht mehr gelesen. (bash-newbie ist wohl kein Bestandteil Deines Befehls) Es hängt somit im Hohen Maße von dem aktuellen Verzeichnis ab. Nur wenn keine Datei mit lib anfängt bekommt grep das lib* überhaupt zu sehen. Das ist doch sicherlich nicht so gewollt. Um dieses Verhalten zu vermeiden muß Du den * vor der bash schützen. Entweder indem Du ein \ vor dem * setzt oder aber lib* in " bzw ' setzt. Aber dann übergibst Du grep lib*. grep kennt aber keine shell-Wildcards, sondren RegExp. Die funktionieren ganz anders. lib* steht für ein l gefolgt von genau ein i gefolgt von beliebig viele, auch kein, b irgendwo in einer Zeile. Zeilen, die diese Bedingung erfüllen, werden ausgegeben. Das mit dem b* kannst Du Dir genausogut sparen. lib* macht nichts anderes als li denn b* umfaßt auch kein b und insgesamt reicht es, wenn der Suchbegriff sich irgendwo in der Zeile befindet, daß muß nicht am Anfang oder Ende sein, kann auch mitten drin sein. Es wird somit jede Zeile ausgegeben, die irgendwo li enthält. Was Du willst ist grep "^lib" Dabei steht das ^ für den Zeilenanfang. ^lib bedeutet somit, daß lib am Zeilenanfang stehen muß. RegExp werden unter anderem von grep, aber auch von vielen anderen Programmen benutzt. Siehe auch man regex RegExp sind sehr, sehr mächtig und es lohnt sich, sich ein wenig damit zu befassen. Aber die bash benutzt sie nicht. Die bash benutzt Wildcards. Insgesamt ist Dein Problem weniger ein bash-Problem als ein grep und RegExp Problem. Von der bash solltest Du aber wissen, daß sie die Ersetzungen vornimmt. Angenommen im aktuellen Verzeichnis gibt es folgende Dateien: $ ls bar baz foo foobar foobaz und Du machst jetzt ein $ cmd foo* so ersetzt die bash foo* durch foo foobar foobaz, das aufgerufene Programm bekommt folgendes Argumente zu sehen: ARG 0: cmd ARG 1: foo ARG 2: foobar ARG 3: foobaz Als 0. Argument wird immer der Dateiname selber übergeben, aber das ist hier nicht wichtig. Wichtig sind die folgende Argumente. Das aufrufende Programm sieht nicht, daß der Anwender ursprünglich foo* und nicht foo foobar foobaz gesagt hat. Mithin reagiert der Befehl exakt so, als hätte der Anwender von vorneherein $ cmd foo foobar foobaz gesagt, das Programm hat keinerlei Möglichkeiten es zu unterscheiden. Natürlich nur solange sich im aktuellen Verzeichnis genau die Dateien foo foobar und foobaz befinden, die mit foo beginnen. Das $ oben soll übrigens der Prompt sein. Bernd -- ROTFL = Rolling On The Floor, Laughing = Auf dem Boden wälzen, lachend. SCNR = Sorry, Could Not Resist = Sorry, Ich konte nicht widerstehen. AFAIK = As Far As I Know = So weit ich weis|BTW = By The Way = Nebenbei bemerkt IMHO = In My Humble Opinion = meiner bescheidenen Meinung nach |Zufallssig. 9
Am Mittwoch, 30. April 2003 06:49 schrieb Bernd Brodesser:
Was macht dieser Befehl? Lenken wir mal die Aufmerksamkeit auf den letzten Teil: grep lib* Als erstes wird dies von der bash interpretiert. Falls es im aktuellen Verzeichnis eine Datei gibt, die mit lib anfängt, so wird lib* durch diesen Namen ersetzt, und es wird nicht mehr nach lib* gesucht, sondern nach libanon, oder wie immer diese Datei heißt. Gibt es gar mehere Dateien, die mit lib anfangen, so wird lib* durch all diese Namen ersetzt und es grep so übergeben. Dann aber interpretiert grep nur das erste Wort als Suchwort, und alle anderen als Dateien in denen gesucht werden soll, aus der Pipe wird dann nicht mehr gelesen. (bash-newbie ist wohl kein Bestandteil Deines Befehls) Es hängt somit im Hohen Maße von dem aktuellen Verzeichnis ab. Nur wenn keine Datei mit lib anfängt bekommt grep das lib* überhaupt zu sehen. Das ist doch sicherlich nicht so gewollt.
Um dieses Verhalten zu vermeiden muß Du den * vor der bash schützen. Entweder indem Du ein \ vor dem * setzt oder aber lib* in " bzw ' setzt.
Aber dann übergibst Du grep lib*. grep kennt aber keine shell-Wildcards, sondren RegExp. Die funktionieren ganz anders. lib* steht für ein l gefolgt von genau ein i gefolgt von beliebig viele, auch kein, b irgendwo in einer Zeile. Zeilen, die diese Bedingung erfüllen, werden ausgegeben. Das mit dem b* kannst Du Dir genausogut sparen. lib* macht nichts anderes als li denn b* umfaßt auch kein b und insgesamt reicht es, wenn der Suchbegriff sich irgendwo in der Zeile befindet, daß muß nicht am Anfang oder Ende sein, kann auch mitten drin sein. Es wird somit jede Zeile ausgegeben, die irgendwo li enthält. Was Du willst ist grep "^lib" Dabei steht das ^ für den Zeilenanfang. ^lib bedeutet somit, daß lib am Zeilenanfang stehen muß.
RegExp werden unter anderem von grep, aber auch von vielen anderen Programmen benutzt. Siehe auch man regex
RegExp sind sehr, sehr mächtig und es lohnt sich, sich ein wenig damit zu befassen.
Aber die bash benutzt sie nicht. Die bash benutzt Wildcards. Insgesamt ist Dein Problem weniger ein bash-Problem als ein grep und RegExp Problem.
Von der bash solltest Du aber wissen, daß sie die Ersetzungen vornimmt.
Angenommen im aktuellen Verzeichnis gibt es folgende Dateien:
$ ls
bar baz foo foobar foobaz
und Du machst jetzt ein
$ cmd foo*
so ersetzt die bash foo* durch foo foobar foobaz, das aufgerufene Programm bekommt folgendes Argumente zu sehen:
ARG 0: cmd ARG 1: foo ARG 2: foobar ARG 3: foobaz
Als 0. Argument wird immer der Dateiname selber übergeben, aber das ist hier nicht wichtig. Wichtig sind die folgende Argumente. Das aufrufende Programm sieht nicht, daß der Anwender ursprünglich foo* und nicht foo foobar foobaz gesagt hat. Mithin reagiert der Befehl exakt so, als hätte der Anwender von vorneherein
$ cmd foo foobar foobaz
gesagt, das Programm hat keinerlei Möglichkeiten es zu unterscheiden. Natürlich nur solange sich im aktuellen Verzeichnis genau die Dateien foo foobar und foobaz befinden, die mit foo beginnen. Das $ oben soll übrigens der Prompt sein.
Danke für die mächtige Anwort. Bei erster Lektüre habe ich immerhin mitbekommen, daß die bash und einige Standardbefehle so mächtig sind, daß ich erst (noch) ein paar Stunden lesen sollte, bevor ich auf gut Glück anfange herumzuhantieren. Das mit den RegExp war mir völlig neu. Peter
participants (4)
-
Andreas Kyek
-
B.Brodesser@t-online.de
-
Michael Raab
-
Peter Lipp