Barra rovesciata su collegamenti simbolici alle directory


8

Sto cercando di emulare il processo di risoluzione del percorso (vedi la pagina man path_resolution) in sistemi unix-like.

Il mio sistema operativo è Linux con core GNU 8.7.

Al fine di chiarire il significato di extra / "in risoluzione", ho fatto le seguenti cose in una shell:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link

Tutto andava bene, perché this_is_link è un link simbolico e l'ho rimosso. Ma mentre provi:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link/

Echeggiò rm: cannot remove 'this_is_link/': Is a directory

Bene, il finale "/" ha causato il seguito di symlink, ho pensato. Quindi, ho provato un altro comando:rmdir this_is_link/

E un risultato divertente è venuto fuori: rmdir: failed to remove 'this_is_link/': Not a directory

Non è quello che mi aspettavo. Quindi ho chiesto al mio amico di confermare se si potesse ottenere lo stesso risultato sul suo sistema. Aveva una versione inferiore di coreutils di me. E il risultato è stato sorprendente, non importa rmo rmdir 'this_is_link/', si Not a directoryverifica lo stesso errore .

E un altro amico lo ha appena provato sul suo Mac OS, il risultato è: rm=> 'È una directory', rmdir=> la directory è stata cancellata con successo, il collegamento è rimasto .

Ci sono delle specifiche sull'esatto comportamento della risoluzione del percorso?


Risposte:


7

La specifica POSIX / Single Unix specifica che un nome percorso con una barra finale deve fare riferimento a una directory (vedere le definizioni di base §4.11 risoluzione percorso ). foo/è infatti definito come equivalente a foo/.(ai fini della risoluzione del percorso, non durante la manipolazione dei nomi di file; basenamee dirnameignora le barre finali). La maggior parte delle implementazioni lo rispetta, ma ci sono alcune eccezioni.

Questo spiega il comportamento di rm this_is_link/: è equivalente a rm this_is_link/., dove l'argomento è chiaramente una directory.

rmdir this_is_link/dovrebbe fare riferimento allo stesso modo alla directory. Che non funzioni sul tuo computer è un bug nei coreutils GNU. OSX si sta comportando correttamente qui.


Questo è esattamente quello di cui avevo bisogno, grazie ragazzo!
— ymfoi,

-1

La mia opinione:

  • '' rm link / '' fallisce perché rm guarda l'ultimo carattere, vede che è una barra, fornisce la diagnostica (non proprio corretta) che hai visto;
  • '' rmdir link / '' non funziona bene: link non è una directory, è un symlink
  • '' rm link '' funzionerà correttamente

Per inciso, la risoluzione del percorso ha ben poco a che fare con questo, sembra solo che '' rm '' stia tagliando un angolo piuttosto che (correttamente) invocando "stat" su un argomento (che è ciò che sta facendo rmdir).

Saluti.


1
In realtà, il contrario sembra essere vero: rmchiama stat (beh, newfstatat, in realtà, con l' AT_SYMLINK_NOFOLLOWopzione) e rifiuta di procedere ulteriormente, mentre rmdir in realtà chiama rmdir (2), ma ottiene ENOTDIR.
— Ansgar Esztermann,

@AnsgarEsztermann AT_SYMLINK_NOFOLLOWimpedirà che segua il collegamento simbolico, quindi rm dovrebbe eliminare il collegamento stesso invece di stampare "Non una directory" che non corrisponde alla circostanza.
— ymfoi,

Da un breve controllo con stat (1), la barra finale sovrascriverà l'opzione. L'output di state stat -Ldifferisce solo se l'argomento viene fornito senza una barra finale.
— Ansgar Esztermann,

@AnsgarEsztermann Oh, vedo ... Grazie. Che ne dite dei diversi effetti sul diverso evironment? Qualche idea?
— ymfoi,

1
È l'opposto: sulla macchina di ymfoi, si rmsta comportando correttamente e rmdirnon lo è. Il trailing /dovrebbe costringerli a trattare il loro argomento come una directory, secondo lo standard POSIX. Vedi la mia risposta per i riferimenti .
— Gilles 'SO- smetti di essere malvagio' il
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.