bash test auf datei geht nicht [fast gelöst]

Alles rund um die verschiedenen Konsolen und shells sowie die Programmierung unter Linux

Moderator: Moderatoren

Antworten
Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 340
Registriert: 27. Mai 2006, 01:28

bash test auf datei geht nicht [fast gelöst]

Beitrag von OsunSeyi » 21. Okt 2016, 16:18

Hi,

Code: Alles auswählen

	PATH_NEW=`echo $PATH_OLD | sed "s|$EXCLUDED_PATHS||g"`

	echo  $PATH_NEW						# ergibt korrekt '/home/tom/file'
	file $PATH_NEW						# findet die Datei
	cat $PATH_NEW						# funktioniert ebenfalls.

	if [ -f "$PATH_NEW"  ] ; then echo 'x' ; fi		# hingegen ergibt keine Ausgabe
Wie kann das sein, und wie kann ich das Problem vermeiden?
Hat das vielleicht mit dem Zeichensatz vom Script zu tun, daß da noch Steuerzeichen im String sind?
Zuletzt geändert von OsunSeyi am 22. Okt 2016, 11:38, insgesamt 2-mal geändert.

Werbung:
uhelp
Member
Member
Beiträge: 81
Registriert: 25. Nov 2012, 19:33

Re: bash test auf datei geht nicht

Beitrag von uhelp » 21. Okt 2016, 17:28

Glaub ich nicht.
Das funktioniert so.

Irgendetwas hast du übersehen hier mitzuteilen.
Kannst ja mal das vollständiges Script posten.

Benutzeravatar
Geier0815
Administrator
Administrator
Beiträge: 4218
Registriert: 14. Jun 2004, 09:12

Re: bash test auf datei geht nicht

Beitrag von Geier0815 » 21. Okt 2016, 18:56

file dient nicht dem Finden von Dingen sondern gibt aus um was für eine Art von file es sich handelt. Dort steht dann nicht zufällig was von symbolischer Link oder ähnliches?
Wenn Windows die Lösung ist...
kann ich dann bitte das Problem zurück haben?

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 340
Registriert: 27. Mai 2006, 01:28

Re: bash test auf datei geht nicht

Beitrag von OsunSeyi » 21. Okt 2016, 21:59

Code: Alles auswählen

  EXCLUDED_PATHS='/mnt/hd/sda4/DAT/D/BAK/SCR/BIN/SL-12.2/MySQL/sql-update-tour'

	PATH_OLD='/mnt/hd/sda4/DAT/D/BIN/MySQL/sql-update-tour /mnt/hd/sda4/DAT/D/BAK/SCR/BIN/SL-12.2/MySQL/sql-update-tour'

	PATH_NEW=`echo $PATH_OLD | sed "s|$EXCLUDED_PATHS||g"`

	if [ -f "$PATH_NEW" ] ; then echo 'x' ; fi

	echo $PATH_NEW
	file $PATH_NEW

Ausgabe:

Code: Alles auswählen

~ | LifeDoc-SRC
/mnt/hd/sda4/DAT/D/BIN/MySQL/sql-update-tour
/mnt/hd/sda4/DAT/D/BIN/MySQL/sql-update-tour: POSIX shell script, ISO-8859 text executable
müsste aber eigentlich sein:

Code: Alles auswählen

~ | LifeDoc-SRC
x
/mnt/hd/sda4/DAT/D/BIN/MySQL/sql-update-tour
/mnt/hd/sda4/DAT/D/BIN/MySQL/sql-update-tour: POSIX shell script, ISO-8859 text executable
'ls $PATH_NEW' funktioniert auch normal!

Kein symbolischer Link!
Bin ich verrückt?

Gegenprobe:
Das selbe ohne Einsatz von 'sed':

Code: Alles auswählen

	PATH_NEW='/mnt/hd/sda4/DAT/D/BIN/MySQL/sql-update-tour'

	if [ -f "$PATH_NEW" ] ; then echo 'x' ; fi

	echo $PATH_NEW
	file $PATH_NEW
	ls $PATH_NEW

Code: Alles auswählen

~ | LifeDoc-SRC
x
/mnt/hd/sda4/DAT/D/BIN/MySQL/sql-update-tour
/mnt/hd/sda4/DAT/D/BIN/MySQL/sql-update-tour: POSIX shell script, ISO-8859 text executable
/mnt/hd/sda4/DAT/D/BIN/MySQL/sql-update-tour
Nur mal so, das unten klappt wiederum:
Da wird der zweite Pfad auch entfernt, alles ab dem Leerzeichen.

Code: Alles auswählen

	PATH_OLD='/mnt/hd/sda4/DAT/D/BIN/MySQL/sql-update-tour /mnt/hd/sda4/DAT/D/BAK/SCR/BIN/SL-12.2/MySQL/sql-update-tour'

	PATH_NEW=`echo $PATH_OLD | sed "s| .*$||g"`


	if [ -f "$PATH_NEW" ] ; then echo 'x' ; fi  # Ausgabe ist jetzt 'x'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Code: Alles auswählen

 EXCLUDED_PATHS='/home/tom/file2'

    PATH_OLD='/home/tom/file1 /home/tom/file2'

   PATH_NEW=`echo $PATH_OLD | sed "s|$EXCLUDED_PATHS||g"`

   if [ -f "$PATH_NEW" ] ; then echo 'x' ; fi			# klappt nicht

Code: Alles auswählen

 EXCLUDED_PATHS=' /home/tom/file2'

    PATH_OLD='/home/tom/file1 /home/tom/file2'

   PATH_NEW=`echo $PATH_OLD | sed "s|$EXCLUDED_PATHS||g"`

   if [ -f "$PATH_NEW" ] ; then echo 'x' ; fi			# klappt!
Der Unterschied ist, das bei "EXCLUDET_PATHS" das Leerzeichen mit angegeben ist:
EXCLUDED_PATHS=' /home/tom/file2'

Das ist mir jetzt aber vollkommen neu, weil mW bisher immer alle Variablen Leerzeichen am Anfang oder Ende vom String nicht übernehmen!
:???:

MH1962
Member
Member
Beiträge: 54
Registriert: 10. Aug 2015, 16:42

Re: bash test auf datei geht nicht

Beitrag von MH1962 » 22. Okt 2016, 08:30

Was ist jetzt eigentlich genau Dein Problem?

Wenn $PATH_NEW mit einem Leerzeichen beginnt (was beim sed übrig geblieben ist) UND im if-Statement gequotet wird, wird das Leerzeichen als Teil des Dateinamens angesehen und eine solche Datei wird mit Recht nicht gefunden.

Also kannst Du ENTWEDER das Leerzeichen mit abschneiden, was Du ja in dem einen Beispiel machst ODER auf die Quotes um die Variable im if-Statement verzichten. Beides funktioniert.

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 340
Registriert: 27. Mai 2006, 01:28

Re: bash test auf datei geht nicht

Beitrag von OsunSeyi » 22. Okt 2016, 09:32

Ich hatte angenommen, daß generell führende und abschließende Leerzeichen nicht in Variablen übernommen werden...
Deine Antwort leuchtet ein, hab's gerade überprüft.

Darüber hinaus hatte ich angenommen, if-'test' würde meckern, wenn eine leere Variable ohne doppelte Anführungszeichen übergeben wird,
aber auch das ist im Fall '-f' oder '-d' offensichtlich nicht der Fall.

Danke für die Hilfe!

PS

Code: Alles auswählen

	TESTPATH=''
		if [ -d $TESTPATH -o -f $TESTPATH ] ; then echo 'x' ; fi
ergibt 'x' als Ausgabe, was für mich überaschend (und irreführend) ist :schockiert:

So gesehen wäre eine eindeutigere Methode, um die Gültigkeit eies Pfades zu prüfen, wünschenswert.
Gibt es da nicht was?

Alleine dieses "if [ -d $TESTPATH -o -f $TESTPATH ]" nervt doch schon...

Code: Alles auswählen

	if [ -f $PATH_NEW    -o -d $PATH_NEW   ] ; then TEST_PATH='x' ; fi

	if [ -z "$TEST_PATH" -o -z "$PATH_NEW" ] ; then
	...
Das obige kann doch nicht die Lösung sein???

josef-wien
Guru
Guru
Beiträge: 4874
Registriert: 23. Sep 2008, 17:09

Re: bash test auf datei geht nicht [fast gelöst]

Beitrag von josef-wien » 22. Okt 2016, 12:38

Löst

Code: Alles auswählen

if [[ -f "$PATH_NEW" ]] ; then ...
Deine Probleme?

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 340
Registriert: 27. Mai 2006, 01:28

Re: bash test auf datei geht nicht [fast gelöst]

Beitrag von OsunSeyi » 22. Okt 2016, 13:18

In Hinblick auf eine evtl. leere Variable besser, aber eine Abfrage auf Gültigkeit des Pfades ist damit immer noch ungeschickt ist.
Muss leider zur Arbeit, auf die Schnelle klappt fogendes nicht...

Code: Alles auswählen

	test='/home/tom'

	if [[ -d "$test" -o -f "$test" ]] ; then echo 'x' ; fi
Wenn ich die Gültigkeit mit 'ls' prüfe, wird es auch komplizierter, weil 'ls' auch auf mehrere Pfadangaben reagiert.
Man will schließlich wissen, og es sich um genau einen gültigen Pfad handelt!

uhelp
Member
Member
Beiträge: 81
Registriert: 25. Nov 2012, 19:33

Re: bash test auf datei geht nicht [fast gelöst]

Beitrag von uhelp » 22. Okt 2016, 15:28

Dir fehlt ein prizipielles Verständnis des Quotens. Lies mal das hier: http://www.grymoire.com/Unix/Quote.html

Code: Alles auswählen

var=eins zwei drei   # CommandNotFoundError; die "eins" landet in der Variable,
#  das Kommando "zwei" mit seinem Argument "drei" wird nicht gefunden.
var="eins zwei drei"   #OK. Durch Quoting sieht die Bash den String "eins zwei drei" (Ohne Anführungszeichen)

# eine Hilfsfunktion, die die Anzahl aller Argumente ausgibt und dann die Argumente eines pro Zeile
# Die Argumente werden in <> eingeschlossen.
print_args(){    
   echo es wurden $# Argumente angegeben; 
   for ((i=1;i<=$#;i++)) ; do  
      printf "ArgNo: %-3s Arg: <%s>\n" $i "${!i}"; 
   done
}

# set -- arg1 arg2
# setzt die aktuellen Argumentzeile. Hier auf "arg1 arg2" ohne Anführungszeichen
set -- $var
print_args $*  # die Argumente müssen mit übergeben werden

set -- $var "drei vier fünf" LetztesArgument
print_args $*
# sieht so aus, als wäre alle gleich
# aber:
printf "<$1> <$2> <$3> <$4> <$5> <$6> <$7> <$8> <$9> <${10}> <${11}> <${12}>\n"
# Das ist passiert, weil der Aufruf von printf selbst wieder von der Bash geparst werden muss, 
# und damit wieder nach Leerzeichen in Tokens geteilt wird (genauer nach der IFS (InternalFieldSeparator) Variablen gesplittet wird.

var="BEGINN"
var2=ENDE
set -- $var " Leerzeichen auch am Anfang und Ende "   $var2
print_args $*
printf "<$1> <$2> <$3> <$4> <$5> <$6> <$7> <$8> <$9> <${10}> <${11}> <${12}>\n"

# wir schreiben jetzt die ganze Argumentzeile ( BEGINN  Leerzeichen auch am Ende  ENDE ) iin eine Variable
all_args="$*"
set -- $all_args
print_args $*
printf "<$1> <$2> <$3> <$4> <$5> <$6> <$7> <$8> <$9> <${10}> <${11}> <${12}>\n"

# Die Leerzeichen am Anfang und Ende sind weg.
# Weil die bash Leerzeichen als Trenner sieht, wenn sie die Zeile set -- $all_args ausführt.
Langer Rede, kurzer Sinn: du willst (fast) immer jede Expanison, wie $var als "$var" schreiben.

Du musst auch nicht auf directory oder file prüfen.
Es genügt auf -exists oder -writable zu prüfen.

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 340
Registriert: 27. Mai 2006, 01:28

Re: bash test auf datei geht nicht [fast gelöst]

Beitrag von OsunSeyi » 22. Okt 2016, 18:11

Vielen Dank für die ausführliche Antwort und die Bemühung!
Da werde ich noch einiges zu lernen haben...
Für den Augenblick hat der Test '-e' auf jeden Fall schon viel weitergeholfen!

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste