Mettre le résultat d’une commande MS-DOS dans une variable

Publié dans Geekeries | Marqué avec , , ,
Share

Ces derniers jours j’ai eu l’occasion, avec douleur je dois dire, de faire un peu de MS-DOS. Les commandes DOS ne sont à mon goût pas aussi facile d’accès que le bash sous Linux, mais c’est peut-être parce que je connais mieux ce dernier et que j’ai eu plus souvent l’occasion de le pratiquer. Une chose est sûre en tout cas, quand on veut mettre le résultat d’une commande (ls -l ou dir par exemple) dans une variable, il vaut mieux travailler sous Linux que sous Windows !

Sous Linux

Sous Linux, c’est relativement simple, il suffit de faire une affectation classique, mais en mettant la commande entre simple guillemet inversé : ` (qu’on appelle généralement « guillemet du 7 » ;-)) ou, parait-il, de l’entourer avec $(commande) (mais je n’ai jamais testé).

test=`ls -l`

Sous Windows

Solution 1 : Fichier temporaire

On enregistre le résultat de la commande dans un fichier temporaire (avec le chevron supérieur >), et on récupère le contenu de fichier dans une variable (avec le chevron inférieur <). Pfiou ! Notez que pour cela, on se sert de set /p qui attend qu'on écrive quelque chose sur stdout, ce que fais le chevron inférieur.

dir > tmp.txt
set /p VAR=<tmp.txt
echo %VAR% pause

Solution 2 : En utilisant for

On utilise une magouille avec la commande for (on se demande bien pourquoi !?!) avec le paramètre f, et pof ça marche !

for /f %%d in ('dir') do set VAR=%%d
echo %VAR%

Autre exemple avec la date :

for /f %%d in ('date /t') do set madate=%%d
echo %madate%

ce qui affiche : 11/06/2010
Pour ma part, je trouve cette deuxième méthode bien plus propre, quoique très mystérieuse. Cependant elle pose de vrais problèmes pour antislasher un chemin vers un fichier par exemple, et ça, c'est pas cool !

Mise à jour du 3 septembre 2013 :
J'ai deux-trois petites remarques à ajouter. Tout d'abord, comme l'a fait remarquer ... dans les commentaires de cet article, si vous utilisez ce code dans un fichier .bat, il faut en effet utiliser "%%d" pour le nom des variables locales. Si vous l'utilisez directement en ligne de commande, c'est le classique "%d" qu'il faut écrire (Gnu ??). De manière similaire, dans un .bat si vous avez besoin d'utiliser des pipes pour enchaîner des commandes, il faut les pré-fixer d'un accent circonflexe : DIR /B ^| finstr grrr dans un .bat, et DIR /B | findstr grrr directement en ligne de commande.
Quant à mes exemples avec for /f, ils faut les modifier si l'on veut exécuter plus d'une commande dans la boucle. Par exemple set myDate=%%d et set found=true. Mais dans ce cas, il y a visiblement un problème de porté des variables que je n'ai pas encore compris... Toujours est-il que pour récupérer le résultat de myDate, il faut utiliser setlocal ENABLEDELAYEDEXPANSION et accèder à la valeur de la variable à l'aide de points d'exclamation (!myVariable!). Avec les "pourcentages" classiques, ça ne renvoie rien. Je comprends mieux les for aujourd'hui, peut-être comprendrais-je cette bizarrerie un jour !

if "%OS%" == "Windows_NT" setlocal ENABLEDELAYEDEXPANSION
for /f %%d in ('date /t') do (
  set myDate=%%d
  set found=true
)
echo !myDate!
if "%OS%" == "Windows_NT" endlocal

Apprendre MS-DOS

Pour apprendre à utiliser MS-DOS, j'ai découvert le très bon site batcher.fr : très complet, bien expliqué et largement agrémenté d'exemples. Mangez-en !

3 réponses à Mettre le résultat d’une commande MS-DOS dans une variable

  1. ejbye7

    Salut salut
    Ben le 1er for en 2ème solution m’affiche « %%d était inattendu. »
    Idem pour l’autre for…
    Un truc m’échappe…
    Merci
    @+

  2. ejbye7

    OK, on la refait:
    comme je n’étais pas dans un batch mais en ligne de commande, il ne fallait à chaque fois qu’un seul %.
    Désolé du réveil difficile de ce matin 😀
    @+ et merci pour cette astuce
    EJB

  3. BN

    Du coup, c’est bon à savoir ça ! Merci 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*