Question

J'ai un simple script bat qui copie les fichiers d'un répertoire connu vers un répertoire fourni 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 les éléments suivants

: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, l'erreur suivante s'affiche:

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

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

files was unexpected at this time.
C:\Projects\Setup>
Était-ce utile?

La solution

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.

Autres conseils

Utilisez "% ~ 1" . % ~ 1 supprime seul les guillemets environnants. Cependant, étant donné que vous ne pouvez pas savoir si le paramètre d'entrée % 1 contient des guillemets ou non, vous devez vous assurer par "% ~ 1" qu'ils ont bien été ajoutés. Ceci est particulièrement utile lors de la concaténation de variables, par exemple. convert.exe "% ~ 1.input " "% ~ 1.output"

Je pense que le problème du PO était qu'il voulait faire LES DEUX :

  • Passer un paramètre pouvant contenir des espaces
  • Teste si le paramètre est manquant

Comme plusieurs afficheurs l'ont mentionné, pour passer un paramètre contenant des espaces, vous devez entourer la valeur du paramètre actuel de guillemets doubles.

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

if "%1" == ""

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

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

qui cause les "inattendus" Erreur. Si vous utilisez plutôt

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 résoudre ce problème, utilisez tout autre caractère (à l'exception de ceux ayant une signification particulière pour DOS) au lieu des guillemets dans le test:

if [%1] == []
if .%1. == ..
if abc%1xyz == abcxyz

"% ~ 1 " travaillera la plupart du temps. Cependant, vous devez noter quelques points à ce sujet:

  1. Ce n'est pas pris en charge dans 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, prenez garde.)
  2. Cela ne rend pas les paramètres sécurisés et désinfectés. Mon observation est qu’il n’existe aucun moyen de nettoyer correctement les arguments de ligne de commande dans les scripts CMD.

Pour illustrer le deuxième point, laissez-moi vous donner un exemple:

REM example.cmd
ECHO %~1

Exécuter avec example.cmd dummy ^ & amp; DIR . L'esperluette est échappée ici ( ^ & ) pour empêcher le shell de s'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 , là où il ne devrait pas l'être.

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

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

exemple2.cmd foo ^ "^ & amp; DIR ^ & amp; ^" 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 ECHO. Vous voyez que le "% ~ 1" que vous pensez bien être cité ne sera pas cité par l'argument lui-même.

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

(EDIT: EnableDelayedExpansion ne fonctionne pas non plus dans Windows NT 4. Grâce à l'info ci-dessous: http://www.robvanderwoude.com/local.php )

Si vous avez un chemin comportant 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 le VardhanDotNet , % 1 est suffisant.

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

  • 'chaîne vide' ( " " ),
  • suivi de "c: \ programme",
  • suivi du "ici inattendu" 'Fichiers \ xxx',
  • suivi d'une chaîne vide ( ")

Notez cependant que si vous devez utiliser PWA_PATH dans votre clause IF , vous devez faire référence à si ! PWA_PATH! (d'où le enabledelayedexpansion au début du script)

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top