web-dev-qa-db-fra.com

Création d'un fichier batch pour démarrer cygwin et exécuter une commande spécifique

Je veux créer un fichier batch qui démarre cygwin et exécute une commande spécifique (la commande consiste à lire un fichier bash et à exécuter une commande à l'intérieur).

Ceci est le fichier batch que j'ai développé, il fonctionne dans une certaine mesure. le terminal cygwin s'ouvre et essaie de lire le fichier bash, mais ne peut pas exécuter les commandes à l'intérieur:

@ECHO OFF

C:\cygwin64\bin\mintty.exe -li /cygdrive/c/(path-to-bash-file-location)/(MyBashFile)

PAUSE

Comment puis-je faire fonctionner cela?

11
manifertal

À partir de votre fichier de commandes, lancez le shell bash de Cygwin et utilisez l'indicateur de connexion. Cela fournit une base pour définir le chemin d'accès et les variables d'environnement via votre .bash_profile ou .bashrc des dossiers. Je pense que cela peut être à l'origine de vos difficultés.

@ echo off
C:\cygwin64\bin\bash --login -c "cd ~/path/to/desired; ./mybashfile.sh"

Si vous fournissez plus de détails sur la nature de votre fichier bash, je peux être plus précis. Bonne chance.

13
Patrick Kelly

réponse utile de Patrick Kelly souligne que pas exécutant bash en tant que login Shell dans Cygwin peut être la source du problème.

En effet: Exécutez toujours Cygwin bash en tant que login Shell, car sinon les initialisations cruciales n'auront pas lieu ; notamment, le $PATH la variable ne contiendra pas /usr/local/bin:/usr/bin, et les paramètres régionaux ne seront pas définis correctement.

Pour que bash démarre un login Shell, le exécutable bash doit être passé le -l option (ou son alias plus long, --login).

  • Pour exécuter votre script:

    • dans la fenêtre de la console actuelle, voir réponse de Patrick .

      • Notez qu'à moins que le script cible ne repose sur un répertoire de travail particulier, l'utilisation de -c avec cd et des commandes d'exécution distinctes n'est pas strictement nécessaire; quelque chose comme ce qui suit fera:

        C:\cygwin64\bin\bash -l c:\path\to\your\script
        
    • dans mintty.exe, l'application terminale fournie avec Cygwin (comme vous l'avez essayé):

      C:\cygwin64\bin\mintty /bin/bash -l c:\path\to\your\script
      
      • Notez que l'exécution de mintty à partir d'une invite de commandes ou d'un fichier batch ouvre invariablement une fenêtre de console nouveau, et le fait asynchrone.

Notez comment un chemin de style Windows - peut (alternativement) être utilisé pour spécifier le script cible (ce qui signifie que vous auriez pu utiliser c:\cygwin64\bin\bash au lieu de /bin/bash aussi).

Plus important encore, notez comment une référence explicite à l'exécutable bash est requise dans les deux cas, ce qui contraste avec ce que vous avez essayé :


Options que vous passez à mintty.exe sont spécifiques à it - ils sont pas transmis à bash. Plus précisément, mintty.exe les options que vous utilisez sont (voyez-les toutes en exécutant mintty --help):

  • -l, --log FILE|- ... Enregistrer la sortie dans un fichier ou une sortie standard
  • -i, --icon FILE[,IX] ... Icône de chargement de la fenêtre à partir du fichier, éventuellement avec index

Par conséquent, -li crée un fichier journal nommé i dans le répertoire courant, car i est interprété comme l'argument d'option de l, et non comme une option distincte i.

Le script spécifié (/cygdrive/c/...) s'exécute toujours - mais, surtout, pas dans un shell de connexion.

Ce que vous vouliez faire nécessite un appel explicite à l'exécutable bash, comme illustré ci-dessus, afin que les options soient interprétées par Bash:

C:\cygwin64\bin\mintty /bin/bash -li c:\path\to\your\script

En outre, comme indiqué, l'exécution de mintty.exe à partir d'un fichier de commandes crée invariablement une fenêtre de console nouveau et le fait de manière asynchrone - c'est-à-dire que votre fichier de commandes passe immédiatement à la PAUSE, indépendamment du fait que le mintty.exe le processus est encore terminé ou non.

De toute évidence, tout ce qui est sorti dans cette nouvelle fenêtre ne sera pas visible dans la fenêtre d'origine.


Lecture optionnelle: interaction avec un mintty.exe fenêtre:

Avertissement : mintty.exe s'exécute de manière asynchrone même lorsque vous utilisez le start /wait approche à partir d'un fichier batch; c'est-à-dire que la tentative suivante de bloquer un fichier batch/une invite de commande jusqu'à ce que mintty.exe termine ne pas fonctionne:

start /wait "" "c:\cygwin64\bin\mintty" # !! DOES NOT WORK - still asynchronous

Lors de la transmission d'un script/commande, la session Bash créée par mintty.exe sera invariablement exit à la fin du script , parce que bash - même lorsqu'il est passé -i pour indiquer une session interactive - se fermera automatiquement dans ce cas.

Si tout ce dont vous avez besoin est de inspecter la sortie après la fin du script , exécutez:

c:\cygwin64\bin\mintty -h always /bin/bash -l /cygdrive/c/path/to/bash-script

Notez qu'aucun Shell ne s'exécute dans cette fenêtre une fois le script terminé, donc tout ce que vous pouvez faire est inspecter la sortie du script - rien de plus.

Pour garder un shell ouvert , vous avez besoin d'une solution de contournement :

c:\cygwin64\bin\mintty /bin/bash -lc "/cygdrive/c/path/to/bash-script; exec /bin/bash"

Notez que cela crée une instance nouveau Shell après la fin du script.

7
mklement0