• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[solved] testen, ob ein Element in einem Array vorhanden ist

OsunSeyi

Hacker
Hallo.
reißt mich ruhig in Stücke...
Code:
path=$(echo $PATH | sed 's/:/\n/g')
for i in /home/tom/bin/*; do

#...hier möchte ich testen, ob ein Unterverzeichnis von ~/bin
# bereits in $PATH enthalten ist...

done;
Vorgeschichte:
/etc/profile.local : $PATH
tom
 

regexer

Advanced Hacker
Es gibt sicher mehrere Wege zum Ziel. Einfachster Vorschlag:
Code:
if echo :$PATH | grep -q :~/bin/.
then
  echo Ein Unterverz ist bereits in PATH
else
  echo Kein Unterverz in PATH
fi
 
:~/bin/. ist ungünstig, weil es auch PATH="...:~/bin/:~/whatever" trifft. Und es wird vor allem nicht expandiert (weil die Tilde nicht an erster Stelle ist), weswegen du hier :$HOME/bin nehmen musst. Mein Tip:
Code:
echo ":$PATH:" | grep -q ":$HOME/bin/"'[^\.:]'
 

regexer

Advanced Hacker
jengelh schrieb:
:~/bin/. ist ungünstig, weil es auch PATH="...:~/bin/:~/whatever" trifft. Und es wird vor allem nicht expandiert (weil die Tilde nicht an erster Stelle ist), weswegen du hier :$HOME/bin nehmen musst. Mein Tip:
Code:
echo ":$PATH:" | grep -q ":$HOME/bin/"'[^\.:]'
Stimmt! Dass die Tilde am Anfang stehen muss, habe ich nicht bedacht. Im Übrigen halte ich [^:] für ausreichend, weil ein Verzeichnis theoretisch auch mit Punkt anfangen kann...
 

regexer

Advanced Hacker
jengelh schrieb:
Und es wird vor allem nicht expandiert (weil die Tilde nicht an erster Stelle ist), weswegen du hier :$HOME/bin nehmen musst.
Ich habe nochmals drüber nachgedacht: Eigentlich kann doch die Tilde auch im Pfad selbst stehen - wenn nämlich der Pfad mit tilde gesetzt wurde.

Also - nächster Vorschlag:
Code:
if echo ":$PATH:" | grep -qE ":(~|$HOME)/bin/[^:]"
then
...
Haben wir jetzt eine relativ sichere Lösung? :wink:
 
OP
OsunSeyi

OsunSeyi

Hacker
Hallo allerseits!
Vielen Dank...
möchte nochmal das Problem schildern.
Habe in ~/bin eine Reihe Unterverzeichnisse angelegt, alle nach dem Muster BIN_xxx
Da es deren einige sind, möchte ich sie nicht alle einzeln exportieren.
Unverständlicherweise führt
Code:
for i in ~/bin/*; do
        PATH="$PATH:$i";
done;
export PATH;
dazu, daß alle betroffenen Verzeichnisse gleich 3x in $PATH auftauchen.
Mir schwebt also sowas vor:
Code:
path=$(echo ~/bin/BIN*)
 for i in $path; do
	if [ -z (echo $PATH | grep $i) ]; then
        echo $i
#bzw.	export $i;
        fi;
 done;
...was natürlich in der Form nix gehen tut. :evil:
Hab mir daran schon was abgebrochen (an die 6 Stunden), und denke 'kann doch nicht so schwer sein', aber hilft ja nichts.
Auf jeden Fall habe ich jetzt gelernt, daß grep auch in der pipe funktioniert, danke.
Aber wie bekomme ich den Ausdruck in der Bedingung hin ?
Oder ginge es überhaupt eleganter ?
viele Grüße
tom
 

regexer

Advanced Hacker
OsunSeyi schrieb:
Code:
for i in ~/bin/*; do
        PATH="$PATH:$i";
done;
export PATH;
Ich würde an deiner Stelle eher das eigentliche Problem lösten. Wenn ich dich richtig verstehe, brauchst du den ganzen PATH-test-Kram eigentlich nicht, oder?

Erste Frage: Hast du unter ~/bin/ wirklich nur Verzeichnisse stehen? In der jetzigen Form würdest du deine for-Schleife für jedes x-beliebige File durchlaufen...
 
OP
OsunSeyi

OsunSeyi

Hacker
Hi
hab für das Test-Dings jetzt folgendes:
Code:
bin=$(echo ~/bin/BIN*)
for i in $bin; do
	dat=$(echo $PATH | grep -w $i)
	if [ -z "$dat" ]; then
	path="$path:$i"
	fi;
done;
PATH=$path
export $PATH
...was wohl gehen dürfte (warscheinlich aber auch einfacher ?)
Natürlich hast Du recht, und ich hab bisher mehr abgeschrieben als verstanden :oops:
aber mit Gedud & Spucke...
Jedenfalls sind in /bin (ist hier ein Verweis auf ~/DAT/D/BIN) auch Dateien.
Man hatte das ganze Thema schon mal ausführlich in:
/etc/profile.local : $PATH
viele Grüße,
tom
 

regexer

Advanced Hacker
Code:
PATH=$path 
export $PATH
...was wohl gehen dürfte (warscheinlich aber auch einfacher ?)
Wenn du wirklich PATH komplett überschreiben willst...

Unsere hier besprochene Lösung würde für dich vollständig so aussehen (ungetestet):
Code:
for i in ~/bin/BIN* ; do
  if echo ":$PATH:" | grep -qvE ":$bin:" ; then 
    path="$path:$i" 
  fi
done
Hinzugekomen ist nur der grep-Parameter -v für die Negation. Aber es gibt natürlich viele Lösungswege.
Man hatte das ganze Thema schon mal ausführlich in:
/etc/profile.local : $PATH
... werde ich mir bei Gelegenheit ansehen.
 
OP
OsunSeyi

OsunSeyi

Hacker
Das ganze war kein Scherz...
in etc/profile.local eingetragen, bezieht sich ~/bin nicht auf home/tom/bin.
Der genaue Zusammenhang ist mir nicht klar, jedenfalls bekam ich zuerst gar keine Shell (zumindest nicht unter root, in der folgenden allgemeinen Panik brauchte es etwas, bis mir Zusammenhänge klarer wurden...) und natürlich keinen Desktop, alles über F1.
Das zeigt das durchaus gefährliche Potential solcher Scripte.
Wird wegen eines Fehlers der Ladevorgang der Shell abgebrochen, sind wohl tiefere Kenntnisse nötig, um überhaupt in's System zu kommen ?
Daraus ergibt sich die Frage, ob es nicht möglich ist, soetwas im laufenden System zu testen (neu einzulesen), wenn noch eine Konsole unter der alten Einstellung offen ist ?
Naja, ist ja gut gegangen, ich weiß, das die meisten Programme unter /usr/bin liegen, sonst hätte ich wohl eine gute Gelegenheit gehabt, etwas ed zu lernen... :)
 
Oben