Wenn man bash benutzt, kann man auch "here strings" benutzen:Lohengrin hat geschrieben:21.11.2018 23:13:53Code: Alles auswählen
echo "$1" | sed -e "s/$2[^<>]*$3/$4"/g; /^[ ]*$/d"
Code: Alles auswählen
sed ... <<< "$1"
Wenn man bash benutzt, kann man auch "here strings" benutzen:Lohengrin hat geschrieben:21.11.2018 23:13:53Code: Alles auswählen
echo "$1" | sed -e "s/$2[^<>]*$3/$4"/g; /^[ ]*$/d"
Code: Alles auswählen
sed ... <<< "$1"
Ja. Ist ganz nett. Aber ich ärgere mich über Emacs. Sobald ich << getippt habe, haut der mit zwei EOF da hin und setzt den Curor dazwischen. Das muss ich dann erst wieder wegmachen.owl102 hat geschrieben:21.11.2018 23:25:59Wenn man bash benutzt, kann man auch "here strings" benutzen:Code: Alles auswählen
sed ... <<< "$1"
Das war mir vorgestern noch nicht klar. Danke für den Hinweis! Ich werde es in Erinnerung behalten.owl102 hat geschrieben:21.11.2018 23:25:59Und wenn man kein bash, sondern POSIX benutzt, sollte man "echo "$1"" nicht als generischen Input verwenden, da es sein kann, daß das echo der Shell Dinge innerhalb der Zeichenkette interpretiert. Stattdessen besser "printf "%s\n" "$1" verwenden.
So etwa. In der Library:Lohengrin hat geschrieben:21.11.2018 23:13:53Dann vermute ich, dass es bei dir in der Funktion so aussieht, und die $1 $2 $3 $4 in in Gänsefüßen sind.
Code: Alles auswählen
replPartStrings () { echo "$1" | sed -e "s/$2[^<>]*$3/$4"/g; /^[ ]*$/d" }
Code: Alles auswählen
# Teilstring "$strPart" durch "$strPartRep" ersetzen
# Achtung: Punkte in "$strPartRep" maskieren: '\\.', sonst werden sie als Platzhalter interpretiert
# Option: Steuerzeichen, das im String nicht vorkommt (default: '/')
replChars () { #RV strRep #A "$str" "$strPart" "$strPartRep" 'optChrCtrl'
chrCtrl=/; [ $4 ] && chrCtrl=$4
echo "$1" | sed s"$chrCtrl$2$chrCtrl$(maskSpecChars "$3")$chrCtrl"g
}
Code: Alles auswählen
#!/bin/bash
Gut, dass du nachhakst. Ich habe es nicht so gemeint wie es sich scheinbar auch anhoeren koennte. Im Gegenteil, ich stimme allen deinen Aussagen in diesem Post zu.owl102 hat geschrieben:21.11.2018 18:40:55Das hört sich so an, als könnte man sich nur dann für die Bash entscheiden, wenn man keine Kompatibilität benötigt.Meillo hat geschrieben:21.11.2018 11:27:00Aber ja: Wenn man keine Kompatiblitaet braucht, dann kann man verwenden, was einem selbst am sinnvollsten erscheint.
Aber auch ich will Kompatibilität; meine Skripte sollen unter RHEL/CentOS 7, Fedora, Debian 9 und openSuse laufen, und einige auch auf meinem Illumos-basiertem Server (OmniOS). Und deswegen habe ich mich bewußt für "!/bin/bash" entschieden.
Wie man sieht: Eine individuelle Entscheidung, basierend auf der Kompatibilität, die ich benötige. Deswegen störe ich mich auch immer an Sätzen wie "Und für höhere portabilität kein bash sondern bourne shell verwenden...", denn ohne zu wissen, was für Kompatibilität der Autor/Fragestellung überhaupt benötigt ist so ein Ratschlag IMHO einfach Käse. (Und "bourne shell verwenden" bedeutet, nicht einmal POSIX einsetzen zu dürfen, da die Bourne Shell einige POSIX-Features nicht bietet, wie z.B. "test -e" oder "test -L". [1] Aber der Autor dieser Zeile hat auch recht, man wäre dann zu noch mehr/älteren Unix-Systemen kompatibel, als wenn man POSIX einsetzen würde.)
[1] Quelle: http://mywiki.wooledge.org/BashFAQ/004
Sollte sie nicht vielleicht besserraa hat geschrieben:22.11.2018 08:51:46Der Vollständigkeit halber: Die erste Zeile in meinen Scripten lautet selbstverständlich immerCode: Alles auswählen
#!/bin/bash
Code: Alles auswählen
#!/usr/bin/env bash
Klar, man kann's auch übertreiben.Meillo hat geschrieben:22.11.2018 09:34:04Sollte sie nicht vielleicht besserraa hat geschrieben:22.11.2018 08:51:46Der Vollständigkeit halber: Die erste Zeile in meinen Scripten lautet selbstverständlich immerCode: Alles auswählen
#!/bin/bash
lauten?Code: Alles auswählen
#!/usr/bin/env bash
Och, die bash ist auch äußerst interpretationsfreudig. Aber beiowl102 hat geschrieben:21.11.2018 23:25:59Und wenn man kein bash, sondern POSIX benutzt, sollte man "echo "$1"" nicht als generischen Input verwenden, da es sein kann, daß das echo der Shell Dinge innerhalb der Zeichenkette interpretiert.
Code: Alles auswählen
echo $irgendeinString | sed sonstwas
Code: Alles auswählen
echo $irgendeinString
Ich empfinde das als einen guten und berechtigten Punkt und nicht als Übertreibung.
Das ist auch korrekt so. Ist jedem (der Nicht-Profis) klar, warum das so ist?raa hat geschrieben:22.11.2018 10:11:26liefert allerdings an Stelle mehrerer aufeinanderfolgender Blanks jeweils nur eins, jedenfalls bei mir ...Code: Alles auswählen
echo $irgendeinString
Ich schon. Was ist denn der Unterschied? "Weiß" das OS sonst nicht, dass es als Umgebung für das Script eine Instanz der bash starten muss?
Naja, mir im Moment noch etwa zur Hälfte, sagen wir mal.Meillo hat geschrieben:22.11.2018 10:22:39Das ist auch korrekt so. Ist jedem (der Nicht-Profis) klar, warum das so ist?raa hat geschrieben:22.11.2018 10:11:26liefert allerdings an Stelle mehrerer aufeinanderfolgender Blanks jeweils nur eins, jedenfalls bei mir ...Code: Alles auswählen
echo $irgendeinString
Richtig, es sei denn, man will es so. Und ich kann's öfters so gebrauchen.Meillo hat geschrieben:22.11.2018 10:22:39... und es zeigt schoen, warum es sinnvoll ist, Variablenexpansionen normalerweise zu doublequoten.
Ja, ist nicht in doublequotes. Hintergrund ist AFAIK, dass die Shell ohne quotes interpretiert und für die Interpretation sind "überflüssige" zusätzliche Leerzeichen irrelevant, weshalb sie einfach entfallen. (So wie z.B. beiMeillo hat geschrieben:22.11.2018 10:22:39Das ist auch korrekt so. Ist jedem (der Nicht-Profis) klar, warum das so ist?
Code: Alles auswählen
cp -a file file2
Code: Alles auswählen
#!/bin/bash
[...]
usage () {
echo -e "\
Usage: $0 -r <device> [-p <device>...] -u <device> -m <directory>
Arguments:
-r <device> root partition
-p <device>... other partitions (quote when more than one!)
-u <device> usb device
-m <directory> mountpoint for usb device
Example:
$0 -r /dev/sda2 -p \"/dev/sda3 /dev/sda4 /dev/sda5\" -u /dev/sdb1 -m /mnt/tmp
Note:
Except the option '-p', all options are mandatory.\
"
}
# END: functions
c=0
while getopts r:p:u:m: opt; do
case "$opt" in
r) rootpart="$OPTARG" && ((c++));;
p)
parts="$OPTARG"
if [ -z "$parts" ]; then
usage "$0"; exit 1
fi
;;
u) usb="$OPTARG" && ((c++));;
m) mountpoint="$OPTARG" && ((c++));;
\?) usage "$0" && exit 1;;
esac
done
[...]
# mount $parts
for i in $parts; do
echo "Mounting $i ..."
mount_cmd "$i"
if [ $? -ne 0 ]; then
echo "ERROR: failed to mount $i."
umount_cmd
exit 1
else
echo "$i mounted."
fi
done
[...]
Die bash könnte z.B. nicht in /bin, sondern auf einem Nicht-Linux in /usr/local/bin liegen. Siehe auch: https://stackoverflow.com/questions/163 ... r-bin-bash
Nehmen wir an, dass zuvorraa hat geschrieben:22.11.2018 12:39:43Naja, mir im Moment noch etwa zur Hälfte, sagen wir mal.Meillo hat geschrieben:22.11.2018 10:22:39Das ist auch korrekt so. Ist jedem (der Nicht-Profis) klar, warum das so ist?raa hat geschrieben:22.11.2018 10:11:26liefert allerdings an Stelle mehrerer aufeinanderfolgender Blanks jeweils nur eins, jedenfalls bei mir ...Code: Alles auswählen
echo $irgendeinString
Code: Alles auswählen
irgendeinString="foo bar baz"
Code: Alles auswählen
echo $irgendeinString
Code: Alles auswählen
echo foo bar baz
Code: Alles auswählen
"echo" "foo" "bar" "baz"
(Diese Beschreibung unterschlaegt ein paar Details, sollte aber im Groben verstaendlich machen, was passiert.)http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html hat geschrieben: The echo utility arguments shall be separated by single <space> characters and
a <newline> character shall follow the last argument.
Code: Alles auswählen
"echo" "foo bar baz"
Du kannst natuerlich tun was du willst. Meiner Erfahrung nach ist es ueblicherweise so, dass ein Quoten der Variablenexpansion in etwa 90% der Faelle das ist was man haben sollte. Falls man einmal zu viel quoted, dann ist der Fehler gleich offensichtlich. Falls man einmal zu wenig quoted, dann funktioniert es oft scheinbar gut, bis dann mal ein unerwarteter Wert kommt. Das sind aber nur Erfahrung und rationale Argumentation, du darfst es natuerlich auch anders machen. (Wer sehr genau weiss, was er tut, darf sich auch mal begruendet ueber die Best Practice hinwegsetzen ... was er aber aus gutem Grund selten wollen wird.)Richtig, es sei denn, man will es so. Und ich kann's öfters so gebrauchen.Meillo hat geschrieben:22.11.2018 10:22:39... und es zeigt schoen, warum es sinnvoll ist, Variablenexpansionen normalerweise zu doublequoten.
Ich habe kein Problem damit, englische Begriffe einzudeutschen, wenn es denn im Zusammenhang sinnvoll ist. Aber dann muss man auch deutsch beugen. Ich forke, du forkst, die Shell forkt.Meillo hat geschrieben:22.11.2018 16:58:474) Die Shell forked und ruft per exec() /bin/echo mit einem argv von vier Strings ("echo", "foo", "bar", "baz") auf.
Dann mach' haltLohengrin hat geschrieben:23.11.2018 06:12:30Was ich noch nicht durchblickt habe, ist !. Das habe ich noch nie gebraucht. Es kommt mir nur bei echo -e "Text!\nMehr Text!" lästig in die Quere.
Code: Alles auswählen
echo -e "Text! \nMehr Text!"
oderowl102 hat geschrieben:23.11.2018 10:08:54...oderCode: Alles auswählen
echo -e 'Text!\nMehr Text!'
Code: Alles auswählen
echo -e "Text\x21\nMehr Text\x21"
Klar, dankeMeillo hat geschrieben:22.11.2018 16:58:471) Die Shell liest eine Zeile:2) Die Shell expandiert die Variable:Code: Alles auswählen
echo $irgendeinString
3) Die Shell macht Word-Splitting:Code: Alles auswählen
echo foo bar baz
4) Die Shell forked und ruft per exec() /bin/echo mit einem argv von vier Strings ("echo", "foo", "bar", "baz") auf.Code: Alles auswählen
"echo" "foo" "bar" "baz"
5) echo(1) gibt jedes seiner Argumente Leerzeichen getrennt aus.
Auch klar. Ich mache das eben nur, wenn ich's genau so sehen will: Aus irgend einem String (einem reinen String, der keine zu expandierenden Variablen enthält), die "überflüssigen" Blanks enternen.Meillo hat geschrieben:22.11.2018 16:58:47Du kannst natuerlich tun was du willst. Meiner Erfahrung nach ist es ueblicherweise so, dass ein Quoten der Variablenexpansion in etwa 90% der Faelle das ist was man haben sollte. Falls man einmal zu viel quoted, dann ist der Fehler gleich offensichtlich. Falls man einmal zu wenig quoted, dann funktioniert es oft scheinbar gut, bis dann mal ein unerwarteter Wert kommt.
Ja ... typisches Problem bei mir.Lohengrin hat geschrieben:23.11.2018 06:12:30Bis auf eine Sache, die mich zum Schmunzeln gebracht hat.Ich habe kein Problem damit, englische Begriffe einzudeutschen, wenn es denn im Zusammenhang sinnvoll ist. Aber dann muss man auch deutsch beugen. Ich forke, du forkst, die Shell forkt.Meillo hat geschrieben:22.11.2018 16:58:474) Die Shell forked und ruft per exec() /bin/echo mit einem argv von vier Strings ("echo", "foo", "bar", "baz") auf.
Was ist denn `!'? History Expansion? Meine Shell macht das nicht. Im non-interaktiven Modus macht die Bash das auch nicht. Das finde ich manchmal irritierend, wenn sich die Shell unterschiedlich verhaelt, je nachdem ob man einen Befehl interaktiv oder in einem Script ausfuehrt.Was ich noch nicht durchblickt habe, ist !. Das habe ich noch nie gebraucht. Es kommt mir nur bei echo -e "Text!\nMehr Text!" lästig in die Quere.
Wem sagst du das.Meillo hat geschrieben:23.11.2018 13:04:45Das finde ich manchmal irritierend, wenn sich die Shell unterschiedlich verhaelt, je nachdem ob man einen Befehl interaktiv oder in einem Script ausfuehrt.
So, dann habe ich ein Problem: Eins der wenigen englischen Wörter, die ich gerne verwende, weil sie kürzer, prägnanter oder / und "klangvoller" sind, ist "Amp" ("amplifier" - "Verstärker"). Also wie muss das dann heißen: Ich ampe, du ampst, der Amp ampt - oder wie ...Meillo hat geschrieben:23.11.2018 13:04:45Ja ... typisches Problem bei mir.Lohengrin hat geschrieben:23.11.2018 06:12:30Bis auf eine Sache, die mich zum Schmunzeln gebracht hat.Ich habe kein Problem damit, englische Begriffe einzudeutschen, wenn es denn im Zusammenhang sinnvoll ist. Aber dann muss man auch deutsch beugen. Ich forke, du forkst, die Shell forkt.Meillo hat geschrieben:22.11.2018 16:58:474) Die Shell forked und ruft per exec() /bin/echo mit einem argv von vier Strings ("echo", "foo", "bar", "baz") auf.
Ob Smiley oder nicht, ich antworte darauf.raa hat geschrieben:24.11.2018 22:06:42So, dann habe ich ein Problem: Eins der wenigen englischen Wörter, die ich gerne verwende, weil sie kürzer, prägnanter oder / und "klangvoller" sind, ist "Amp" ("amplifier" - "Verstärker"). Also wie muss das dann heißen: Ich ampe, du ampst, der Amp ampt - oder wie ...