2017-12-14 1 views
0

Ich stolpere über ein seltsames Verhalten eines #!/bin/bash Skript.Shell-Skript fügt Platz beim Aufrufen von Variablen

Ich habe die Variable SD=/SOME_VALID_PATH und SCRIPT=SOME_PYTHON_SCRIPT.py. Was ich jetzt in meinem Skript machen möchte, ist eval python ${SD}/${SCRIPT}.

Was passiert ist, dass das Ergebnis wie python /SOME_VALID_PATH/ SOME_PYTHON_SCRIPT.py aussieht. Beachten Sie den Abstand zwischen dem Pfad und dem Namen des Skripts. Daher wird dieser Befehl natürlich nicht ausgeführt.

echo ${SD} ergibt /SOME_VALID_PATH und echo ${SCRIPT} gibt SOME_PYTHON_SCRIPT.py, keine Leerzeichen überhaupt.

Irgendwelche Ideen was ich (allgemein) falsch machen könnte?

+2

Warum denken Sie, dass Sie 'eval' verwenden möchten? –

+1

BTW, im Allgemeinen können Sie echo nicht vertrauen, um irgendetwas zu geben, das einer ehrlichen und genauen Darstellung ähnelt, wie sich etwas ausdehnt. Beachten Sie, dass 'mkdir'-Verzeichnis mit Leerzeichen '' und 'mkdir-Verzeichnis mit Leerzeichen' völlig unterschiedliche Dinge tun, aber' echo'-Verzeichnis mit Leerzeichen "' und 'echo-Verzeichnis mit Leerzeichen' sind nicht unterscheidbar. –

+3

Verwenden Sie "bash -x yourscript", um Ihr Skript mit der Protokollierung jedes Befehls auszuführen, den die Shell ausführt. Und [benutzen Sie nicht 'eval'] (http://mywiki.wooledge.org/BashFAQ/048), es sei denn, Sie haben genug Jahre Erfahrung, um zu verstehen, (1) * warum * Ihnen geraten wird,' eval ', und (2) * wie * eval nicht zu verwenden. –

Antwort

0

Ich bin mir nicht wirklich sicher, warum Sie versuchen, eval so zu verwenden, wie Sie es erwähnt haben (wie in den Kommentaren erwähnt, wird ein Beispiel Ihres Codes hilfreich sein). Es ist wahrscheinlich, dass der Fehler, den Sie erwähnten, ist, weil eval die als Argument bereitgestellte Zeichenfolge verkettet, und es liegt in Ihrer Verantwortung, sicherzustellen, dass die Befehlssyntax korrekt ist. Es kann also sein, dass Python den Pfad (SD) und SCRIPT als zwei verschiedene Argumente (durch Leerzeichen getrennt) erhält und somit den Pfad, der wahrscheinlich ein Verzeichnis ist, nicht ausführen kann.

Sie können Befehl Substitution mit eval und echo beispielsweise verwenden, um sicherzustellen, dass die Saiten richtig dargestellt werden. Ein Beispiel wird unten gegeben, wo ich zwei Variablen für den Pfad und den Skriptnamen definiert habe. Der Skriptname enthält ein Leerzeichen, sodass ein normales Eval einen Fehler verursacht.

$ echo $var1 
/home/user/Documents/Temp 
$ echo $var2 
temp.py 
$ echo \"$var1/$var2\" 
"/home/user/Documents/Temp/ temp.py" 
$ cat "$(echo $var1/$var2)" 
print "Hello World" 
$ eval python $var1/$var2 
/home/user/bin/python: can't find '__main__' module in '/home/user/Documents/Temp/' 
$ eval python $(echo \"$var1/$var2\") 
Hello World 

Aber das ist wahrscheinlich nicht der beste Weg, Dinge zu tun. Räume sollten in Pfaden vermieden werden.

+1

Ich stimme nicht zu, dass "Räume in Wegen vermieden werden sollten". Wenn gute Praktiken eingehalten werden, um Daten und Code voneinander zu trennen, sind Leerzeichen völlig harmlos.Wenn keine guten Praktiken * befolgt werden (wie in der Anfrage des OP und dem Beispiel hier), haben Sie viel ernstere Probleme (zB Sicherheitslücken bei Shell-Injektionsangriffen). –

+0

Ich stimme völlig zu, dass aus Sicht des Programmierers gute Praktiken übernommen werden müssen, damit der Code für alle erlaubten Dateinamen funktioniert. Aus der Sicht des Dateiherstellers, wenn es eine Option gibt, zwischen Whitespace und einem anderen Nicht-Whitespace-Zeichen zu wählen, bevorzuge ich immer einen Unterstrich, besonders in einem Unix-ähnlichen System. Es ist genauso lesbar, spielt gut mit der Tab-Vervollständigung, führt zu einfacheren regexes/glob-Mustern und macht es viel bequemer, den Namen mit bash-Werkzeugen wie cat, ls, grep usw. in der Befehlszeile zu verwenden. – SigmaPiEpsilon

Verwandte Themen