Discussion:
bash, cat, grep und Variablen
Helge Reimer
2018-10-01 16:32:27 UTC
Permalink
Hallo ,

vielleicht ein unglücklicher Thread Titel aber ich möchte mir zum ersten mal
ein kleines bash script bauen und hab hier ein unerwartetes Ergebnis, wenn ich
die Ausgabe von 'grep' in eine Variable packe und mir die dann anzeigen lasse.
Hier mal ein paar Schnipsel:

***@debian:~$ cd /sys/devices/
***@debian:/sys/devices$ altmodes=`find -name alternate_modes`
***@debian:/sys/devices$ echo $altmodes
./pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/0003:046D:C24F.0007/
alternate_modes
***@debian:/sys/devices$ cat $altmodes | grep "*"
native: G29 Racing Wheel *
G29: G29 Racing Wheel *

Der Pfad zu 'alternate_modes' wurde gefunden und nach den Zeilen mit '*'
greppen klappt auch. Ausgabe korrekt.

Wenn ich diese Ausgabe aber in eine Variable packe, dann passiert folgendes:

***@debian:/sys/devices$ actmode=$(cat $altmodes | grep "*")
***@debian:/sys/devices$ echo $actmode
native: G29 Racing Wheel breakpoint cpu cstate_core cstate_pkg i915 kprobe
LNXSYSTM:00 msr pci0000:00 platform pnp0 power software system tracepoint
uncore_arb uncore_cbox_0 uncore_cbox_1 uncore_cbox_2 uncore_cbox_3 uncore_imc
uprobe virtual G29: G29 Racing Wheel breakpoint cpu cstate_core cstate_pkg
i915 kprobe LNXSYSTM:00 msr pci0000:00 platform pnp0 power software system
tracepoint uncore_arb uncore_cbox_0 uncore_cbox_1 uncore_cbox_2 uncore_cbox_3
uncore_imc uprobe virtual

Versteh ich gerade nicht.
Kann mir jemand auf die Sprünge helfen?
--
Gruß
Helge
Martin Steigerwald
2018-10-01 16:46:51 UTC
Permalink
Hallo Helge.
Post by Helge Reimer
native: G29 Racing Wheel breakpoint cpu cstate_core cstate_pkg i915
kprobe LNXSYSTM:00 msr pci0000:00 platform pnp0 power software system
tracepoint uncore_arb uncore_cbox_0 uncore_cbox_1 uncore_cbox_2
uncore_cbox_3 uncore_imc uprobe virtual G29: G29 Racing Wheel
breakpoint cpu cstate_core cstate_pkg i915 kprobe LNXSYSTM:00 msr
pci0000:00 platform pnp0 power software system tracepoint uncore_arb
uncore_cbox_0 uncore_cbox_1 uncore_cbox_2 uncore_cbox_3 uncore_imc
uprobe virtual
Versteh ich gerade nicht.
Kann mir jemand auf die Sprünge helfen?
Funktioniert

actmode=$(grep "*" $altmodes)

?

Deine Verwendung von "cat" läuft in "Expertenkreisen" auch unter
"useless use of cat" :)

Eines noch: "*" ist ein Quantor. Ich denke, Du müsstest den Stern
escapen,

actmode=$(grep "\*" $altmodes)

damit Grep ihn für sich genommen nimmt.

Warum das aber dann auf der Befehlszeile funktioniert, ist mir gerade
nach einem langem Tag Schulung halten auch ganz schlüssig.

Ciao,
--
Martin
Helge Reimer
2018-10-01 16:59:41 UTC
Permalink
Post by Martin Steigerwald
Funktioniert
actmode=$(grep "*" $altmodes)
?
Nein, selbes Erbebnis wie geschrieben.
Post by Martin Steigerwald
Deine Verwendung von "cat" läuft in "Expertenkreisen" auch unter
"useless use of cat" :)
Ja, macht bei weiterer Überlegung Sinn. Werde ich zukünftig dran denken.
Post by Martin Steigerwald
Eines noch: "*" ist ein Quantor. Ich denke, Du müsstest den Stern
escapen,
actmode=$(grep "\*" $altmodes)
Nö, auch nicht. Selbes Ergebnis.
'grep "\*" $altmodes' bringt aber auch die gewünschte Ausgabe.
--
Gruß
Helge
Jochen Spieker
2018-10-01 20:14:25 UTC
Permalink
Post by Martin Steigerwald
Eines noch: "*" ist ein Quantor. Ich denke, Du müsstest den Stern
escapen,
actmode=$(grep "\*" $altmodes)
Noch besser (auch, wenn das im konkreten Beispiel neben der Sache ist):
grep -F verwenden, wenn man gar keine regulären Ausdrücke will. Im
vorliegenden Fall egal, aber bei großen Datenmengen macht das einen
erheblichen Geschwindigkeitsunterschied und es vermeidet Fehler, wenn
man sich das angewöhnt.

J.
--
I will not admit to failure even when I know I am terribly mistaken and
have offended others.
[Agree] [Disagree]
<http://archive.slowlydownward.com/NODATA/data_enter2.html>
Martin Steigerwald
2018-10-01 20:48:20 UTC
Permalink
Post by Jochen Spieker
Post by Martin Steigerwald
Eines noch: "*" ist ein Quantor. Ich denke, Du müsstest den Stern
escapen,
actmode=$(grep "\*" $altmodes)
Noch besser (auch, wenn das im konkreten Beispiel neben der Sache
ist): grep -F verwenden, wenn man gar keine regulären Ausdrücke will.
Im vorliegenden Fall egal, aber bei großen Datenmengen macht das
einen erheblichen Geschwindigkeitsunterschied und es vermeidet
Fehler, wenn man sich das angewöhnt.
Das hatte ich auch noch im Kopf. Ist ne gute Idee.
--
Martin
Jens Schüßler
2018-10-01 17:07:31 UTC
Permalink
Post by Helge Reimer
Der Pfad zu 'alternate_modes' wurde gefunden und nach den Zeilen mit '*'
greppen klappt auch. Ausgabe korrekt.
UUOC
***@debian:/sys/devices$ echo "$actmode"

Und prinzipiell gehören solche Fragen nach de.comp.os.unix.shell
Helge Reimer
2018-10-01 17:40:16 UTC
Permalink
Post by Jens Schüßler
UUOC
Danke. Angenommen.
Habe verstanden.
Nochmal Danke. So gehts.
Verstehe die Ausgabe ohne " trotzdem gerade nicht.
Post by Jens Schüßler
Und prinzipiell gehören solche Fragen nach de.comp.os.unix.shell
Ja, schon klar. Bin halt nicht so im Thema und hoffte auf schnelle Hilfe.
Magst du hier erklären wie die Ausgabe ohne die " zustande kommt?
--
Gruß
Helge
Stefan Tichy
2018-10-01 19:05:47 UTC
Permalink
Post by Helge Reimer
Ja, schon klar. Bin halt nicht so im Thema und hoffte auf schnelle Hilfe.
Magst du hier erklären wie die Ausgabe ohne die " zustande kommt?
Nach der Parameter- (Variablen-) Erweiterung tut die Shell noch
einiges. Durch die doppelten Hochkomma wird ein Teil dieser Aktionen
übersprungen. Einfaches Beispiel:

TXT='d*'
cd $(mktemp -d) && touch abc def
echo "$TXT"
echo $TXT
--
Stefan Tichy ( dlist at pi4tel dot de )
Uwe Kleine-König
2018-10-02 09:25:46 UTC
Permalink
Post by Stefan Tichy
Post by Helge Reimer
Ja, schon klar. Bin halt nicht so im Thema und hoffte auf schnelle Hilfe.
Magst du hier erklÀren wie die Ausgabe ohne die " zustande kommt?
Nach der Parameter- (Variablen-) Erweiterung tut die Shell noch
einiges. Durch die doppelten Hochkomma wird ein Teil dieser Aktionen
TXT='d*'
cd $(mktemp -d) && touch abc def
echo "$TXT"
echo $TXT
Da gibt es auch noch andere Seiteneffekte:

TXT=-e
echo "$TXT"

Deswegen empfehle ich zum Skripten eher printf (also:

TXT=-e
printf '%s\n' $TXT

), da passieren weniger Überraschungen; auch weil echo sich abhÀngig von
der Shell anders verhÀlt:

$ dash -c "echo -e lala"
-e lala
$ bash -c "echo -e lala"
lala

Liebe GrÌße
Uwe
Helge Reimer
2018-10-02 17:13:56 UTC
Permalink
Post by Stefan Tichy
Nach der Parameter- (Variablen-) Erweiterung tut die Shell noch
einiges. Durch die doppelten Hochkomma wird ein Teil dieser Aktionen
TXT='d*'
cd $(mktemp -d) && touch abc def
echo "$TXT"
echo $TXT
Danke nochmal an Uwe uns Stefan.
Ich bin ziemlich unbedarft und dachte ich kann mir schnell ein paar Zeilen
zusammenklöppeln. Soll ja nichts großes werden.
Möchte in Verbindung mit 'dialog' oder 'kdialog' Werte in 2 Dateien dessen
Pfad sich ändern kann, ändern und die aktuellen Werte vorher und hinterher
anzeigen lassen. Und Passwortabfrage für 'sudo'.
Werde ich auch tun, aber ich muss mir dafür wohl doch noch einiges anlesen.
Martin Steigerwald
2018-10-01 19:04:06 UTC
Permalink
Hmm, den hatte ich übersehen.

Ciao,
--
Martin
Heiko Schlittermann
2018-10-02 10:09:39 UTC
Permalink
Post by Helge Reimer
Hallo ,
vielleicht ein unglÌcklicher Thread Titel aber ich möchte mir zum ersten mal
ein kleines bash script bauen und hab hier ein unerwartetes Ergebnis, wenn ich
die Ausgabe von 'grep' in eine Variable packe und mir die dann anzeigen lasse.
altmodes enhÀlt eventuell jetzt mehrere Zeilen.
Sollte im weiteren Verlauf ggf. bedacht werden.
Post by Helge Reimer
./pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/0003:046D:C24F.0007/alternate_modes
native: G29 Racing Wheel *
G29: G29 Racing Wheel *
Die Verwendung von "*" ist nicht ok, das ist kein zulÀssiger RegulÀrer
Ausdruck, unglÃŒcklicherweise toleriert Grep das aber und „denkt“, daß Du
tatsÀchlich einen * suchst.

(Es zeigt anderes Verhalten bei -E bzw. noch mal anderes bei -P,
vielleicht ist da sogar dokumentiert irgendwo, daß ein Quantifier am
Anfang eines Audrucks kein Quantifier mehr ist, wenn man POSIX RE
verwendet - ja, ist in regex(7), kurz vor der BUGS section:

ning of a parenthesized subexpression, '$' is an ordinary character except at the end of the
RE or(!) the end of a parenthesized subexpression, and '*' is an ordinary character if it
appears at the beginning of the RE or the beginning of a parenthesized subexpression (after
a possible leading '^').
Post by Helge Reimer
Der Pfad zu 'alternate_modes' wurde gefunden und nach den Zeilen mit '*'
greppen klappt auch. Ausgabe korrekt.
Ja, soweit so gut.
Post by Helge Reimer
native: G29 Racing Wheel breakpoint cpu cstate_core cstate_pkg i915 kprobe
...
Post by Helge Reimer
Versteh ich gerade nicht.
Kann mir jemand auf die SprÃŒnge helfen?
Du möchstest

echo "$actmode"

machen. Dein actmode enthÀlt einen *, wenn Du mal nachliest Ìber
die Reihenfolge der Aktionen beim Parsen der Kommandozeile, wirst Du
feststellen, daß als eine der ersten Aktionen die Variablen expandiert
werden.

Best regards from Dresden/Germany
Viele GrÌße aus Dresden
Heiko Schlittermann
--
SCHLITTERMANN.de ---------------------------- internet & unix support -
Heiko Schlittermann, Dipl.-Ing. (TU) - {fon,fax}: +49.351.802998{1,3} -
gnupg encrypted messages are welcome --------------- key ID: F69376CE -
! key id 7CBF764A and 972EAC9F are revoked since 2015-01 ------------ -
Lesen Sie weiter auf narkive:
Loading...