Befehl funktioniert in bash aber nicht in sh - Woran liegt das?

I

Ildefonso

Jungspund
Ich möchte die ersten 10 Zeichen einer Variable ausgeben, was mit bash funtktioniert, mit sh aber nicht. Woran liegt das? Wie kann es in sh realisiert werden?

Code:
#!/bin/bash
LOGTIME=$(date)
echo $LOGTIME
LOGTIME_DATE=${LOGTIME:0:10}
echo $LOGTIME_DATE

Mit Okt 27 14:41:56 CEST 2010
Mit Okt 27

Code:
#!/bin/sh
LOGTIME=$(date)
echo $LOGTIME
LOGTIME_DATE=${LOGTIME:0:10}
echo $LOGTIME_DATE

Mit Okt 27 14:42:30 CEST 2010
./test.sh: 4: Bad substitution
 
Hab ich gerade gefunden und funktioniert in der sh:
echo $LOGTIME | cut -c -10

Mit Variablenzuweisung:
LOGTIME_DATE=$(date | cut -c -10)

Oder noch besser:
LOGTIME_DATE=$(echo $LOGTIME | cut -c -10)

Funktioniert in der sh. Problem gelöst, allerdings habe ich weiter keine Ahnung, wieso die einfache Lösung aus der bash in der sh nicht geht...
 
Zuletzt bearbeitet:
Hi,

eigentlich ganz einfach: die Substring-Extraktion in der Schreibweise ${VAR:xxx:yyy} ist eine Bash-Erweiterung, das implementiert, soweit mir bekannt ist, sonst keine Shell.

Ganz am Rande: auch die Kommando-Auswertung mit $(command) ist in der Original-Bourne-Shell so eigentlich nicht vorhanden - dort müsstest du normalerweise mit Backticks arbeiten, also etwa
Code:
LOG_DATE_TIME=`date`
LOG_DATE=`date '+%d.%m.%Y'`

Was für ein Betriebssystem und welche 'sh' verwendest du überhaupt? Auf Linux ist 'sh' ja meist nur ein Link auf die 'bash', aber auf z.B. HP-UX bekommst du da eine POSIX-Shell in /usr/bin/sh oder eine echte Bourne-Shell in /usr/old/bin/sh, Solaris hat 'ne Bourne, etc. ...

Gruss, A.
 
Danke für deine Erklärung!

Code:
andreas@andreas-desktop ~/test $ uname -a
Linux andreas-desktop 2.6.31-22-generic #65-Ubuntu SMP Thu Sep 16 15:48:58 UTC 2010 i686 GNU/Linux

(eigentlich LinuxMint 8, welches aber auf Ubuntu 9.10 basiert (virtuelle Maschine))

sh ist bei mir ungleich bash, weil LOGTIME_DATE=${LOGTIME:0:10} in der bash funktioniert (Ausgabe "Mit Okt 27"), in der sh aber "./test.sh: 4: Bad substitution" ausgibt. (Siehe erstes Posting.)

Ich brauchte eine Lösung, weil, als ich zurück auf die bash gewechselt bin, andere Befehle des Scripts nicht mehr funktionierten. Z.B. dieser:
Code:
echo To: $RECEIVER > $TJ_FILE.result.mail
Auch das Anhängen von Text oder einer Leerzeile, z.B.
Code:
echo >> $TJ_FILE.result.mail
funktionierte bei Ausführung mit der bash nicht, mit sh jedoch schon.

Ich habe das kleine, vielleicht 100-zeilige Script vor einiger Zeit in der sh geschrieben und es funktionierte fast auf Anhieb. sh habe ich dabei eher zufällig gewählt, weil es kürzer war als bash. ;-)
Daß es da Inkompatibilitäten geben kann, damit habe ich nicht gerechnet. Ich dachte, das Ding ist so kurz und einfach, da ist es egal, was ich nehme. Funktioniert sicher überall.

Werde wohl mal alles so lassen, weil ich jedenfalls auf die Schnelle keine Idee habe, wie ich
Code:
echo To: $RECEIVER > $TJ_FILE.result.mail
usw. in der bash lauffähig mache. Und außerdem funktionierts ja jetzt mit der sh. :) Und im schlimmsten Fall könnten andere Befehle in der bash auch nicht funktionieren (habe ich nicht getestet).

Mir fehlt wohl die Erfahrung, um überhaupt eine qualifizierte Entscheidung treffen zu können, welche shell ich jeweils nehmen soll. Oder nimmt man besser immer die gleiche, und wenn ja, welche?

Nochmals vielen Dank für die Erklärung!
 
Hi,

habe gerade keine Ubuntu/Mint-Installation greifbar, aber Tante Google liefert bei Suche nach "sh bash difference ubuntu" einen ganz interessanten Artikel: In Version 06.10 von Ubuntu wurde aus Effizienzgründen also statt der bis dahin verwendeten "bash" die "dash" als /bin/sh installiert. Die unterstützt nicht alle bash-Features, soll aber ein schnelleres Booten ermöglichen ... (keine Ahnung, ob das heute noch so ist, aber das wäre mal eine mögliche Erklärung.)

Warum echo-Befehle in der sh funktionieren und in der bash nicht laufen sollen, verstehe ich eigentlich nicht. Das sind ja doch absolute Basics. Gibt es irgendwelche Fehlermeldungen?

Welche Shell ich selber nehme, hängt immer davon ab, was ich machen will ... wenn ich etwas unter Linux schnell zum Laufen bringen will, bash, keine Frage. Wenn das Ding auf einer Plattform laufen soll, auf der es gar keine bash gibt, oder auf möglichst vielen verschiedenen Betriebssystemen mit unterschiedlichen Shells, dann Uralt-Bourne-Shell-Stil - das versteht auch heute noch jede vernünftige Shell. Und wenn dann die Performance nicht mehr ausreicht, weil plötzlich die Arithmetik nicht mehr Shell-intern sondern mit der externen 'expr'-Utility abgehandelt wird, dann ist die Shell sowieso der falsche Ansatz 8)

Gruss, A.
 
Code:
#!/bin/sh
LOGTIME=$(date)
echo "LOG-FILE built on $LOGTIME" > test2.sh" "$LOGTIME.log

Ausführung produziert ein File mit Namen "test2.sh Don Okt 28 16:22:59 CEST 2010.log" in dem steht "LOG-FILE built on Don Okt 28 16:22:59 CEST 2010".

Code:
#!/bin/bash
LOGTIME=$(date)
echo "LOG-FILE built on $LOGTIME" > test2.sh" "$LOGTIME.log

Wenn ich dasselbe Script in der bash ausführe, wird kein File erzeugt, sondern ich bekomme folgende Fehlermeldung:
Code:
andreas@andreas-desktop ~/test $ ./test2.sh 
./test2.sh: Zeile 3: test2.sh" "$LOGTIME.log: Mehrdeutige Umlenkung.

Standard-Shell ist offenbar bash:
Code:
andreas@andreas-desktop ~/test $ echo $SHELL
/bin/bash

Eine Idee, woran das liegen könnte?
 
Wenn ich mir hier auf einer neueren Kiste die Manual-Page der 'bash' anschaue, sehe ich im Abschnitt über REDIRECTION:
Code:
... The following redirection operators [B]may precede or 
appear anywhere within a simple command or may follow
a command[/B].
Das interpretiere ich so, dass die bash hier die Umlenkungen auch zwischen Argumenten zulässt. Das lässt sich einfach überprüfen:
Code:
$ echo $SHELL
/bin/bash
$ echo $BASH_VERSION
3.2.25(1)-release
$ echo 1 2 >TEST 3 4
$ cat TEST
1 2 3 4
$
Ich vermute, dass die 'sh' bei dir einfach alles, was nach dem '>' kommt als Ausgabedatei interpretiert, und dass andererseits die 'bash' eine andere Version ist, die z.B. die Umlenkung der Ausgabe nicht zwischen den Argumenten erlaubt ... könnte man ggf. ebenfalls mal in den Manuals überprüfen.

Was in beiden Fällen m.E. allerdings funktionieren sollte:
Code:
LOGTIME=`date`
echo "LOG-FILE built on $LOGTIME" >"test2.sh $LOGTIME.log"

Quotes einzusetzen hat bei der Shell noch nie geschadet ;)

Gruss, A.
 
Code:
andreas@andreas-desktop ~/test $ echo $SHELL
/bin/bash
andreas@andreas-desktop ~/test $ echo $BASH_VERSION 
4.0.33(1)-release
andreas@andreas-desktop ~/test $ echo 1 2 > TEST 3 4
andreas@andreas-desktop ~/test $ cat TEST 
1 2 3 4
andreas@andreas-desktop ~/test $

ist genauso, wie du sagst.

Code:
echo "LOG-FILE built on $LOGTIME" > "test2.sh $LOGTIME.log"

funktioniert ebenfalls.

Danke.
 

Ähnliche Themen

script wird als cronjob anders ausgeführt

HP PSC 2175 - CUPS druckt nicht

xargs beschränkt? Script funktioniert nicht...

RHELv5 Join in W2K3 Domäne funktioniert nicht richtig

Textdatei manipulieren mittels sed

Zurück
Oben