shellscript Problem

Manga

Well-Known Member
hallo,

ich habe hier ein Problem mit einem kleinen shellscript.
Das Skript soll prüfen ob es sich um ein Linux oder *bsd system handelt
und dann die alte Datei sichern bevor die neue kopiert wird, da BSD cp dei option -u nicht kennt.

PHP:
if [ "$USER" = "y" ] ; then
	echo -n "Copying files from ${SOURCE} to ${HOME}..." >&2
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc 		${HOME}/.tcshrc
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.bindkey 	${HOME}/.tcshrc.bindkey
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.complete ${HOME}/.tcshrc.complete
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.set 	${HOME}/.tcshrc.set
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.alias 	${HOME}/.tcshrc.alias
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.hosts 	${HOME}/.tcshrc.hosts
	
	if ["`uname`" == "Linux"] ; then
	    if ["-e ${HOME}/.tcshrc.local"] ; then
		/bin/cp -f ${VERBOSE} ${HOME}/.tcshrc.local ${HOME}/.tcshrc.local.old
		/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.local 	${HOME}/.tcshrc.local		
	else
		/bin/cp -u ${VERBOSE} ${SOURCE}/tcshrc.local 	${HOME}/.tcshrc.local
		fi
	    fi
	echo " done." >&2
	exit 0
fi

Wenn ich Linux!=Linux setzte,(nur zu Testzwecken, soll später mit `uname`funktioniern)
habe ich folgende Ausgabe und die tcshrc.local wird nicht kopiert.

Code:
root@ /root                                                                    
# /usr/local/bin/tcshrc_config -v -u                                           
Copying files from /usr/local/share/tcshrc to /root.../usr/local/share/tcshrc/t
shrc -> /root/.tcshrc                                                          
/usr/local/share/tcshrc/tcshrc.bindkey -> /root/.tcshrc.bindkey                
/usr/local/share/tcshrc/tcshrc.complete -> /root/.tcshrc.complete              
/usr/local/share/tcshrc/tcshrc.set -> /root/.tcshrc.set                        
/usr/local/share/tcshrc/tcshrc.alias -> /root/.tcshrc.alias                    
/usr/local/share/tcshrc/tcshrc.hosts -> /root/.tcshrc.hosts                    
 done.

Bei Linux==Linux folgende:

Code:
root@ /root                                                                   
# /usr/local/bin/tcshrc_config -v -u                                          
Copying files from /usr/local/share/tcshrc to /root.../usr/local/share/tcshrc/
shrc -> /root/.tcshrc                                                         
/usr/local/share/tcshrc/tcshrc.bindkey -> /root/.tcshrc.bindkey               
/usr/local/share/tcshrc/tcshrc.complete -> /root/.tcshrc.complete             
/usr/local/share/tcshrc/tcshrc.set -> /root/.tcshrc.set                       
/usr/local/share/tcshrc/tcshrc.alias -> /root/.tcshrc.alias                   
/usr/local/share/tcshrc/tcshrc.hosts -> /root/.tcshrc.hosts                   
[: Linux: unexpected operator                                                 
 done.

Vielleicht kann mir jemand mit ein wenig mehr Erfahrung mit shellscripten weiterhelfen.

Hier die komplette tcshrc_config
http://nopaste.bsdforen.de/189


MfG
 
Ich bin mir nicht sicher, ob das Dein Problem ist, aber um mit test(1) Strings zu auf Gleichheit zu testen nutzt man '='. '==' gibts net.
 
Das war schonmal ein Teil des Problems.

Bei uname != Linux (auf meinen FreeBSD system)
funtionierts jetzt soweit und die Ausgabe sieht so aus:

Code:
root@ /root                                                           
# /usr/local/bin/tcshrc_config -v -u                                  
Copying files from /usr/local/share/tcshrc to /root.../usr/local/share
shrc -> /root/.tcshrc                                                 
/usr/local/share/tcshrc/tcshrc.bindkey -> /root/.tcshrc.bindkey       
/usr/local/share/tcshrc/tcshrc.complete -> /root/.tcshrc.complete     
/usr/local/share/tcshrc/tcshrc.set -> /root/.tcshrc.set               
/usr/local/share/tcshrc/tcshrc.alias -> /root/.tcshrc.alias           
/usr/local/share/tcshrc/tcshrc.hosts -> /root/.tcshrc.hosts           
/root/.tcshrc.local -> /root/.tcshrc.local.old                        
/usr/local/share/tcshrc/tcshrc.local -> /root/.tcshrc.local           
 done.

Allerdings bei uname= Linux kommt

Code:
root@ /root                                                        
# /usr/local/bin/tcshrc_config -v -u                               
Copying files from /usr/local/share/tcshrc to /root.../usr/local/sh
shrc -> /root/.tcshrc                                              
/usr/local/share/tcshrc/tcshrc.bindkey -> /root/.tcshrc.bindkey    
/usr/local/share/tcshrc/tcshrc.complete -> /root/.tcshrc.complete  
/usr/local/share/tcshrc/tcshrc.set -> /root/.tcshrc.set            
/usr/local/share/tcshrc/tcshrc.alias -> /root/.tcshrc.alias        
/usr/local/share/tcshrc/tcshrc.hosts -> /root/.tcshrc.hosts


Es müsste allerdings noch eine Fehlermeldung kommen, das es cp -u nicht gibt.
Scheint so als würde nicht in die else Anweisung gesprungen.
Nur wieso?
 
Das eigentliche Problem liegt darin, daß der Code falsch eingerückt ist. Ich habe das im folgenden mal repariert:
PHP:
    if ["`uname`" = "Linux"]
       then  if ["-e ${HOME}/.tcshrc.local"]
                then  /bin/cp -f ${VERBOSE} ${HOME}/.tcshrc.local  ${HOME}/.tcshrc.local.old 
                      /bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.local ${HOME}/.tcshrc.local         
                else  /bin/cp -u ${VERBOSE} ${SOURCE}/tcshrc.local ${HOME}/.tcshrc.local 
             fi 
fi
Und jetzt sollte problemlos ersichtlich sein, warum bei `uname` != Linux nichts passiert.
 
In den else-Zweig wird gesprungen, wenn ${HOME}/tcshrc.local nicht existiert. Da hast Du wohl was verhuddelt, besser Einrücken hilft.

Das ==/= Problem liegt wohl an der, in einem anderen Thread von mir kritisierten, Extrawurst der (t)csh, wo es if ( "text" == "text" ) ... heißen würde. Vollkommen sh-inkompatibe Syntax.

0815 war schneller ;)
 
Habe die Datei jetzt folgendemaßen angepasst:

PHP:
if [ "$USER" = "y" ] ; then
	echo -n "Copying files from ${SOURCE} to ${HOME}..." >&2
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc 		${HOME}/.tcshrc
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.bindkey 	${HOME}/.tcshrc.bindkey
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.complete ${HOME}/.tcshrc.complete
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.set 	${HOME}/.tcshrc.set
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.alias 	${HOME}/.tcshrc.alias
	/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.hosts 	${HOME}/.tcshrc.hosts
	
	if [ "`uname`" != "Linux" ] ; then
	    if [ "-e ${HOME}/.tcshrc.local" ] ; then
		/bin/cp -f ${VERBOSE} ${HOME}/.tcshrc.local ${HOME}/.tcshrc.local.old
		/bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.local 	${HOME}/.tcshrc.local		
	
	    else /bin/cp -f ${VERBOSE} ${SOURCE}/tcshrc.local 	${HOME}/.tcshrc.local
		fi
	    else /bin/cp -u ${VERBOSE} ${SOURCE}/tcshrc.local 	${HOME}/.tcshrc.local
		
	fi

Wenn Linux erkannt wird versucht das Skript jetzt auch schön mit cp -u zu kopieren, erkennt es allerdings FreeBSD springt es in die erste if-Anweisung und
versucht .tcshrc.local zu kopieren, egal ob sie schon existiert oder nicht.

Die Überprüfung schlägt also fehl, oder ich hab schon wieder was an der if-Anweisung falsch gemacht.
 
Wenn Du das -e in die Quotes nimmst, wird es als String angesehen. Ein String ist wahr, also ist der Ausdruck wahr und es wird nicht in den Else-Zweig gesprungen.

Vielleicht doch mal ein wenig 'Grundlagenforschung'? ;)

Mein Tip:
Das schöne an Shellskripts ist, dass man alles schnell mal ausprobieren kann. Das heißt, wenn Du auf ein Problem triffst, dann kannst Du es einfach vereinfachen und ausprobieren. Das ist ein riesiger Vorteil ggü. Sprachen wie C oder Java und macht vieles einfacher. Schreib Dir kleine, stark vereinfachte, Skripte um zu sehen woran es hakt. Wenn Du dann den Durchblick hast, wendest Du das Gelernte im 'größeren Maßstab' an. So kann man schnell Fortschritte machen. Wenn Du also z.B. unübersichtliche, verschachtelte Tests hast, probier sie einfach nacheinander (vielleicht sogar mit vereinfachten Ausdrücken) auf der Kommandozeile aus. Dann löst sich meist schnell der Knoten.
 
Zuletzt bearbeitet:
Vielen Dank, klappt jetzt :)


p.s.

Eigentlich ist es ja schon recht einfach.
Das ein Sting immer wahr ist, und es deshalb nicht funktioniert hätt ich wohl so schnell nicht rausgefunden.
 
Um genau zu sein, ist er nicht immer wahr. "", also der Leerstring ist zwar genaugenommen auch ein String, aber falsch. ;)
 
[: Linux: unexpected operator

Sieht man öffter ;-)
Da wir ja schon bei "Grundlagen" sind von mir auch noch was dazu ;-)

[ ist in einem Shell-Skript kein Syntax-Zeichen sondern ein Programm aufruf, nähmlich TEST(1)

Code:
# ls -i /bin/test /bin/[
94374 /bin/[    94374 /bin/test

Hier sieht man schön das [ und test genau das gleiche ist.
Somit müssen die Paramter die Du test ([) übergibst mit Spaces getrennt werden.
Somit ist ein: if ["`uname`" == "Linux"] ungültig weil es übersetzt heist: test"`uname`" == "Linux"] was es natürlich nicht gibt und somit "if" ins straucheln kommt...
 
@ paefchen - kurzer tip am rande, wenn du shell scripting lernen willst kann ich dir folgendes buch empfehlen

Shell Skript Programmierung
Broschiert: 736 Seiten
Verlag: Mitp-Verlag; Auflage: 2., Aufl. (März 2006)
Sprache: Deutsch
ISBN: 3826616235
 
Zurück
Oben