So überprüfen Sie, ob ein Symlink vorhanden ist

208

Ich versuche zu überprüfen, ob in bash ein Symlink vorhanden ist. Folgendes habe ich versucht.

mda=/usr/mda
if [ ! -L $mda ]; then
  echo "=> File doesn't exist"
fi


mda='/usr/mda'
if [ ! -L $mda ]; then
  echo "=> File doesn't exist"
fi

Das funktioniert jedoch nicht. Wenn '!' wird ausgelassen, es wird nie ausgelöst. Und wenn '!' ist da, es wird jedes Mal ausgelöst.

Bär
quelle
2
für was es wert ist, wenn Sie [[! -D $ mda]] funktioniert gut ..
DMin

Antworten:

327

-LGibt true zurück, wenn die "Datei" vorhanden ist und eine symbolische Verknüpfung darstellt (die verknüpfte Datei kann vorhanden sein oder nicht). Sie möchten -f(gibt true zurück, wenn eine Datei vorhanden ist und eine reguläre Datei ist) oder einfach -e(gibt true zurück, wenn die Datei unabhängig vom Typ vorhanden ist).

Gemäß dem GNU manpage , -hist identisch mit -L, aber nach dem BSD manpage , sollte es nicht verwendet werden:

-h file True, wenn eine Datei vorhanden ist und ein symbolischer Link ist. Dieser Operator wird aus Gründen der Kompatibilität mit früheren Versionen dieses Programms beibehalten. Verlassen Sie sich nicht auf seine Existenz; Verwenden Sie stattdessen -L.

Drysdam
quelle
2
Ich suche nach einem Symlink, der NICHT existiert. ! -h oder! -L sollten für Symlinks funktionieren ,! -e sollte anders funktionieren.
tragen
48
Um Hilfe jeder, der dies über Google findet wie ich, die vollständige Syntax !ist if ! [ -L $mda ]; then .... fi also das Ausrufezeichen setzen außerhalb der eckigen Klammern.
Sam
19
Ich wollte nur etwas zu dem Tipp von @Sam hinzufügen. Stellen Sie bei diesen Vorgängen sicher, dass Sie Ihren Dateinamen in Anführungszeichen setzen, um Probleme mit Leerzeichen zu vermeiden. zB if [ ! -L "$mda" ]; then ... fi(Anmerkung: if [ ! ... ]und if ! [ ... ]sind identisch :)
Thomas Vervest
2
Sehen Sie wirklich einen Unterschied zwischen -L und -h? in meiner bash (version 4.2.53 (1) -release (x86_64-redhat-linux-gnu) ist man bash für -L und -h identisch und sie verhalten sich gleich, dh sie überprüfen, ob die Datei tatsächlich ein Link ist und don Es ist
mir
3
Ja -Lund -hsind gleich . man testbestätigt dies auch.
Sparhawk
39

-L ist der Test für Datei vorhanden und ist auch eine symbolische Verknüpfung

Wenn Sie nicht testen möchten, ob die Datei ein symbolischer Link ist, sondern nur testen möchten, ob sie unabhängig vom Typ (Datei, Verzeichnis, Socket usw.) vorhanden ist, verwenden Sie -e

Wenn es sich bei der Datei also wirklich um eine Datei handelt und nicht nur um einen symbolischen Link, können Sie alle diese Tests durchführen und einen Exit-Status erhalten, dessen Wert den Fehlerzustand angibt.

if [ ! \( -e "${file}" \) ]
then
     echo "%ERROR: file ${file} does not exist!" >&2
     exit 1
elif [ ! \( -f "${file}" \) ]
then
     echo "%ERROR: ${file} is not a file!" >&2
     exit 2
elif [ ! \( -r "${file}" \) ]
then
     echo "%ERROR: file ${file} is not readable!" >&2
     exit 3
elif [ ! \( -s "${file}" \) ]
then
     echo "%ERROR: file ${file} is empty!" >&2
     exit 4
fi
Corin
quelle
16
-e "${file}"schlägt fehl, wenn der Symlink vorhanden ist, sein Ziel jedoch nicht vorhanden ist.
Flimm
1
Gleiches Ergebnis wie Flimm. Ich bin unter OS X. Für mich arbeiten -L und -h für Symlinks, aber nicht -e oder -f.
Pauljm
2
@Flimm, wenn ich also nur testen möchte, ob ein Dateiname verwendet wird (ob es sich um eine Datei oder einen Symlink handelt, ohne dass ein Ziel vorhanden ist), wie geht das am besten? anscheinend -e funktioniert nicht
dragonxlwang
38

Sie können überprüfen, ob ein Symlink vorhanden ist und ob er nicht beschädigt ist mit:

[ -L ${my_link} ] && [ -e ${my_link} ]

Die Komplettlösung lautet also:

if [ -L ${my_link} ] ; then
   if [ -e ${my_link} ] ; then
      echo "Good link"
   else
      echo "Broken link"
   fi
elif [ -e ${my_link} ] ; then
   echo "Not a link"
else
   echo "Missing"
fi
Chen Levy
quelle
2
-L Test, ob ein Symlink vorhanden ist, defekt oder nicht. Durch die Kombination mit -e kann getestet werden, ob der Link auch gültig ist (Link zu einem Verzeichnis oder einer Datei). Up-Voting dieser Lösungen, da ich es wichtig finde, diesen Aspekt zu erfassen.
Torbjörn Österdahl
14

Vielleicht ist es das, wonach Sie suchen. Um zu überprüfen, ob eine Datei vorhanden ist und kein Link ist.

Versuchen Sie diesen Befehl:

file="/usr/mda" 
[ -f $file ] && [ ! -L $file ] && echo "$file exists and is not a symlink"
Lynchen
quelle
8

Wie wäre es mit readlink?

# if symlink, readlink returns not empty string (the symlink target)
# if string is not empty, test exits w/ 0 (normal)
#
# if non symlink, readlink returns empty string
# if string is empty, test exits w/ 1 (error)
simlink? () {
  test "$(readlink "${1}")";
}

FILE=/usr/mda

if simlink? "${FILE}"; then
  echo $FILE is a symlink
else
  echo $FILE is not a symlink
fi
popedotninja
quelle
4

Ist die Datei wirklich ein symbolischer Link? Wenn nicht, ist der übliche Existenztest -roder -e.

Siehe man test.

DigitalRoss
quelle
3

Wenn Sie die Existenz von Dateien testen, möchten Sie -e nicht -L. -L testet auf einen Symlink.

Andrew Lazarus
quelle
Ich suche nach einem Symlink, der NICHT existiert. ! -h oder! -L sollten für Symlinks funktionieren ,! -e sollte anders funktionieren.
tragen
3
Was Sie wollen, ist nicht klar. Die Datei existiert und ist kein Symlink? Dann teste sowohl -e als auch! -H.
Andrew Lazarus
3
  1. Zuerst können Sie mit diesem Stil tun:

    mda="/usr/mda"
    if [ ! -L "${mda}" ]; then
      echo "=> File doesn't exist"
    fi
  2. Wenn Sie es in einem fortgeschritteneren Stil machen möchten, können Sie es wie folgt schreiben:

    #!/bin/bash
    mda="$1"
    if [ -e "$1" ]; then
        if [ ! -L "$1" ]
        then
            echo "you entry is not symlink"
        else
            echo "your entry is symlink"
        fi
    else
      echo "=> File doesn't exist"
    fi

Das Ergebnis von oben ist wie folgt:

root@linux:~# ./sym.sh /etc/passwd
you entry is not symlink
root@linux:~# ./sym.sh /usr/mda 
your entry is symlink
root@linux:~# ./sym.sh 
=> File doesn't exist
Amin Shateri
quelle
Der erste Aufruf ist falsch, wenn die Datei vorhanden ist, aber kein Link oder ein baumelnder Link ist. Der zweite ist falsch, wenn der Pfad ein baumelnder Symlink ist.
Jonathan Tomer