Cách kiểm tra nếu một symlink tồn tại


208

Tôi đang cố kiểm tra xem một symlink có tồn tại trong bash không. Đây là những gì tôi đã thử.

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

Tuy nhiên, điều đó không làm việc. Nếu '!' bị bỏ lại, nó không bao giờ kích hoạt. Và nếu '!' là ở đó, nó kích hoạt mọi lúc.


2
với giá trị của nó, nếu bạn sử dụng [[! -D $ mda]] hoạt động tốt ..
DMin

Câu trả lời:


327

-Ltrả về true nếu "tệp" tồn tại và là một liên kết tượng trưng (tệp được liên kết có thể tồn tại hoặc không tồn tại). Bạn muốn -f(trả về true nếu tệp tồn tại và là tệp thông thường) hoặc có thể chỉ -e(trả về true nếu tệp tồn tại bất kể loại nào).

Theo manpage GNU , -hgiống hệt -L, nhưng theo manpage BSD , nó không nên được sử dụng:

-h file Đúng nếu tập tin tồn tại và là một liên kết tượng trưng. Toán tử này được giữ lại để tương thích với các phiên bản trước của chương trình này. Đừng dựa vào sự tồn tại của nó; sử dụng -L thay thế.


2
Tôi đang tìm kiếm để xem liệu một liên kết tượng trưng KHÔNG tồn tại. ! -h hoặc! -L nên hoạt động cho các liên kết tượng trưng ,! -e nên hoạt động khác.
chịu

48
Để giúp đỡ bất cứ ai tìm thấy điều này thông qua Google như tôi đã làm, đầy đủ cú pháp sử dụng !if ! [ -L $mda ]; then .... fi tức là đặt dấu chấm than bên ngoài dấu ngoặc vuông.
Sam

19
Chỉ muốn thêm một chút gì đó vào mẹo được đưa ra bởi @Sam; khi thực hiện các loại thao tác này, hãy đảm bảo đặt tên tệp của bạn trong dấu ngoặc kép, để ngăn chặn sự cố với khoảng trắng. ví dụ: if [ ! -L "$mda" ]; then ... fi(lưu ý: if [ ! ... ]if ! [ ... ]giống hệt nhau :)
Thomas Vervest

2
Bạn có thực sự thấy sự khác biệt giữa -L và -h không? trong bash của tôi (phiên bản 4.2.53 (1) -release (x86_64-redhat-linux-gnu) man bash giống hệt nhau cho cả -L và -h và chúng hoạt động giống nhau, tức là chúng kiểm tra xem thực tế tệp có phải là liên kết và không 'không quan tâm liệu liên kết đến tập tin có tồn tại hay không.
philippe lhardy

3
Vâng, -L-hcùng . man testcũng xác nhận điều này.
Sparhawk

39

-L là bài kiểm tra cho tập tin tồn tại và cũng là một liên kết tượng trưng

Nếu bạn không muốn kiểm tra xem tệp có phải là một liên kết tượng trưng không, nhưng chỉ cần kiểm tra xem nó có tồn tại bất kể loại (tệp, thư mục, ổ cắm, v.v.) không, hãy sử dụng -e

Vì vậy, nếu tệp thực sự là tệp và không chỉ là một liên kết tượng trưng, ​​bạn có thể thực hiện tất cả các kiểm tra này và nhận trạng thái thoát có giá trị cho biết tình trạng lỗi.

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}"thất bại nếu symlink tồn tại nhưng mục tiêu của nó không tồn tại.
Flimm

1
Kết quả tương tự như Flimm. Tôi đang dùng OS X. Đối với tôi, -L và -h hoạt động cho các liên kết tượng trưng, ​​nhưng không phải -e hoặc -f.
pauljm

2
@Flimm, vì vậy nếu tôi chỉ muốn kiểm tra xem tên tệp có được lấy hay không (dù đó là tệp hoặc liên kết tượng trưng mà không có mục tiêu hiện tại) thì cách tốt nhất để làm điều đó là gì? hình như -e không hoạt động
dragonxlwang

38

Bạn có thể kiểm tra sự tồn tại của một liên kết tượng trưng và nó không bị hỏng với:

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

Vì vậy, giải pháp hoàn chỉnh là:

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 kiểm tra nếu có một liên kết tượng trưng, ​​bị hỏng hay không. Bằng cách kết hợp với -e, có thể kiểm tra xem liên kết có hợp lệ không (liên kết đến một thư mục hoặc tệp). Bỏ phiếu cho giải pháp này, vì tôi thấy điều quan trọng là phải nắm bắt khía cạnh này.
Torbjorn Österdahl

14

Có lẽ đây là những gì bạn đang tìm kiếm. Để kiểm tra nếu một tập tin tồn tại và không phải là một liên kết.

Hãy thử lệnh này:

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

8

Làm thế nào về việc sử dụng 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

Là tập tin thực sự là một liên kết tượng trưng? Nếu không, kiểm tra thông thường cho sự tồn tại là -rhoặc-e .

Xem man test.


3

Nếu bạn đang kiểm tra sự tồn tại của tệp bạn muốn -e không -L. -L kiểm tra một liên kết tượng trưng.


Tôi đang tìm kiếm để xem liệu một liên kết tượng trưng KHÔNG tồn tại. ! -h hoặc! -L nên hoạt động cho các liên kết tượng trưng ,! -e nên hoạt động khác.
chịu

3
Những gì bạn muốn là không rõ ràng. Các tập tin tồn tại và không phải là một liên kết tượng trưng? Sau đó kiểm tra cả -e và! -H.
Andrew Lazarus

3
  1. đầu tiên bạn có thể làm với phong cách này:

    mda="/usr/mda"
    if [ ! -L "${mda}" ]; then
      echo "=> File doesn't exist"
    fi
  2. Nếu bạn muốn làm theo phong cách nâng cao hơn, bạn có thể viết nó như dưới đây:

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

kết quả ở trên giống như:

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

Yêu cầu đầu tiên là sai nếu tệp tồn tại nhưng không phải là một liên kết hoặc là một liên kết lơ lửng. Thứ hai là sai nếu đường dẫn là một symlink lơ lửng.
Jonathan Tomer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.