¿Cómo encuentro enlaces simbólicos rotos automáticamente en Windows?

11

No estoy seguro de si este es un mal estilo, pero estoy haciendo esta pregunta aquí porque no pude encontrar la respuesta en otro lado, y luego encontré una solución por mi cuenta. Me interesaría ver las soluciones de otras personas, pero después de unos días publicaré las mías.

En mi caso específico, estoy ejecutando Windows 7, pero me interesarían las respuestas para otras versiones anteriores de Windows. Me doy cuenta de que una respuesta es "instalar una versión de Unix find, y luego resolver en cuanto a Unix ", pero quería una solución más "nativa".

EDITAR 2012-07-17: Aclaración: por "automáticamente" idealmente quiero decir algo que puedo ejecutar como parte de un script, en lugar de una herramienta GUI que hace todo el trabajo con solo presionar un botón, porque querré hacer esta desatendida.

HughG
fuente

Respuestas:

4

algo retrasado, pero aquí está mi propia respuesta a mi pregunta. Básicamente es el mismo enfoque que el habitual en Unix: encuentre todos los enlaces, luego actúe sobre los rotos; No es tan conciso. La secuencia de comandos a continuación elimina enlaces simbólicos rotos, después de descargar alguna información sobre ellos.

@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
HughG
fuente
3

Las siguientes herramientas pueden ayudarlo a encontrar y eliminar enlaces simbólicos en Windows

  1. Enlace de enlace mágico
  2. Diskjunction
Abhijeet Kasurde
fuente
Ambas son herramientas prácticas de GUI, pero no estaba claro: quiero algo que pueda ejecutar en un script. He editado la pregunta para aclarar.
HughG
2

También puede probar una utilidad de código abierto llamada SageLinks , que muestra y verifica las uniones de Windows NTFS, enlaces simbólicos e incluso accesos directos.

Nikolay Raspopov
fuente
0

Usando cygwin64 (find, xargs, sh, ls) (probado en win7 para enlaces duros ntfs muertos)

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

Nota: test -e no funciona como se esperaba con el enlace rígido ntfs muerto.

mosh
fuente
1
Gracias @mosh pero, como dije, quiero algo que no implique "instalar una versión de las utilidades de Unix", porque quiero un script que otros puedan ejecutar sin preparación.
HughG