Cambiar temporalmente el directorio para un comando de archivo por lotes único

Cambiar temporalmente el directorio para un comando de archivo por lotes único

En el scripting de shell, si necesito ejecutar un comando desde un directorio, puedo usar un subshell para asegurarme de regresar al contexto original:

(cd temporary/new/directory ; command)
# now I am still in original directory

¿Se puede hacer esto en archivos por lotes de Windows (o archivos cmd)?

Hacer lo mismo en archivos por lotes me deja en el nuevo directorio.

Puedo hacer:

pushd temporary\new\directory && command && popd

Pero el popd depende del éxito de command.

¿Algunas ideas?

Respuesta1

Si lo haces:

pushd \windows && foobar && popd

quedarás (como indicas) en la carpeta \windows. Intentar:

pushd \windows & foobar & popd

y deberías encontrarte de nuevo donde empezaste.

Respuesta2

De forma predeterminada, los archivos por lotes de Windows se ejecutan en el contexto del shell principal (lo cual es inusual para los usuarios de Unix, donde sourcese necesita una configuración explícita, pero era la única posibilidad en MS-DOS). Esto significa que los cambios de directorio y las variables de entorno también afectan el shell interactivo original.

Colóquelo setlocalen la parte superior de su secuencia de comandos para que se ejecute en su propio contexto; entonces puede usarlo de manera segura cddentro de la secuencia de comandos.

Respuesta3

Como se mencionó anteriormente, grawity pushd \windows && (foobar & popd)funcionaría mejor pushd \windows & foobar & popdporque este último puede fallar si no existe dicho directorio.

Además, usar setlocaly endlocalle permite tener múltiples entornos locales, así por ejemplo podría tener:

setlocal

cd dir

command

endlocal

Ahora estaría de vuelta en su directorio original.

Respuesta4

Aplaudo la sugerencia de Grawity de colocarlo setlocalal comienzo de su secuencia de comandos por lotes, pero agregaría el hecho de que puede tener múltiples bloques setlocal/ anidados endlocal, por lo que una respuesta más relevante a la pregunta podría ser

@echo off
setlocal
cddir1
  ...
setlocal
cddir2
command
endlocal
:: Now I am back indir1
  ...

Y, por supuesto, si desea que el comando se ejecute sólo si cdeldir2tiene éxito, digamoscddir2&&command.

Tenga en cuenta que el bloque setlocal/ endlocalcrea un entorno localizado, por lo que cualquier variable que establezca o cambie en dicho bloque volverá a su valor anterior después del archivo endlocal.

información relacionada