Symlink olup olmadığını kontrol etme


208

Bash'da bir symlink olup olmadığını kontrol etmeye çalışıyorum. İşte denedim.

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

Ancak, bu işe yaramaz. Eğer '!' dışarıda bırakılır, asla tetiklenmez. Ve eğer '!' orada, her seferinde tetiklenir.


2
[[! -D $ mda]] gayet iyi çalışıyor ..
DMin

Yanıtlar:


328

-L"dosya" varsa ve sembolik bir bağlantıysa (bağlı dosya olabilir veya olmayabilir) true değerini döndürür. İsterseniz -f(dosya varsa ve normal bir -edosyaysa true değerini döndürür ) veya belki de (dosya türünden bağımsız olarak dosya varsa true değerini döndürür).

Göre GNU man , -haynıdır -L, ancak uygun BSD man , bu kullanılmamalıdır:

-h file Dosya varsa ve sembolik bir bağlantıysa doğrudur. Bu operatör, bu programın önceki sürümleriyle uyumluluk için korunur. Varlığına güvenmeyin; yerine -L kullanın.


2
Bir sembolik bağın var olup olmadığını görmek istiyorum. ! -h veya! -L sembolik linkler için çalışmalı,! -e aksi şekilde çalışmalıdır.
ayı

48
Benim yaptığım gibi Google üzerinden bu bulur yardım kimseye kullanılarak tam sözdizimi !olduğunu if ! [ -L $mda ]; then .... fi yani bir ünlem işareti koymak dışında köşeli parantez.
Sam

19
Sadece @Sam tarafından verilen ipucuna küçük bir şey eklemek istedim; bu tür işlemleri yaparken boşluk alanlarıyla ilgili sorunları önlemek için dosya adınızı tırnak içine aldığınızdan emin olun. örneğin if [ ! -L "$mda" ]; then ... fi(not: if [ ! ... ]ve if ! [ ... ]özdeş :)
Thomas Vervest

2
-L ve -h arasında gerçekten bir fark görüyor musunuz? benim bash (sürüm 4.2.53 (1) -çalışması (x86_64-redhat-linux-gnu) adam bash -L ve -h için aynıdır ve aynı davranırlar, yani dosyanın gerçekte bir bağlantı ve don dosya ile bağlantılı olup olmadığını umurumda değil.
philippe lhardy

3
Evet, -Lve -hvardır aynı . man testbunu da doğrular.
Sparhawk

39

-L dosya testi ve aynı zamanda sembolik bir bağlantı

Dosyanın sembolik bir bağlantı olup olmadığını test etmek istemiyorsanız, ancak dosya türünden (dosya, dizin, soket vb.) Bağımsız olarak var olup olmadığını test edin, sonra -e kullanın

Dosya sadece sembolik bir bağlantı değil, gerçekten dosya ise, tüm bu testleri yapabilir ve değeri hata durumunu gösteren bir çıkış durumu alabilirsiniz.

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}"simge bağlantısı varsa, ancak hedefi yoksa başarısız olur.
Flimm

1
Flimm ile aynı sonuç. OS X'dayım. Benim için -L ve -h sembolik bağlantılar için çalışıyor, ama -e veya -f değil.
pauljm

2
@Flimm, bu yüzden sadece bir dosya adının alınıp alınmadığını test etmek istersem (hedef olmayan bir dosya veya symlink olsun) bunu yapmanın en iyi yolu nedir? görünüşe göre -e çalışmıyor
dragonxlwang

38

Bir sembolik bağlantının varlığını ve onunla bozuk olmadığını kontrol edebilirsiniz:

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

Yani, tam çözüm:

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 symlink, kırık veya değil olup olmadığını test edin. -E ile birleştirerek bağlantının da geçerli olup olmadığını test etmek mümkündür (bir dizine veya dosyaya bağlanır). Bu bakış açısını yakalamayı önemli bulduğum için bu çözümleri oylayarak değerlendiriyorum.
Torbjörn Österdahl

14

Belki de aradığınız şey budur. Bir dosyanın var olup olmadığını ve bağlantı olmadığını kontrol etmek için.

Bu komutu deneyin:

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

8

Kullanmaya ne dersiniz 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

Dosya gerçekten sembolik bir bağlantı mı? Değilse, olağan varoluş testi -rveya-e .

Bkz man test.


3

Dosya varlığını test ediyorsanız, -e değil -e istemezsiniz. Bir sembolik bağlantı için L testleri.


Bir sembolik bağın var olup olmadığını görmek istiyorum. ! -h veya! -L sembolik linkler için çalışmalı,! -e aksi şekilde çalışmalıdır.
ayı

3
Ne istediğiniz açık değil. Dosya var ve bir sembolik değil mi? Sonra hem -e hem de ! -H'yi test edin .
Andrew Lazarus

3
  1. ilk önce bu stille yapabilirsiniz:

    mda="/usr/mda"
    if [ ! -L "${mda}" ]; then
      echo "=> File doesn't exist"
    fi
  2. daha gelişmiş bir tarzda yapmak istiyorsanız, aşağıdaki gibi yazabilirsiniz:

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

yukarıdakilerin sonucu şöyledir:

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

Dosya varsa ancak bir bağlantı değilse veya sarkan bir bağlantıysa ilk çağırma yanlıştır. İkincisi, yol sarkan bir sembolikse yanlıştır.
Jonathan Tomer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.