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.