Chemin de passe avec des espaces comme paramètre au fichier bat

j'ai un simple script bat qui copie des fichiers à partir d'un répertoire connu vers un répertoire donné par l'utilisateur. Comment puis-je passer le chemin (il peut contenir des espaces) pour 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 FilesPWA"
        rem
        echo You have not specified your PWA url.
        echo Default will be assumed: C:Program FilesPWA. 
        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 l'erreur suivante:

C:ProjectsSetup>install.cmd "C:program files (x86)"

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

files was unexpected at this time.
C:ProjectsSetup>
46
demandé sur Bill the Lizard 2009-01-23 17:42:53

7 réponses

intéressant. J'adore collectionner les citations sur citations de manutention dans cmd/commande.

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

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

15
répondu vrdhn 2009-01-23 16:10:32

utiliser "%~1" . %~1 seul supprime les guillemets environnants. 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. Cela est particulièrement utile lorsque l'on concaténue des variables, par exemple convert.exe "%~1.input" "%~1.output"

89
répondu zikaS 2018-03-18 20:51:25

je pense que l'OP est le problème était qu'il veut faire les DEUX de ce qui suit:

  • passer un paramètre qui peut contenir des espaces
  • Test si le paramètre est manquant

comme plusieurs affiches l'ont mentionné, pour passer un paramètre contenant des espaces, vous devez entourer la valeur réelle du paramètre de guillemets doubles.

pour vérifier si un paramètre est manquant, la méthode que j'ai toujours apprise était:

if "%1" == ""

Cependant, si le paramètre est cité (comme il doit l'être si la valeur contient des espaces), cela devient

if ""actual parameter value"" == ""

qui provoque l'erreur" inattendue". Si vous utilisez

if %1 == ""

alors l'erreur ne se produit plus pour les valeurs citées. Mais dans ce cas, le test ne fonctionne plus lorsque la valeur est manquante -- il devient

if  == ""

pour corriger ceci, utilisez tous les autres caractères (sauf ceux qui ont une signification spéciale Pour DOS) au lieu des guillemets dans le test:

if [%1] == []
if .%1. == ..
if abc%1xyz == abcxyz
14
répondu 2009-05-05 16:29:25

"%~1" fonctionne la plupart du temps. Cependant, il y a quelques choses que vous devez noter pour cela:

  1. il n'est pas supporté par Windows NT 4.0. Vous avez besoin de Windows 2000 ou plus tard. (Si vous codez un script compatible avec un ancien OS, attention.)
  2. il ne rend pas les paramètres sécurisé et aseptisé. 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, permettez-moi de donner un exemple:

REM example.cmd
ECHO %~1

Courir avec example.cmd dummy^&DIR . L'ampersand est ici échappé ( ^& ) pour empêcher shell d'interpréter comme un délimiteur de commandes, de sorte qu'il devient une partie de l'argument passé au script. Le DIR est interprété comme une commande à l'intérieur du sous-shell exécutant le script , où il ne devrait pas.

citant il pourrait travailler un certain temps, mais toujours dans l'insécurité:

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

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

donc, aucun moyen de sécuriser l'analyse des arguments.

(EDIT: EnableDelayedExpansion ne fonctionne pas non plus sous Windows NT 4. Merci à l'info ici: http://www.robvanderwoude.com/local.php )

6
répondu Explorer09 2015-03-06 08:35:30

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
répondu 2009-01-23 14:44:36
@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 suffisant.

"%1%" ajouterait des citations autour des citations: ""c:\Program Files\xxx"" qui signifie:

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

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

2
répondu VonC 2017-05-23 11:54:31

si votre chemin contient de l'espace, essayez %~s1 . Cela permettra d'éliminer l'espace et ajoute ~1 à votre chemin et plus important encore, il renvoie le chemin absolu de votre fichier. Essayez de l'utiliser.

2
répondu Prabhu RK 2012-08-31 11:15:23