web-dev-qa-db-fra.com

Passer le chemin avec des espaces comme paramètre pour bat le fichier

J'ai un script de batte simple qui copie des fichiers d'un répertoire connu dans un répertoire donné par l'utilisateur. Comment puis-je transmettre le chemin (il peut contenir des espaces) à mon script et l'utiliser avec la commande xcopy?


Dans mon code j'ai le suivant

:READ_PWA_PATH
    if "%1" == "" ( 
        rem Set default path
        set PWA_PATH="C:\Program Files\PWA"
        rem
        echo You have not specified your PWA url.
        echo Default will be assumed: C:\Program Files\PWA. 
        choice /C:YN /M:"Do you wish to continue [Y] or cancel the script [N]?"
            IF ERRORLEVEL ==2 GOTO CANCEL
            IF ERRORLEVEL ==1 GOTO READ_WSS_SERVER_EXTENSIONS_PATH
        GOTO END
    ) else (
        set PWA_PATH=%1
    )

Si j'appelle simplement le script, j'obtiens le message d'erreur suivant:

C:\Projects\Setup>install.cmd "C:\program files (x86)"

-----------------
SETUP SCRIPT
-----------------

files was unexpected at this time.
C:\Projects\Setup>
58
kjv

Intéressant. J'aime collecter des citations sur la gestion des citations dans cmd/command.

Vos scripts particuliers sont corrigés en utilisant% 1 au lieu de "% 1" !!!

En ajoutant un "écho" (ou en supprimant un écho), vous auriez facilement pu le découvrir.

21
vrdhn

Utilisation "%~1". %~1 seul supprime les citations environnantes. Cependant, comme vous ne pouvez pas savoir si le paramètre d'entrée %1 a des guillemets ou non, vous devez vous assurer par "%~1" qu'ils sont ajoutés à coup sûr. Ceci est particulièrement utile lors de la concaténation de variables, par exemple. convert.exe "%~1.input" "%~1.output"

102
zikaS

"% ~ 1" fonctionnera la plupart du temps. Cependant, il y a quelques points à noter pour cela:

  1. Ce n'est pas supporté par Windows NT 4.0. Vous avez besoin de Windows 2000 ou version ultérieure. (Si vous codez un script compatible avec l'ancien système d'exploitation, méfiez-vous.)
  2. Cela ne rend pas les paramètres sécurisés et désinfectés. Mon observation est qu'il n'y a aucun moyen de nettoyer correctement les arguments en ligne de commande dans les scripts CMD.

Pour démontrer le second point, laissez-moi vous donner un exemple:

REM example.cmd
ECHO %~1

Courir avec example.cmd dummy^&DIR. La esperluette est échappée ici (^&) pour empêcher Shell d'interpréter en tant que délimiteur de commande, de sorte qu'il fasse partie de l'argument transmis au script. Le répertoire DIR est interprété comme une commande à l'intérieur du sous-shell exécutant le script, où il ne devrait pas.

Citer cela pourrait fonctionner quelque temps, mais toujours pas sûr:

REM example2.cmd
SETLOCAL EnableExtensions EnableDelayedExpansion
SET "arg1=%~1"
ECHO "%~1"
ECHO !arg1:"=!

example2.cmd foo^"^&DIR^&^"bar va le casser. La commande DIR sera exécutée deux fois, l'une juste après SET et l'autre juste après le premier ECHO. Vous voyez que le "%~1" vous pensez que la citation est bonne et que l'argument lui-même n'est pas cité.

Donc, aucun moyen de sécuriser les arguments d'analyse.

(EDIT: EnableDelayedExpansion ne fonctionne pas non plus sous Windows NT 4. Merci aux informations suivantes: http://www.robvanderwoude.com/local.php )

6
Explorer09

Si vous avez un chemin avec des espaces, vous devez l’entourer de guillemets (").

Vous ne savez pas si c'est exactement ce que vous demandez?

5
user7094
@echo off
setlocal enableextensions enabledelayedexpansion

if %1=="" (     
        rem Set default path
        set PWA_PATH="C:\Program Files\PWA"
        rem
        echo You have not specified your PWA url.
        echo Default will be assumed: C:\Program Files\PWA.     
        choice /C:YN /M:"Do you wish to continue [Y] or cancel the script [N]?"
                IF ERRORLEVEL ==2 GOTO CANCEL
                IF ERRORLEVEL ==1 GOTO READ_WSS_SERVER_EXTENSIONS_PATH
        GOTO END
    ) else (
        set PWA_PATH=%1
        @echo !PWA_PATH! vs. %1
        goto end
    )
:READ_WSS_SERVER_EXTENSIONS_PATH
echo ok
goto end
:CANCEL
echo cancelled
:end
echo. final %PWA_PATH% vs. %1

Comme VardhanDotNet mentionne, %1 est assez.

"%1%" ajouterait des guillemets autour de guillemets: ""c:\Program Files\xxx"" ce qui signifie:

  • 'chaîne vide' (""),
  • suivi de 'c:\Program',
  • suivi de "l'inattendu ici" 'Files\xxx',
  • suivi d'une chaîne vide ("")

Notez cependant que si vous devez utiliser PWA_PATH dans votre clause IF, vous devez indiquer si !PWA_PATH! (d'où le enabledelayedexpansion comme début du script)

2
VonC

Si votre chemin contient de l'espace, essayez d'utiliser %~s1. Cela supprimera l’espace et ajoutera ~1 sur votre chemin et, plus important encore, il fait référence au chemin absolu de votre fichier. Essayez de l'utiliser.

2
Prabhu RK