วิธีการตรวจสอบว่ามีการเชื่อมโยง


208

ฉันพยายามตรวจสอบว่า symlink มีอยู่ในทุบตี นี่คือสิ่งที่ฉันได้ลอง

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

อย่างไรก็ตามนั่นไม่ได้ผล ถ้า '!' ถ้า ถูกปล่อยออกไปมันจะไม่เรียก และถ้า '!' อยู่ที่นั่นมันทริกเกอร์ทุกครั้ง


2
สำหรับสิ่งที่คุ้มค่าถ้าคุณใช้ [[! -D $ mda]] ใช้ได้ดี ..
DMIN

คำตอบ:


327

-Lผลตอบแทนจริงถ้า "ไฟล์" มีอยู่และเป็นลิงค์สัญลักษณ์ (ไฟล์ที่เชื่อมโยงอาจหรืออาจไม่มีอยู่) คุณต้องการ-f(ส่งคืนค่าจริงหากไฟล์มีอยู่และเป็นไฟล์ปกติ) หรืออาจเป็นเพียงแค่-e(คืนค่าจริงถ้าไฟล์นั้นมีอยู่โดยไม่คำนึงถึงชนิด)

ตามที่manpage GNU , -hเป็นเหมือน-Lแต่ตามmanpage BSDมันไม่ควรจะใช้:

-h file เป็นจริงถ้ามีไฟล์อยู่และเป็นลิงก์สัญลักษณ์ โอเปอเรเตอร์นี้จะยังคงใช้งานได้กับโปรแกรมรุ่นก่อนหน้านี้ อย่าพึ่งพาการดำรงอยู่ของมัน ใช้ -L แทน


2
ฉันต้องการตรวจสอบว่า symlink ไม่มีอยู่จริงหรือไม่ ! -h or! -L ควรใช้งานได้กับ symlink! -e ควรทำงานเป็นอย่างอื่น
แบก

48
เพื่อช่วยให้ทุกคนที่ค้นพบสิ่งนี้ผ่านทาง Google เช่นเดียวกับฉันการใช้ไวยากรณ์!ทั้งหมดif ! [ -L $mda ]; then .... fi คือใส่เครื่องหมายอัศเจรีย์นอกวงเล็บเหลี่ยม
Sam

19
แค่อยากจะเพิ่มอะไรเล็ก ๆ น้อย ๆ ให้กับทิปที่ @Sam มอบให้; เมื่อทำการดำเนินการประเภทต่าง ๆ เหล่านี้ตรวจสอบให้แน่ใจว่าได้ใส่ชื่อไฟล์ของคุณในเครื่องหมายคำพูดเพื่อป้องกันปัญหาเกี่ยวกับช่องว่าง เช่นif [ ! -L "$mda" ]; then ... fi(หมายเหตุ: if [ ! ... ]และif ! [ ... ]เหมือนกัน :)
Thomas Vervest

2
คุณเห็นความแตกต่างระหว่าง -L และ -h หรือไม่ ในทุบตีของฉัน (รุ่น 4.2.53 (1) - ปล่อย (x86_64-redhat-linux-gnu) ทุบตีคนเหมือนกันสำหรับทั้ง -L และ -h และพวกเขาทำงานเหมือนกันคือพวกเขาตรวจสอบว่าไฟล์จริงเป็นลิงค์และสวม ไม่ว่าจะมีการเชื่อมโยงไปยังไฟล์หรือไม่
philippe lhardy

3
ใช่-Lและ-hเป็นแบบเดียวกัน man testยังยืนยันสิ่งนี้
Sparhawk

39

-L คือการทดสอบสำหรับไฟล์ที่มีอยู่และยังเป็นลิงค์สัญลักษณ์

หากคุณไม่ต้องการทดสอบไฟล์ที่เป็นลิงก์สัญลักษณ์ แต่เพียงทดสอบเพื่อดูว่ามีอยู่หรือไม่โดยไม่คำนึงถึงประเภท (ไฟล์ไดเรกทอรีซ็อกเก็ต ฯลฯ ) ให้ใช้ -e

ดังนั้นหากไฟล์เป็นไฟล์จริงๆและไม่ใช่แค่ลิงค์สัญลักษณ์คุณสามารถทำการทดสอบเหล่านี้ทั้งหมดและรับสถานะการออกซึ่งค่าระบุเงื่อนไขข้อผิดพลาด

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}"ล้มเหลวหาก symlink มีอยู่ แต่ไม่มีเป้าหมาย
Flimm

1
ผลเช่นเดียวกับ Flimm ฉันใช้ OS X สำหรับฉันแล้ว -L และ -h ทำงานกับ symlink ได้ แต่ไม่ใช่ -e หรือ -f
pauljm

2
@Flimm ดังนั้นหากฉันต้องการทดสอบว่ามีการใช้ชื่อไฟล์ (ไม่ว่าจะเป็นไฟล์หรือ symlink ที่ไม่มีเป้าหมาย) สิ่งที่ดีที่สุดในการทำคืออะไร? apparently -e ไม่ทำงาน
dragonxlwang

38

คุณสามารถตรวจสอบการมีอยู่ของ symlink ได้และมันจะไม่แตกหักด้วย:

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

ดังนั้นทางออกที่สมบูรณ์คือ:

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
- ทดสอบว่ามี symlink เสียหรือไม่ โดยการรวมกับ -e คุณสามารถทดสอบว่าลิงก์นั้นใช้ได้หรือไม่ (ลิงก์ไปยังไดเรกทอรีหรือไฟล์) โหวตโซลูชันนี้เนื่องจากฉันพบว่าสำคัญที่ต้องจับภาพด้านนี้
TorbjörnÖsterdahl

14

บางทีนี่อาจเป็นสิ่งที่คุณกำลังมองหา เพื่อตรวจสอบว่ามีไฟล์อยู่หรือไม่และไม่ใช่ลิงค์

ลองคำสั่งนี้:

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

8

วิธีการเกี่ยวกับการใช้งาน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

ไฟล์นี้เป็นลิงก์สัญลักษณ์จริงๆหรือไม่ ถ้าไม่ได้การทดสอบตามปกติสำหรับการดำรงอยู่เป็นหรือ-r-e

man testดู


3

หากคุณกำลังทดสอบการมีอยู่ของไฟล์ที่คุณต้องการ -e ไม่ใช่ -L การทดสอบ -L สำหรับ symlink


ฉันต้องการตรวจสอบว่า symlink ไม่มีอยู่จริงหรือไม่ ! -h or! -L ควรใช้งานได้กับ symlink! -e ควรทำงานเป็นอย่างอื่น
แบก

3
สิ่งที่คุณต้องการไม่ชัดเจน มีไฟล์อยู่และไม่ใช่ symlink ใช่ไหม จากนั้นทดสอบทั้ง -e และ! -h
Andrew Lazarus

3
  1. ก่อนอื่นคุณสามารถทำได้ด้วยสไตล์นี้:

    mda="/usr/mda"
    if [ ! -L "${mda}" ]; then
      echo "=> File doesn't exist"
    fi
  2. ถ้าคุณต้องการที่จะทำในรูปแบบที่สูงขึ้นคุณสามารถเขียนมันเหมือนด้านล่าง:

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

ผลลัพธ์ที่ได้คือ:

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

การเรียกใช้ครั้งแรกไม่ถูกต้องหากไฟล์มีอยู่ แต่ไม่ใช่ลิงก์หรือเป็นลิงก์ที่ห้อยต่องแต่ง อย่างที่สองนั้นผิดถ้าเส้นทางนั้นเป็น symlink ที่ห้อยอยู่
Jonathan Tomer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.