[gelöst]bash | von wo werde ich gestart?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Rubberduck
Beiträge: 177
Registriert: 14.07.2013 21:48:19
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Langenfeld Rheinland

[gelöst]bash | von wo werde ich gestart?

Beitrag von Rubberduck » 22.08.2013 11:41:40

Hi,

ich finde es einfach nicht...
Wie finde ich im Skript heraus von wo aus das Skript gestartet wurde, also wo es liegt. Mit komplettem Pfad.
Das ist doch sicherlich eine Standard Variable wie $$ oder so...

Danke für die Hilfe

Rubberduck
Zuletzt geändert von Rubberduck am 26.08.2013 15:38:53, insgesamt 1-mal geändert.

Benutzeravatar
Dogge
Beiträge: 1895
Registriert: 13.09.2010 11:07:33
Lizenz eigener Beiträge: MIT Lizenz

Re: bash | von wo werde ich gestart?

Beitrag von Dogge » 22.08.2013 12:02:08

Findet man das nicht mit oder so ähnlich raus? Hab gerade leider kein Linux zur Hand. :(

Edit: Pwd scheint zu stimmen: http://wiki.ubuntuusers.de/pwd
Debian Testing + Gnome | Linux-Anfänger seit 04/2003
http://files.mdosch.de/2014-07/0xE13D657D.asc

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: bash | von wo werde ich gestart?

Beitrag von r900 » 22.08.2013 12:18:55

Dogge hat geschrieben:Edit: Pwd scheint zu stimmen: http://wiki.ubuntuusers.de/pwd
$PWD ist das aktuelle Verzeichnis. Wenn man vorher im Skript das Verzeichnis wechselt passt es also nicht mehr.

Eine ausführliche Antwort auf die Frage gibt es hier: http://mywiki.wooledge.org/BashFAQ/028. Die beste Lösung:
try to avoid the problem entirely by not depending on the location of your script!

Benutzeravatar
Rubberduck
Beiträge: 177
Registriert: 14.07.2013 21:48:19
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Langenfeld Rheinland

Re: bash | von wo werde ich gestart?

Beitrag von Rubberduck » 22.08.2013 13:30:48

Eine interessante Seite und ich verstehe das Problem.
Aber es ärgert mich, denn stellen wir uns folgendes vor.

Ich möchte in einem Skript prüfen ob ich bestimmte Voraussetzungen schon mal installiert habe oder nicht und möchte diese Information in ein File - in den Ordner des Skripts - schreiben.
Beim nächsten Durchlauf wird diese Datei geprüft und die Installation übersprungen.
Sicher kann ich das irgendwo hin "fest verdrahten" aber portabel ist anders.

Oder?
Aber danke für die Info.

Edit: Wobei in meinem Fall würde "$0" den Job machen aber: Zitat:"
The suspect answer is "in some shells, $0 is always an absolute path, even if you invoke the script using a relative path, or no path at all". But this isn't reliable across shells; some of them (including BASH) return the actual command typed in by the user instead of the fully qualified path. And this is just the tip of the iceberg!
.....dann werde ich es mir wohl erst garnicht angewöhnen...

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: bash | von wo werde ich gestart?

Beitrag von r900 » 22.08.2013 14:36:30

Rubberduck hat geschrieben:Ich möchte in einem Skript prüfen ob ich bestimmte Voraussetzungen schon mal installiert habe oder nicht und möchte diese Information in ein File - in den Ordner des Skripts - schreiben.
Und was soll passieren wenn das Skript nicht mit ./skript.sh sondern mit ordner/skript.sh aufgerufen wird? Möglichkeiten gibt es genug, du müsstest nur mal etwas mehr ins Detail gehen.

uname
Beiträge: 12075
Registriert: 03.06.2008 09:33:02

Re: bash | von wo werde ich gestart?

Beitrag von uname » 22.08.2013 14:51:45

Es gibt ein paar Shellbefehle. Ich denke du suchst "dirname" in Verbindung mit "readlink". Wobei vielleicht geht es einfacher.

Code: Alles auswählen

#!/bin/bash
echo "name:" $0
echo "basename: " $(basename $0)
echo "dirname: " $(dirname $0)

fullname=$(readlink -f $0)
echo "fullname: " $fullname
echo "fulldirname:" $(dirname $fullname)

Kurzversion für dein Problem. Der vollständige Pfad für $0 ist:

Code: Alles auswählen

$(dirname $(readlink -f $0))
Bitte lese die Manuals. Ich weiß nicht wie sich die Befehle z.B. bei symbolischen Links verhalten würden. Aber auf $0 würde ich bestimmt nicht prüfen ;-)

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: bash | von wo werde ich gestart?

Beitrag von r900 » 22.08.2013 15:05:54

GreyCat is neither Grey nor a Cat hat geschrieben: Too often, people believe the configuration of a script should reside in the same directory where they put their script. This is the root of the problem.

A UNIX paradigm exists to solve this problem for you: configuration artifacts of your scripts should exist in either the user's HOME directory or /etc. That gives your script an absolute path to look for the file, solving your problem instantly: you no longer depend on the "location" of your script:
:)

Benutzeravatar
Rubberduck
Beiträge: 177
Registriert: 14.07.2013 21:48:19
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Langenfeld Rheinland

Re: bash | von wo werde ich gestart?

Beitrag von Rubberduck » 22.08.2013 15:08:01

hm, ich hatte doch schon geschrieben, dass ich es verstanden hatte und es mir deswegen auch nicht angewöhnen werde S0 zu benutzen.

Mit dirname habe ich es dann hinbekommen.

Code: Alles auswählen

iniFile=$(dirname "$0")/config.ini
Deine Version

Code: Alles auswählen

iniFile=$(dirname $(readlink -f $0))/config.ini
funktioniert genauso, ist sie besser, wenn ja warum?

Danke und Gruß

uname
Beiträge: 12075
Registriert: 03.06.2008 09:33:02

Re: bash | von wo werde ich gestart?

Beitrag von uname » 22.08.2013 15:10:10

Sie wird dann besser sein wenn du das Programm ($0) von unterschiedlichen Pfaden wie oben beschrieben aufrufst. Das mag z.B. per CRON nicht passieren. Wenn du es aber z.B. manuell nutzt wird meine Version den Unterschied zwischen ./skript.sh und ordner/skript.sh verkraften, da der Pfad immer absolut ist. Deine Version verkraftet den Unterschied leider nicht. Wobei es nur dann relevant wird wenn du den Pfad irgendwo weiterverarbeitest (z.B. in Listen speicherst usw.). Am besten du gibst einfach mal den Wert von "iniFile" bei verschiedenen Aufrufen aus. Verwiesen wird jedoch immer auf die selbe Datei. Bei mir absolut und bei dir absolut oder auch mal relativ.
Nachtrag:
Ich weiß gar nicht ob die Anführungszeichen bei "$0" notwendig sind. Werden die für Dateinamen mit Leerzeichen gebraucht?

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: bash | von wo werde ich gestart?

Beitrag von r900 » 22.08.2013 15:27:36

Rubberduck hat geschrieben:

Code: Alles auswählen

iniFile=$(dirname $(readlink -f $0))/config.ini
funktioniert genauso
Anführungszeichen nicht vergessen: "$0". Man weiß ja nie was der Pfad so alles für Zeichen enthält.
uname hat geschrieben: Werden die für Dateinamen mit Leerzeichen gebraucht?
Ja. $0 kann Leerzeichen und andere Sonderzeichen enthalten (nicht escaped).

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash | von wo werde ich gestart?

Beitrag von Meillo » 22.08.2013 15:48:01

Rubberduck hat geschrieben: Ich möchte in einem Skript prüfen ob ich bestimmte Voraussetzungen schon mal installiert habe oder nicht und möchte diese Information in ein File - in den Ordner des Skripts - schreiben.
Beim nächsten Durchlauf wird diese Datei geprüft und die Installation übersprungen.
Sicher kann ich das irgendwo hin "fest verdrahten" aber portabel ist anders.
Man sollte sich hueten das Problem und einen Loesungsansatz zu mischen. Hier ging's jetzt nur darum wie dein Loesungsansatz (Datei im gleichen Verzeichnis) umgesetzt werden kann. Sinnvoller waere es den *besten* Loesungsansatz fuer ein Problem zu finden und diesen umzusetzen.

Zuerst sollte man sich fragen ob es denn nicht auch moeglich waere auf dieses Abspeichern einer Datei ganz zu verzichten. Muss ein Programm denn unbedingt wissen ob es zum ersten Mal ausgefuehrt wird? Gute Programme verhalten sich bei jeder Ausfuehrung gleich.

Dann: Was bedeutet zum ersten Mal? Auf dem Betriebssystem? Auf dem Dateisystem? Von diesem Nutzer? Aus diesem Verzeichnis?

Wenn du nun tatsaechlich vermerken musst dass es das erste Mal war, dann waeren folgende Verzeichnisse (aus der Manpage hier(7)) geeignete Plaetze:

Code: Alles auswählen

/var/lib
              Variable state information for programs.

/var/tmp
              Like  /tmp,  this  directory holds temporary files
              stored for an unspecified duration.
Use ed once in a while!

Benutzeravatar
hikaru
Moderator
Beiträge: 13593
Registriert: 09.04.2008 12:48:59

Re: bash | von wo werde ich gestart?

Beitrag von hikaru » 22.08.2013 16:16:26

Meillo hat geschrieben:Wenn du nun tatsaechlich vermerken musst dass es das erste Mal war, dann waeren folgende Verzeichnisse (aus der Manpage hier(7)) geeignete Plaetze:

Code: Alles auswählen

/var/lib
              Variable state information for programs.

/var/tmp
              Like  /tmp,  this  directory holds temporary files
              stored for an unspecified duration.
/var/tmp ist da eher weniger geeignet, denn "unspecified duration" ist eben genau das: "unspecified"
Man kann sich daher nicht darauf verlassen dass dort gespeicherte Informationen dauerhaft verfügbar sind. Bei gewissen Installationen lege ich das Verzeichnis z.B. in ein tmpfs, es ist also nach einem Reboot wieder jungfräulich.

Deine Frage was "zum ersten mal" bedeutet ist hier sehr wichtig. Heißt das pro User böte sich z.B. eine Datei oder ein Verzeichnis $HOME/.programmname an. Pro Betriebssystem spräche für eine ähnliche Struktur in /etc sofern einem die üblicherweise fehlenden Schreibrechte nicht im Weg stehen.

uname
Beiträge: 12075
Registriert: 03.06.2008 09:33:02

Re: bash | von wo werde ich gestart?

Beitrag von uname » 22.08.2013 16:29:21

/var/tmp ist da eher weniger geeignet, denn "unspecified duration" ist eben genau das: "unspecified"
Kannte das Verzeichnis nicht. Habe gerade mal ein wenig Datenschrott aus 2005 gelöscht (habe von Sarge bis Wheezy alle 2 Jahre geupgradet).

Benutzeravatar
Rubberduck
Beiträge: 177
Registriert: 14.07.2013 21:48:19
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Langenfeld Rheinland

Re: bash | von wo werde ich gestart?

Beitrag von Rubberduck » 22.08.2013 16:42:22

;=) Ich sehe (zu meiner Beruhigung) so ganz einig seid ihr euch auch nicht.

Mein momentanes Projekt ist es einen Audio-Konverter zu schreiben.
In dem dafür eigenen Installations-Skript soll lediglich vermerkt werden ob alle abhängigen Programme installiert sind,
anderenfalls läuft apt durch.

Nichts dramatisches - wenn ihr jetzt also sagt, sowas macht man nicht oder nur in bestimmten Ordnern, ja dann mach ich das eben so.
Ich verlasse mich da schon auf eure Meinung.

Wir müssen es auch nicht sonderlich aufbauschen.

Rubberduck

Benutzeravatar
hikaru
Moderator
Beiträge: 13593
Registriert: 09.04.2008 12:48:59

Re: bash | von wo werde ich gestart?

Beitrag von hikaru » 22.08.2013 16:55:25

Rubberduck hat geschrieben:Mein momentanes Projekt ist es einen Audio-Konverter zu schreiben.
In dem dafür eigenen Installations-Skript soll lediglich vermerkt werden ob alle abhängigen Programme installiert sind,
anderenfalls läuft apt durch.
Distributionsspezifische Installerskripte (apt anwerfen) finde ich einen ziemlich unsauberen Hack.
Die sauberere Variante wäre, ein Paket zu bauen, das dann seine Abhängigkeiten selbst definiert.

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: bash | von wo werde ich gestart?

Beitrag von r900 » 22.08.2013 16:56:07

Rubberduck hat geschrieben:In dem dafür eigenen Installations-Skript soll lediglich vermerkt werden ob alle abhängigen Programme installiert sind,
anderenfalls läuft apt durch.
Das prüfst du besser mit dpkg oder type. Kann ja auch sein dass die Programme mal installiert wurden und dann wieder irgendwann entfernt werden. Also so wie ich das bisher sehe ist das einer der Fälle wo man komplett ohne Datei auskommt. Und den Sinn von "Datei im Skript-Verzeichnis" sehe ich in diesem Fall erst recht nicht. Wenn ich das Skript in ein anderes Verzeichnis verschiebe sind die über apt installierten Programme nach wie vor installiert, nur dein Skript weiß davon nichts mehr.

Aber das nur der Vollständigkeit halber. Wenn du damit leben kannst ist dein Problem gelöst. :P

Benutzeravatar
Rubberduck
Beiträge: 177
Registriert: 14.07.2013 21:48:19
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Langenfeld Rheinland

Re: bash | von wo werde ich gestart?

Beitrag von Rubberduck » 22.08.2013 17:24:45

Ok, vielen Dank für eure Antworten, werde mir das Eine oder Andere überlegen.


Gruß
Rubberduck

wanne
Moderator
Beiträge: 7465
Registriert: 24.05.2010 12:39:42

Re: bash | von wo werde ich gestart?

Beitrag von wanne » 23.08.2013 01:26:08

Also ich fürhe Scripte oft so aus: cat script | bash . Ist zwar etwas ineffizenter als bash script für mich einigermasen logisch: Zuerst denke ich, ich will was mit dem script machen und dann OK ich führe es mit der bash aus. Da ist $0 dann plözlich bash.
Dann gibt es da ncoh harte Links => Die gleihe Datei kann in 2 Ordnern liegen.
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash | von wo werde ich gestart?

Beitrag von Meillo » 23.08.2013 08:34:13

wanne hat geschrieben:Also ich fürhe Scripte oft so aus: cat script | bash . Ist zwar etwas ineffizenter als bash script für mich einigermasen logisch: Zuerst denke ich, ich will was mit dem script machen und dann OK ich führe es mit der bash aus. Da ist $0 dann plözlich bash.
Sehr guter Einwand! Danke.

Solche Moeglichkeiten sollte man keinesfalls verbauen.
Use ed once in a while!

Antworten