490 votes

Comment obtenir la liste des arguments ?

J'aimerais trouver un équivalent Windows batch à l'équivalent de Bash. $@ qui contient une liste de tous les arguments passés dans un script.

Ou je dois m'embêter avec shift ?

746voto

matt wilkie Points 1772

dancavallaro a raison, %* pour tous les paramètres de la ligne de commande (à l'exception du nom script lui-même). Vous pourriez également trouver ces éléments utiles :

%0 - la commande utilisée pour appeler le fichier batch (peut être foo , ..\foo , c:\bats\foo.bat etc.)
%1 est le premier paramètre de la ligne de commande,
%2 est le deuxième paramètre de la ligne de commande,
et ainsi de suite jusqu'à %9 (et SHIFT peut être utilisé pour ceux qui sont postérieurs au 9ème).

%~nx0 - le nom réel du fichier batch, quelle que soit la méthode d'appel (some-batch.bat)
%~dp0 - lecteur et chemin vers le script (d : \<strkeep>scripts<strkeep> )
%~dpnx0 - est le nom de chemin entièrement qualifié du script (d : \<strkeep>scripts<strkeep>\some -batch.bat)

Plus d'exemples d'informations à https://www.ss64.com/nt/syntax-args.html y https://www.robvanderwoude.com/parameters.html

17 votes

Notez que SHIFT n'affecte pas les %*, ce qui rend impossible l'utilisation de SHIFT [/n] pour des opérations quelque peu intuitives comme l'accès à la ligne de commande entière à partir du nième paramètre.

9 votes

J'ai aussi découvert que %~dpn0 retournera le lecteur et le chemin d'accès au script plus le nom du fichier batch, mais pas l'extension. J'ai trouvé cela particulièrement utile lors de la création de script batch qui appellent un fichier .ps1 avec le même nom. Essentiellement, le d fait référence au lecteur, p fait référence au chemin, n fait référence au nom du fichier, et x fait référence à l'extension. Avec cette information, vous pouvez faire pas mal de choses.

0 votes

Par curiosité, supposons que je veuille utiliser ECHO pour imprimer le chemin du fichier mais en remplaçant son extension, comment cela se passe-t-il ?

190voto

dancavallaro Points 5639

%* semble contenir tous les arguments passés au script.

1 votes

Une idée de la raison pour laquelle il ne gère pas certains caractères tels que & ? Lorsque j'essaie de récupérer le chemin de plusieurs fichiers sélectionnés (en utilisant le menu "Send To" et "%*" qui passe les arguments à un .py), la liste s'arrête aux caractères &. Ainsi, si par exemple le deuxième fichier contient un & dans son nom, la partie du nom qui suit l'élément & sera ignoré, ainsi que les fichiers restants).

3 votes

@JinSnow Le & est un caractère spécial qui signifie stop this command and start another one . Un nom de fichier contenant un & MUST être cité.

73voto

jeb Points 26035

%1 ... %n y %* contient les arguments, mais il peut être délicat d'y accéder, car le contenu sera interprété.
Il est donc impossible de traiter un tel cas avec des instructions normales.

myBatch.bat "&"^&

Chaque ligne échoue, car cmd.exe essaie d'exécuter l'une des esperluettes (le contenu de %1 est "&"& )

set var=%1
set "var=%1"
set var=%~1
set "var=%~1"

Mais il existe une solution de contournement avec un fichier temporaire.

@echo off
SETLOCAL DisableDelayedExpansion

SETLOCAL
for %%a in (1) do (
    set "prompt=$_"
    echo on
    for %%b in (1) do rem * #%1#
    @echo off
) > param.txt
ENDLOCAL

for /F "delims=" %%L in (param.txt) do (
  set "param1=%%L"
)
SETLOCAL EnableDelayedExpansion
set "param1=!param1:*#=!"
set "param1=!param1:~0,-2!"
echo %%1 is '!param1!'

L'astuce consiste à activer echo on et développer le %1 après un rem (fonctionne également avec %2 .. %*).
Mais pour être capable de rediriger la sortie de echo on vous avez besoin des deux FOR-LOOPS.

Les caractères supplémentaires * # sont utilisés pour se protéger contre des contenus tels que /? (montrerait l'aide pour REM).
Ou un signe d'insertion ^ en fin de ligne pourrait fonctionner comme un caractère multiligne.

Le FOR /F doit être utilisé avec l'expansion retardée désactivée, sinon le contenu avec " !" serait détruit.
Après avoir supprimé les caractères supplémentaires dans param1 et tu l'as eu.

Et pour utiliser param1 de manière sûre, activer l'expansion différée.

Edit : Une remarque à %0

%0 contient la commande utilisée pour appeler le lot, en préservant également la casse comme dans FoO.BaT
Mais après un appel à une fonction %0 et aussi dans %~0 contient le nom de la fonction (ou mieux la chaîne de caractères qui a été utilisée pour appeler la fonction).
Mais avec %~f0 vous pouvez toujours vous souvenir du nom du fichier.

@echo off
echo main %0, %~0, %~f0
call :myLabel+xyz
exit /b

:MYlabel
echo func %0, %~0, %~f0
exit /b

Sortie

main test.bat, test.bat, C:\temp\test.bat
func :myLabel+xyz, :myLabel+xyz, C:\temp\test.bat

8 votes

+++1 OMG - Le %~f0 Cette astuce est totalement inattendue, très cool et potentiellement très utile :-) Il n'est pas surprenant que les autres modificateurs fonctionnent de la même manière, en opérant toujours sur le fichier batch parent, même lorsqu'ils sont dans une sous-routine appelée. Cela semble mériter sa propre question-réponse - "Comment accéder au nom du lot en cours d'exécution lorsqu'on est dans un sous-programme appelé ?".

0 votes

Si je me souviens bien, vous pouvez utiliser call avec des arguments, et ceux-ci seront stockés dans %1, %2, ... %n tout comme lorsque vous exécutez un script.

63voto

KFL Points 1082

J'ai trouvé que la prochaine fois que vous aurez besoin de chercher ces informations. Au lieu d'ouvrir un navigateur et de le googler, vous pouvez simplement taper call /? dans votre cmd et vous l'aurez :

...

%* in a batch script refers to all the arguments (e.g. %1 %2 %3
    %4 %5 ...)

Substitution of batch parameters (%n) has been enhanced.  You can
now use the following optional syntax:

    %~1         - expands %1 removing any surrounding quotes (")
    %~f1        - expands %1 to a fully qualified path name
    %~d1        - expands %1 to a drive letter only
    %~p1        - expands %1 to a path only
    %~n1        - expands %1 to a file name only
    %~x1        - expands %1 to a file extension only
    %~s1        - expanded path contains short names only
    %~a1        - expands %1 to file attributes
    %~t1        - expands %1 to date/time of file
    %~z1        - expands %1 to size of file
    %~$PATH:1   - searches the directories listed in the PATH
                   environment variable and expands %1 to the fully
                   qualified name of the first one found.  If the
                   environment variable name is not defined or the
                   file is not found by the search, then this
                   modifier expands to the empty string

The modifiers can be combined to get compound results:

    %~dp1       - expands %1 to a drive letter and path only
    %~nx1       - expands %1 to a file name and extension only
    %~dp$PATH:1 - searches the directories listed in the PATH
                   environment variable for %1 and expands to the
                   drive letter and path of the first one found.
    %~ftza1     - expands %1 to a DIR like output line

In the above examples %1 and PATH can be replaced by other
valid values.  The %~ syntax is terminated by a valid argument
number.  The %~ modifiers may not be used with %*

23voto

djangofan Points 6046

La façon de récupérer tous les args d'un script est ici :

@ECHO off
ECHO The %~nx0 script args are...
for %%I IN (%*) DO ECHO %%I
pause

2 votes

Pas vraiment, %%I sont interprétés et peuvent casser votre script.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X