2014-10-02 4 views
5

Problem

ich dieses Bash-Skript haben:`ln -s` in einem Skript fungiert als` cp`

ACTIVE_DB=$(grep -P "^[ \t]*db.active" config.properties | cut -d= -f2 | tr -s " ") 
echo $ACTIVE_DB 
if [ "$ACTIVE_DB" = "A" ] 
then 
    ln -sf config-b.properties config.properties 
else 
    ln -sf config-a.properties config.properties 
fi 

config-a.properties

db.active = A 

config-b. Eigenschaften

db.active = B 

Wenn ich das Skript ausführen, eine harte co py (= cp) wird ausgeführt und ist oft kein symbolischer Link (noch ein physikalischer Link für diese Angelegenheit), sondern eine ganz neue Datei mit dem gleichen Inhalt wie config-a.properties oder config-b.properties.

$ ls -li 
53 -rw-r--r-- 1 ogregoir ogregoir  582 Sep 30 15:41 config-a.properties 
54 -rw-r--r-- 1 ogregoir ogregoir  582 Sep 30 15:41 config-b.properties 
56 -rw-r--r-- 1 ogregoir ogregoir  582 Oct 2 11:28 config.properties 

Als ich dies in der Aufforderung Linie manuell durch die Linie, habe ich keine Probleme und ein symbolischer Link ist in der Tat immer erstellt und config.properties Punkte in Richtung config-a.properties oder config-b.properties.

$ ls -li 
53 -rw-r--r-- 1 ogregoir ogregoir  582 Sep 30 15:41 config-a.properties 
54 -rw-r--r-- 1 ogregoir ogregoir  582 Sep 30 15:41 config-b.properties 
55 lrwxrwxrwx 1 ogregoir ogregoir  20 Oct 2 11:41 config.properties -> config-b.properties 

Hinweise

  • Keine Datei ist anderswo offen (ich bin der einzige aktive Benutzer und die Anwendung unter Verwendung der Konfiguration läuft nicht).
  • Manchmal funktioniert ln -sf normal, aber die übliche Regel ist, dass es eine Hardcopy macht.
  • Das Skript wird von einem anderen Verzeichnis ausgeführt, aber cd s in das Verzeichnis, in dem sich die config*.properties Dateien befinden, bevor die Aktionen hier ausgeführt werden.
  • Das Skript ist viel länger, aber dies ist das kürzeste Beispiel, das den Fehler reproduziert.
  • bash Version ist 4.1.2 (es ist lokal, also kümmere ich mich nicht um Shellshock).
  • ln Version ist 8.4.
  • Betriebssystem: Red Hat Enterprise Linux Server Version 6.5 (Santiago).
  • Dateisystem für diesen Ordner verwendet: ext4.

Frage

  • Warum mein Skript nicht konsequent eine symbolische Verknüpfung erstellen, sondern macht eine Hardcopy?
  • Wie erzwinge ich hier einen symbolischen Link?
+6

Der Befehl 'ln' erzeugt * keine * Kopie. Niemals – hek2mgl

+1

Ja, ich kann 'Mann ln' lesen, aber doch tut es ... zufällig! –

+0

Welches Betriebssystem und welches Dateisystem? – Cyrus

Antwort

3

Ich vermute, Sie haben ein anderes Skript oder Code, der die Symlinks überschreibt. Zum Beispiel wird sed -i Symlinks ablegen. Es gibt eine Vielzahl von Befehlen und Dienstprogrammen, die eine Datei modifizieren, indem sie eine Kopie erstellen, die Kopie modifizieren und dann die Kopie über das Original legen, wodurch der ursprüngliche Symlink zerstört wird.

+0

Das ist es in der Tat. Ich überprüfte mit und ohne 'sed -i' und das Ergebnis war anders. Vielen Dank! Ich dachte nicht, dass es die Datei ersetzen würde, also habe ich es in meinem kleinen Test gelassen, aber nicht in die Frage kopiert/eingefügt. Es tut uns leid. –

+0

Ich benutze jetzt 'sed --follow-symlinks -i' und mein Skript macht genau das, was ich will. Vielen Dank! –

+0

Dies: 'sed -i" $ (realpath ./config.properties) "' funktioniert auch durch (vollständige) Auflösung der Datei. 'https: // stackoverflow.com/questions/7665/how-to-resolve-symbolische-links-in-a-shell-script' –

1

Die einzige Antwort möglich auf die Frage (wie gefragt): warum ln verhalten sich wie cp ist: Es kann nicht.

Die einzige andere mögliche Antwort ist: Was Sie uns präsentieren, ist nicht genau, was gerade ausgeführt wird, oder es laufen andere Skripte, die die Antwort verändern.

Einige mögliche Alternativen:
1.- Der ln Befehl ist tatsächlich eine Hard-Link.Die i-node-Liste (ls -li) bestätigt, dass die i-node-Nummern eindeutig sind. Also, nein, das ist nicht der Grund.

2.- Gibt es einen Alias ​​oder eine Funktion für ln?
Das ist einfach zu überprüfen. Just Ausgabe type -a ln in Bash. Das Ergebnis wird zeigen, was Bash ln zu interpretieren ist. Wenn es NUR die Datei /bin/ln ist, dann ist es korrekt.
Sie haben bestätigt, dass kein Alias ​​oder keine Funktion beteiligt ist.

3.- Wie "das Skript wird von einem anderen Verzeichnis ausgeführt". Der Punkt hier ist: Gibt es eine andere Datei irgendwo im Dateisystem, die die gleiche i-Knoten-Nummer hat (wenn ln tatsächlich eine harte Verbindung erstellt). Die Existenz einer anderen Datei mit dem gleichen Inode kann mit (die Inode-Nummern 53,54,56 aus Ihrem Eintrag verwendet) überprüft werden:

find/-follow -inum <your inum> 

4.- Ich hoffe, dass Sie wirklich wissen, dass config-b.properties existiert eigentlich nicht (als Datei). Durch Bearbeiten dieser Datei wird der Link möglicherweise gelöscht.

Wird das eigentliche Skript auch ausgeführt, um den Dateiinhalt zu ändern/zu aktualisieren?

Note01: Beachten Sie, dass die K Trick die Extraktion in nur einem externen Anruf beheben: http://www.charlestonsw.com/perl-regular-expression-k-trick/

ACTIVE_DB=$(grep -Po "^[ \t]*db.active[ ]+=[ ]+\K." config.properties) 

Es wurde bestätigt, dass ein sed -i-config-b.properties später in der realen ausgeführt Skript die Quelle der war Problem.

+0

Bezüglich der Zitate weiß ich, dass das Ergebnis des Schnittes "A" ist. Deshalb trimme ich es danach. Für den Rest werde ich das überprüfen, wenn ich wieder bei der Arbeit bin. Danke für einige Einblicke. –

+0

Das Ergebnis von 'type -a ln' ist 'ln is/bin/ln'. Scheint ok für mich. Die Snippets, die ich in meiner Frage gezeigt habe, stammen aus meinen Skript- und Konfigurationsdateien. Wir haben wirklich Datenbanken, die wir 'A' und' B' nennen und die sich gegenseitig ersetzen können. Endlich verstehe ich deinen zweiten Punkt nicht. Könnten Sie das näher ausführen? –

+0

Der Befehl'ln' konnte nicht das tun, was Sie melden. Etwas anderes sollte passieren. Ich werde meine Antwort bearbeiten, um mehr Optionen zu geben. –

Verwandte Themen