Come posso trovare automaticamente i collegamenti simbolici rotti su Windows?


11

Non sono sicuro che questo sia un cattivo stile, ma sto facendo questa domanda qui perché non sono riuscito a trovare la risposta altrove, e quindi ho trovato una soluzione da solo. Sarei interessato a vedere le soluzioni di altre persone, ma dopo qualche giorno pubblicherò le mie.

Nel mio caso specifico, sono in esecuzione su Windows 7, ma sarei interessato a risposte per altre versioni precedenti di Windows. Mi rendo conto che una risposta è "installa una versione di Unix find, e poi risolvi come per Unix ", ma volevo una soluzione più "nativa".

EDIT 2012-07-17: Chiarimento: per "automaticamente" intendo idealmente qualcosa che posso eseguire come parte di uno script, piuttosto che uno strumento GUI che fa tutto il lavoro con la semplice pressione di un pulsante, perché voglio fare questo incustodito.

Risposte:


4

un po 'tardivo, ma ecco la mia risposta alla mia domanda. È fondamentalmente lo stesso approccio del solito su Unix: trova tutti i collegamenti, quindi agisci su quelli interrotti; non è così conciso. Lo script seguente elimina i collegamenti simbolici rotti, dopo aver scaricato alcune informazioni su di essi.

@echo off

rem Grab the list of directories to scan, before we "pushd to dir containing this script",
rem so that we can have the default be "dir from which we ran this script".
setlocal
if x%CD%==x (echo Command Extensions must be enabled. && goto :eof)
set ORIGINAL_DIR=%CD%

pushd %~dp0

set DIRS_TO_CHECK=%*
if x%DIRS_TO_CHECK%==x (
    set DIRS_TO_CHECK=.
)

rem Find all the files which are both links (/al) and directories (/ad).
rem (We use "delims=" in case any paths have a space; space is a delim by default.)
rem If not, delete it (and assume something else will fix it later :-).
echo Deleting broken symlinks ...
echo.
for %%D in (%ORIGINAL_DIR%\%DIRS_TO_CHECK%) do (
    echo Checking %%D
    echo.
    pushd %%D
    if errorlevel 1 (
        echo Cannot find "%%D"
        echo.
        goto :Next_Dir
    )
    rem Clean up broken directory links.
    for /f "usebackq delims=" %%L in (`dir /adl /b`) do (
        rem Check the directory link works.
        rem Redirecting to nul just to hide "The system cannot find the file specified." message.
        pushd "%%L" >nul 2>&1
        if errorlevel 1 (
            echo Deleting broken directory symlink "%%L".
            rem First dump out some info on the link, before we delete it.
            rem I'd rather a more human-readable form, but don't know how to get that.
            fsutil reparsepoint query "%%L"
            rmdir "%%L"
            echo.
        ) else (
            popd
        )
    )
    rem Clean up broken file (non-directory) links.
    for /f "usebackq delims=" %%L in (`dir /a-dl /b`) do (
        rem Check the file link works.
        rem Redirecting to nul just to hide "The system cannot find the file specified." message.
        copy "%%L" nul >nul 2>&1
        if errorlevel 1 (
            echo Deleting broken file symlink "%%L".
            rem First dump out some info on the link, before we delete it.
            rem I'd rather a more human-readable form, but don't know how to get that.
            fsutil reparsepoint query "%%L"
            rm "%%L"
            echo.
        ) else (
            popd
        )
    )
    popd
    :Next_Dir
    rem Putting a label on the line immediately before a ')' causes a batch file parse error, hence this comment.
)
echo Deleting broken symlinks ... done.

:Finally
popd

3

I seguenti strumenti possono aiutarti a trovare e rimuovere il collegamento simbolico in Windows

  1. Junction Link Magic
  2. Diskjunction

Questi sono entrambi utili strumenti della GUI, ma non ero chiaro: voglio qualcosa che posso eseguire in uno script. Ho modificato la domanda per chiarire.
HughG,

2

Puoi anche provare un'utilità open source chiamata SageLinks , che mostra e controlla giunzioni di Windows NTFS, collegamenti simbolici e persino scorciatoie.


0

Utilizzo di cygwin64 (find, xargs, sh, ls) (testato su win7 per collegamenti hard ntfs morti)

c:\>   find ./ -type l |  xargs -I % sh -c "ls % > /dev/null 2>&1 || echo %" 

Nota: test -e non funziona come previsto con l'hardlink ntfs morto.


1
Grazie @mosh ma, come ho detto, voglio qualcosa che non implichi "installare una versione di Unix utils" - perché voglio uno script che altri possano eseguire senza preparazione.
HughG,
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.