bash, cat, grep und Variablen

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

bash, cat, grep und Variablen

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.
Hier mal ein paar Schnipsel:

helge@debian:~$ cd /sys/devices/
helge@debian:/sys/devices$ altmodes=`find -name alternate_modes`
helge@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
helge@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:

helge@debian:/sys/devices$ actmode=$(cat $altmodes | grep "*")
helge@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


Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Martin Steigerwald
Hallo Helge.

Helge Reimer - 01.10.18, 18:32:

> Wenn ich diese Ausgabe aber in eine Variable packe, dann passiert
> folgendes:
>
> helge@debian:/sys/devices$ actmode=$(cat $altmodes | grep "*")
> helge@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?

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


Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Helge Reimer
Am Montag, 1. Oktober 2018, 18:46:51 CEST schrieb Martin Steigerwald:

> Funktioniert
>
> actmode=$(grep "*" $altmodes)
>
> ?

Nein, selbes Erbebnis wie geschrieben.
 
> 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.

> 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


Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Jens Schüßler-2
In reply to this post by Helge Reimer
* Helge Reimer <[hidden email]> wrote:
>
> 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:
>
> helge@debian:/sys/devices$ actmode=$(cat $altmodes | grep "*")
UUOC
 
 > helge@debian:/sys/devices$ echo $actmode
 
helge@debian:/sys/devices$ echo "$actmode"
   
Und prinzipiell gehören solche Fragen nach de.comp.os.unix.shell

Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Helge Reimer
Am Montag, 1. Oktober 2018, 19:07:31 CEST schrieb Jens Schüßler:

> > helge@debian:/sys/devices$ actmode=$(cat $altmodes | grep "*")
>
> UUOC

Danke. Angenommen.
Habe verstanden.

> helge@debian:/sys/devices$ echo "$actmode"

Nochmal Danke. So gehts.
Verstehe die Ausgabe ohne " trotzdem gerade nicht.

> 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


Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Martin Steigerwald
In reply to this post by Jens Schüßler-2
Jens Schüßler - 01.10.18, 19:07:
> > helge@debian:/sys/devices$ echo $actmode
>
> helge@debian:/sys/devices$ echo "$actmode"

Hmm, den hatte ich übersehen.

Ciao,
--
Martin


Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Stefan Tichy-3
In reply to this post by Helge Reimer
On Mon, Oct 01, 2018 at 07:40:16PM +0200, Helge Reimer wrote:
> 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 )

Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Jochen Spieker
In reply to this post by Martin Steigerwald
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>

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Martin Steigerwald
Jochen Spieker - 01.10.18, 22:14:

> 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


Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Uwe Kleine-König-7
In reply to this post by Stefan Tichy-3
On 10/01/2018 09:05 PM, Stefan Tichy wrote:

> On Mon, Oct 01, 2018 at 07:40:16PM +0200, Helge Reimer wrote:
>> 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
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


signature.asc (499 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Heiko Schlittermann (HS12-RIPE)
In reply to this post by Helge Reimer
Helge Reimer <[hidden email]> (Mo 01 Okt 2018 18:32:27 CEST):
> 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:
>
> helge@debian:~$ cd /sys/devices/
> helge@debian:/sys/devices$ altmodes=`find -name alternate_modes`

altmodes enhält eventuell jetzt mehrere Zeilen.
Sollte im weiteren Verlauf ggf. bedacht werden.

> helge@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

> helge@debian:/sys/devices$ cat $altmodes | grep "*"
> 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 '^').


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

Ja, soweit so gut.

> Wenn ich diese Ausgabe aber in eine Variable packe, dann passiert folgendes:
>
> helge@debian:/sys/devices$ actmode=$(cat $altmodes | grep "*")
> helge@debian:/sys/devices$ echo $actmode
> native: G29 Racing Wheel breakpoint cpu cstate_core cstate_pkg i915 kprobe
...
> 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 ------------ -

signature.asc (499 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: bash, cat, grep und Variablen

Helge Reimer
In reply to this post by Uwe Kleine-König-7
Am Dienstag, 2. Oktober 2018, 11:25:46 CEST schrieb Uwe Kleine-König:

> > 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

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.