Come verificare se esiste un collegamento simbolico


208

Sto cercando di verificare se esiste un collegamento simbolico in bash. Ecco cosa ho provato.

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

Tuttavia, ciò non funziona. Se '!' viene lasciato fuori, non si innesca mai. E se '!' c'è, si innesca ogni volta.


2
per quanto vale, se usi [[! -D $ mda]] funziona bene ..
DMin

Risposte:


328

-Lrestituisce vero se il "file" esiste ed è un collegamento simbolico (il file collegato può o non può esistere). Volete -f(restituisce vero se il file esiste ed è un file normale) o forse solo-e (restituisce true se il file esiste indipendentemente dal tipo).

Secondo la manpage GNU , -hè identico a -L, ma secondo la manpage BSD , non dovrebbe essere usato:

-h file Vero se il file esiste ed è un collegamento simbolico. Questo operatore viene mantenuto per compatibilità con le versioni precedenti di questo programma. Non fare affidamento sulla sua esistenza; usare -L invece.


2
Sto cercando di vedere se un link simbolico NON esiste. ! -h o! -L dovrebbe funzionare per i collegamenti simbolici,! -e dovrebbe funzionare diversamente.
reca il

48
Per aiutare chiunque lo trovi tramite Google come ho fatto io, la sintassi completa usando !è if ! [ -L $mda ]; then .... fi cioè mettere il punto esclamativo fuori dalle parentesi quadre.
Sam,

19
Volevo solo aggiungere qualcosa al suggerimento dato da @Sam; quando si eseguono questo tipo di operazioni assicurarsi di inserire il nome del file tra virgolette, per evitare problemi con gli spazi bianchi. ad es. if [ ! -L "$mda" ]; then ... fi(nota: if [ ! ... ]e if ! [ ... ]sono identici :)
Thomas Vervest il

2
vedi davvero una differenza tra -L e -h? nel mio bash (versione 4.2.53 (1) -release (x86_64-redhat-linux-gnu) man bash è identico sia per -L che -h e si comportano allo stesso modo, cioè controllano che il file sia effettivamente un link e don non importa se esiste il link al file.
Philippe Lhardy,

3
-Le -hsono uguali . man testlo conferma anche questo.
Sparhawk,

39

-L è il test per il file esiste ed è anche un collegamento simbolico

Se non si desidera verificare che il file sia un collegamento simbolico, ma verificare solo se esiste indipendentemente dal tipo (file, directory, socket ecc.), Utilizzare -e

Quindi, se il file è veramente un file e non solo un collegamento simbolico, puoi fare tutti questi test e ottenere uno stato di uscita il cui valore indica la condizione di errore.

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}"non riesce se il collegamento simbolico esiste ma la sua destinazione non esiste.
Flimm,

1
Stesso risultato di Flimm. Sono su OS X. Per me, -L e -h funzionano per i collegamenti simbolici, ma non -e o -f.
pauljm,

2
@Flimm, quindi se voglio solo verificare se viene preso un nome file (che si tratti di un file o di un link simbolico senza destinazione esistente) qual è il modo migliore per farlo? apparentemente -e non funziona
dragonxlwang,

38

Puoi verificare l'esistenza di un link simbolico e che non sia rotto con:

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

Quindi, la soluzione completa è:

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 se c'è un collegamento simbolico, rotto o no. Combinando con -e è possibile verificare se anche il collegamento è valido (collegamento a una directory o file). Voto positivo su queste soluzioni, poiché trovo importante catturare questo aspetto.
Torbjörn Österdahl,

14

Forse questo è quello che stai cercando. Per verificare se esiste un file e non è un collegamento.

Prova questo comando:

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

8

Che ne dici di usare 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

Il file è davvero un collegamento simbolico? In caso contrario, il solito test per l'esistenza è -ro -e.

Vedere man test.


3

Se si sta verificando l'esistenza di un file, si desidera -e non -L. -L test per un collegamento simbolico.


Sto cercando di vedere se un link simbolico NON esiste. ! -h o! -L dovrebbe funzionare per i collegamenti simbolici,! -e dovrebbe funzionare diversamente.
reca il

3
Quello che vuoi non è chiaro. Il file esiste e non è un link simbolico? Quindi prova sia -e che! -H.
Andrew Lazarus,

3
  1. per prima cosa puoi fare con questo stile:

    mda="/usr/mda"
    if [ ! -L "${mda}" ]; then
      echo "=> File doesn't exist"
    fi
  2. se vuoi farlo in uno stile più avanzato puoi scriverlo come di seguito:

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

il risultato di cui sopra è come:

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

La prima chiamata è errata se il file esiste ma non è un collegamento o è un collegamento pendente. Il secondo è sbagliato se il percorso è un collegamento simbolico penzolante.
Jonathan Tomer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.