Cara memeriksa apakah ada symlink

208

Saya mencoba memeriksa apakah ada symlink di bash. Inilah yang saya coba.

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

Namun, itu tidak berhasil. Jika '!' ditinggalkan, tidak pernah dipicu. Dan jika '!' apakah ada, itu memicu setiap waktu.

beruang
sumber
2
berapa nilainya, jika Anda menggunakan [[! -D $ mda]] berfungsi dengan baik ..
DMin

Jawaban:

328

-Lmengembalikan true jika "file" ada dan merupakan tautan simbolik (file tertaut mungkin ada atau tidak ada). Anda ingin -f(mengembalikan true jika file ada dan merupakan file biasa) atau mungkin hanya -e(mengembalikan true jika file ada terlepas dari jenisnya).

Menurut manual GNU , -hidentik dengan -L, tetapi menurut manual BSD , itu tidak boleh digunakan:

-h file Benar jika file ada dan merupakan tautan simbolis. Operator ini dipertahankan untuk kompatibilitas dengan versi program ini sebelumnya. Jangan mengandalkan keberadaannya; gunakan -L sebagai gantinya.

drysdam
sumber
2
Saya mencari untuk melihat apakah symlink TIDAK ADA. ! -h atau! -L harus bekerja untuk symlink,! -e harus bekerja sebaliknya.
beruang
48
Untuk bantuan siapa pun yang menemukan ini melalui Google seperti yang saya lakukan, sintaks penuh menggunakan !adalah if ! [ -L $mda ]; then .... fi yaitu menempatkan tanda seru di luar kurung persegi.
Sam
19
Hanya ingin menambahkan sedikit sesuatu ke ujung yang diberikan oleh @Sam; ketika melakukan operasi semacam ini pastikan untuk memasukkan nama file Anda dalam tanda kutip, untuk mencegah masalah dengan spasi putih. mis. if [ ! -L "$mda" ]; then ... fi(catatan: if [ ! ... ]dan if ! [ ... ]identik :)
Thomas Vervest
2
apakah Anda benar-benar melihat perbedaan antara -L dan -h? di bash saya (versi 4.2.53 (1) -release (x86_64-redhat-linux-gnu) man bash identik untuk -L dan -h dan mereka berperilaku sama, yaitu mereka memeriksa file yang sebenarnya adalah tautan dan tidak tidak peduli apakah
tautannya
3
Ya, -Ldan -hadalah sama . man testjuga mengkonfirmasi ini.
Sparhawk
39

-L adalah tes untuk file yang ada dan juga merupakan tautan simbolik

Jika Anda tidak ingin menguji apakah file tersebut merupakan tautan simbolik, tetapi cukup uji untuk melihat apakah file tersebut ada terlepas dari jenisnya (file, direktori, soket, dll.) Kemudian gunakan -e

Jadi jika file benar-benar file dan bukan hanya tautan simbolis Anda dapat melakukan semua tes ini dan mendapatkan status keluar yang nilainya menunjukkan kondisi kesalahan.

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
sumber
16
-e "${file}"gagal jika symlink ada tetapi targetnya tidak ada.
Flimm
1
Hasil yang sama seperti Flimm. Saya menggunakan OS X. Bagi saya, -L dan -h bekerja untuk symlink, tetapi tidak -e atau -f.
pauljm
2
@ Flimm, jadi jika saya hanya ingin menguji apakah nama file diambil (apakah itu file atau symlink tanpa target yang ada) apa cara terbaik untuk melakukannya? rupanya -e tidak bekerja
dragonxlwang
38

Anda dapat memeriksa keberadaan symlink dan tidak ada hubungannya dengan:

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

Jadi, solusi lengkapnya adalah:

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
sumber
2
-L uji apakah ada symlink, rusak atau tidak. Dengan menggabungkan dengan -e dimungkinkan untuk menguji apakah tautannya juga valid (menautkan ke direktori atau file). Tingkatkan suara untuk solusi ini, karena saya merasa penting untuk menangkap aspek ini.
Torbjörn Österdahl
14

Mungkin ini yang Anda cari. Untuk memeriksa apakah ada file dan bukan tautan.

Coba perintah ini:

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

Bagaimana kalau menggunakan 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
sumber
4

Apakah file tersebut benar-benar tautan simbolis? Jika tidak, tes untuk keberadaan yang biasa adalah -ratau -e.

Lihat man test.

DigitalRoss
sumber
3

Jika Anda menguji keberadaan file yang Anda inginkan -e tidak -L. -L tes untuk symlink.

Andrew Lazarus
sumber
Saya mencari untuk melihat apakah symlink TIDAK ADA. ! -h atau! -L harus bekerja untuk symlink,! -e harus bekerja sebaliknya.
beruang
3
Apa yang Anda inginkan tidak jelas. File ada dan bukan symlink? Kemudian uji baik -e dan! -H.
Andrew Lazarus
3
  1. pertama yang bisa Anda lakukan dengan gaya ini:

    mda="/usr/mda"
    if [ ! -L "${mda}" ]; then
      echo "=> File doesn't exist"
    fi
  2. jika Anda ingin melakukannya dengan gaya yang lebih maju, Anda dapat menuliskannya seperti di bawah ini:

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

hasil di atas seperti:

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
sumber
Doa pertama salah jika file ada tetapi bukan tautan, atau tautan menggantung. Yang kedua salah jika path adalah symlink yang menjuntai.
Jonathan Tomer