Jak sprawdzić, czy istnieje dowiązanie symboliczne


208

Próbuję sprawdzić, czy dowiązanie symboliczne istnieje w bash. Oto, co próbowałem.

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

To jednak nie działa. Jeśli '!' jest pominięty, nigdy się nie uruchamia. I jeśli '!' jest tam, uruchamia się za każdym razem.


2
za jaką wartość, jeśli użyjesz [[! -D $ mda]] działa dobrze ..
DMin 13.12.17

Odpowiedzi:


327

-Lzwraca wartość true, jeśli „plik” istnieje i jest dowiązaniem symbolicznym (połączony plik może, ale nie musi istnieć). Chcesz -f(zwraca true, jeśli plik istnieje i jest zwykłym plikiem), a może po prostu -e(zwraca true, jeśli plik istnieje bez względu na typ).

Według podręcznika GNU , -hjest identyczny -L, ale według podręcznika BSD , nie należy stosować:

-h file Prawda, jeśli plik istnieje i jest dowiązaniem symbolicznym. Ten operator jest zachowany dla kompatybilności z poprzednimi wersjami tego programu. Nie polegaj na jego istnieniu; zamiast tego użyj -L.


2
Szukam, czy dowiązanie symboliczne NIE istnieje. ! -h lub! -L powinien działać dla dowiązań symbolicznych,! -e powinien działać inaczej.
ponieść

48
Aby pomóc każdemu, kto znajdzie to za pośrednictwem Google tak jak ja, pełną składnią !jest if ! [ -L $mda ]; then .... fi np. Umieszczenie wykrzyknika poza nawiasami kwadratowymi.
Sam

19
Chciałem tylko dodać coś do końcówki podanej przez @Sam; wykonując tego rodzaju operacje, pamiętaj o umieszczeniu nazwy pliku w cudzysłowie, aby uniknąć problemów z białymi spacjami. np. if [ ! -L "$mda" ]; then ... fi(uwaga: if [ ! ... ]i if ! [ ... ]są identyczne :)
Thomas Vervest,

2
czy naprawdę widzisz różnicę między -L i -h? w moim bashu (wersja 4.2.53 (1) -release (x86_64-redhat-linux-gnu) man bash jest identyczny dla obu -L i -h i zachowują się tak samo, tzn. sprawdzają, czy plik faktycznie jest linkiem i nie nie ma znaczenia, czy link do pliku istnieje, czy nie.
philippe lhardy

3
Tak -Li -hsą takie same . man testrównież to potwierdza.
Sparhawk

39

-L oznacza, że ​​istnieje test dla pliku i jest on również dowiązaniem symbolicznym

Jeśli nie chcesz testować, czy plik jest dowiązaniem symbolicznym, ale po prostu sprawdź, czy istnieje niezależnie od typu (plik, katalog, gniazdo itp.), Użyj -e

Więc jeśli plik jest naprawdę plikiem, a nie tylko dowiązaniem symbolicznym, możesz wykonać wszystkie te testy i uzyskać status wyjścia, którego wartość wskazuje na błąd.

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

16
-e "${file}"kończy się niepowodzeniem, jeśli dowiązanie symboliczne istnieje, ale jego cel nie istnieje.
Flimm

1
Taki sam wynik jak Flimm. Jestem na OS X. Dla mnie -L i -h pracują dla dowiązań symbolicznych, ale nie -e lub -f.
pauljm

2
@Flimm, więc jeśli chcę tylko przetestować, czy nazwa pliku jest pobierana (czy to plik, czy dowiązanie symboliczne bez celu), jaki jest najlepszy sposób? najwyraźniej -e nie działa
dragonxlwang

38

Możesz sprawdzić istnienie dowiązania symbolicznego i czy nie jest zerwane z:

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

Kompletne rozwiązanie to:

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

2
-L test, czy dowiązanie symboliczne jest uszkodzone, czy nie. Łącząc z -e można sprawdzić, czy łącze jest również prawidłowe (połączenie z katalogiem lub plikiem). Głosowanie za tymi rozwiązaniami, ponieważ uważam, że ważne jest uchwycenie tego aspektu.
Torbjörn Österdahl

14

Może tego właśnie szukasz. Aby sprawdzić, czy plik istnieje i nie jest łączem.

Wypróbuj to polecenie:

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

8

Co powiesz na używanie 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

4

Czy plik naprawdę jest dowiązaniem symbolicznym? Jeśli nie, zwykłym testem na istnienie jest -rlub -e.

Zobaczyć man test.


3

Jeśli testujesz istnienie pliku, chcesz, aby nie -e -L. -L testy dla dowiązania symbolicznego.


Szukam, czy dowiązanie symboliczne NIE istnieje. ! -h lub! -L powinien działać dla dowiązań symbolicznych,! -e powinien działać inaczej.
ponieść

3
To, czego chcesz, nie jest jasne. Plik istnieje i nie jest dowiązaniem symbolicznym? Następnie przetestuj zarówno -e, jak i! -H.
Andrew Lazarus,

3
  1. najpierw możesz zrobić z tym stylem:

    mda="/usr/mda"
    if [ ! -L "${mda}" ]; then
      echo "=> File doesn't exist"
    fi
  2. jeśli chcesz to zrobić w bardziej zaawansowanym stylu, możesz napisać to tak:

    #!/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

wynik powyżej jest następujący:

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

Pierwsze wywołanie jest nieprawidłowe, jeśli plik istnieje, ale nie jest łączem lub jest wiszącym łączem. Drugi jest błędny, jeśli ścieżka jest wiszącym dowiązaniem symbolicznym.
Jonathan Tomer,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.