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>
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.
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"
"% ~ 1" fonctionnera la plupart du temps. Cependant, il y a quelques points à noter pour cela:
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 )
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?
@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:
""
),""
)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)
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.