web-dev-qa-db-fra.com

Comment associer des fichiers .sh à Cygwin?

Je voudrais exécuter une longue commande rsync dans Cygwin en double-cliquant sur un fichier .sh dans Windows. Il doit commencer dans le répertoire contenant le fichier (par exemple/cygdrive/c/scripts /) pour que les chemins relatifs fonctionnent. Quelqu'un a réussi à le faire fonctionner?

Remarque: Je viens de trouver ici , un package Cygwin qui gère les menus contextuels de Windows (invite Bash ici). Cela pourrait avoir des indices.

48
Jerph

Ok, j'ai trouvé quelque chose qui fonctionne. L'association d'un fichier batch comme l'a suggéré Vladimir n'a pas fonctionné, mais les arguments bash étaient essentiels.

Court et doux: associez-le à cette commande: "C:\cygwin\bin\bash.exe" -li "% 1"% *

Version longue si vous ne savez pas comment:

  1. Dans l'Explorateur, accédez à Outils/Options des dossiers/Types de fichiers.
  2. J'avais déjà une entrée SH pour Bash Script. Si vous n'en avez pas, cliquez sur Nouveau et entrez "SH" pour en créer un.
  3. Avec l'extension SH sélectionnée, cliquez sur Avancé.
  4. Choisissez l'action "ouvrir" et cliquez sur modifier (ou créez l'action).
  5. Il s'agit de la commande à utiliser: "C:\cygwin\bin\bash.exe" -li "% 1"% *. Notez que sans - li, il reprenait "commande introuvable" sur mes scripts.

Vous pouvez également ajouter SH à votre variable d'environnement PATHEXT :

WinKey + Pause/Avancé/Variables d'environnement/Variables système/PATHEXT

Merci pour votre aide les gars!

41
Jerph

Voici ma solution. Cela fonctionne bien pour mes scripts * .sh, peu importe où ils se trouvent dans la hiérarchie des répertoires. Notez que je passe au dirname cygpath avant d'appeler bash sur le cygpath. Ça marche juste.

assoc .sh=bashscript

ftype bashscript=C:\cygwin\bin\bash.exe --login -i -c 'cd "$(dirname "$(cygpath -u "%1")")"; bash "$(cygpath -u "%1")"'
15
user78706

Je travaille avec la solution de Dragos depuis un certain temps maintenant et je la considère comme la meilleure car elle évite d'avoir à utiliser "cygpath -u" dans vos scripts Shell.

Je voulais ensuite avoir des fonctionnalités supplémentaires comme le support du glisser-déposer pour les fichiers .sh et .bash. Après quelques recherches, j'ai écrit un .bat qui associe les fichiers .sh et .bash en tant que "bashscript" et active le gestionnaire de glisser-déposer de l'Explorateur Windows pour eux. J'ai dû éditer la commande de Dragos pour qu'elle gère 1 argument (le chemin vers l'élément déposé sur un script Shell).

Le fichier .bat se présente approximativement comme suit:

echo Registering .sh and .bash files as "bashscript"...
assoc .sh=bashscript
assoc .bash=bashscript
echo.
echo Setting the run command for the file type "bashscript"...
ftype bashscript=C:\cygwin\bin\bash.exe --login -i -c 'cd "$(dirname "$(cygpath -u "%%1")")"; bash "$(cygpath -u "%%1")" "$(/argshandler.sh "%%2")"'
echo.
echo Activating the drag^&drop capability for "bashscript" files (only 1 dropped item
echo will be passed to the script, multiple items are not supported yet)...
reg add HKEY_CLASSES_ROOT\bashscript\shellex\DropHandler /v "" /t REG_SZ /d "{60254CA5-953B-11CF-8C96-00AA00B8708C}" /f

Le script "argshandler.sh" dans la racine Cygwin ne fait que remonter le premier argument qu'il reçoit et rien du tout s'il n'y en a pas (par exemple, si vous double-cliquez simplement sur un fichier de script):

#!/bin/bash
if [ ! "$1" == "" ]
then
    cygpath -u "$1"
fi

Tout cela fonctionne très bien jusqu'à présent. Cependant, il y a encore quelques inconvénients qu'il serait bon de résoudre:

  • La commande de Dragos et sa dérivée échouent lorsqu'il s'agit de scripts situés sur des chemins UNC, par exemple \\ myserver\myshare\scriptfile.sh
  • Seul 1 élément supprimé sera transmis au script Shell.

D'une manière ou d'une autre, concernant le problème de 1 élément supprimé uniquement, la modification du script du gestionnaire d'arguments pour redonner quelque chose comme

"cygpathed-arg1" "cygpathed-arg2" "cygpathed-arg3"

et changer le setter de la commande de Dragos en quelque chose comme

...; bash "$(cygpath -u "%%1")" $(/argshandler.sh "%%2" "%%3" ... "%%9")'

(notez que le "" autour de la partie argshandler.sh a disparu) ne semble pas fonctionner correctement: si certains des éléments glissés sur un script contiennent un blanc sur leur chemin, ces chemins seront divisés en plusieurs arguments au niveau des blancs même si chacun d'eux est mis entre guillemets ... bizarre.

Y a-t-il des professionnels de la ligne de commande qui se sentent prêts à résoudre l'un ou les deux de ces problèmes?

6
eomanis

Voici la commande que j'utilise:

"C:\cygwin\bin\mintty.exe" -w max -h always -t "%1" -e /bin/bash -li -c 'cd "$(dirname "$(cygpath -u "%1")")" && bash "$(cygpath -u "%1")"'

Il l'exécute dans mintty, maximisé, définit le titre de la fenêtre du script en cours d'exécution (chemin d'accès Windows vers celui-ci), change de répertoire où se trouve le script, l'exécute et reste ouvert une fois terminé.

Alternativement, cela définira le titre sur le chemin cygwin du script:

"C:\cygwin\bin\mintty.exe" -w max -h always -t "%1" -e /bin/bash -li -c 'printf "\033]0;$(cygpath -u "%1")\007" && cd "$(dirname "$(cygpath -u "%1")")" && bash "$(cygpath -u "%1")"'

Scripts batch pour définir l'association pour vous:

Chemin d'accès Windows dans le titre:

@echo off
assoc .sh=shellscript
ftype shellscript="C:\cygwin\bin\mintty.exe" -w max -h always -t "%%1" -e /bin/bash -li -c 'cd "$(dirname "$(cygpath -u "%%1")")" ^&^& bash "$(cygpath -u "%%1")"'
pause

Et le chemin de cygwin dans le titre:

@echo off
assoc .sh=shellscript
ftype shellscript="C:\cygwin\bin\mintty.exe" -w max -h always -t "%%1" -e /bin/bash -li -c 'printf "\033]0;$(cygpath -u "%%1")\007" ^&^& cd "$(dirname "$(cygpath -u "%%1")")" ^&^& bash "$(cygpath -u "%%1")"'
pause
2
user5227562

Cela n'associe pas les fichiers .sh, mais cela peut vous donner ce que vous voulez. J'ai commencé avec le fichier batch cygwin.bat qui lance le shell bash Cygwin, et je l'ai modifié comme suit:

$ cat test.bat
@echo off

set MYDIR=C:\scripts

C:\cygwin\bin\bash --login -c "cd $MYDIR && echo 'Now in' `pwd`; sleep 15"

C'est un script jouet, mais vous pouvez le modifier pour appeler rsync ou appeler un script Shell distinct. J'avoue que ce serait mieux s'il n'avait pas codé en dur MYDIR. Il y a probablement un moyen de le faire régler automatiquement.

Oh oui, quand j'ai créé le fichier .bat dans un shell bash dans Cygwin, j'ai remarqué que je devais réellement "chmod + x test.bat" avant de pouvoir le lancer avec un double-clic. Je pense que cela définit des autorisations NTFS. Vous n'auriez pas besoin de le faire si vous utilisiez simplement le bloc-notes.

2
David
    Windows Registry Editor Version 5.00
    ;File:ConfigureShToBeRunUnderExplorer.reg v:1.0 docs at the end
    [HKEY_CLASSES_ROOT\Applications\bash.exe] 

    [HKEY_CLASSES_ROOT\Applications\bash.exe\Shell]

    [HKEY_CLASSES_ROOT\Applications\bash.exe\Shell\open]

    [HKEY_CLASSES_ROOT\Applications\bash.exe\Shell\open\command]
    @="C:\\cygwin\\bin\\bash.exe -li \"%1\" %*"

    ; This is a simple registry file to automate the execution of sh via cygwin on windows 7, might work on other Windows versions ... not tested 
    ; you could add this setting by issueing the following command: reg import ConfigureShToBeRunUnderExplorer.reg 
    ; Note the path of your bash.exe
    ; Note that you still have to add the .sh to your %PATHTEXT%
            ; usage: double - click the file or reg import file 
1
Yordan Georgiev

Après avoir regardé différents endroits. Ce que j'ai réussi à trouver, c'est d'abord sélectionner C:\cygwin64\bin\mintty.exe à partir de la fenêtre "Ouvrir avec ...", puis modifiez la valeur de registre de

[Computer\HKEY_CLASSES_ROOT\Applications\mintty.exe\Shell\open\command]

à,

C:\cygwin64\bin\mintty.exe -t "%1" /bin/bash -l -i -c "v1=\"$(cygpath -u \"%0\" -a)\" && v2=\"$(dirname \"$v1\")\" && cd \"$v2\" ; exec bash  \"%1\" %*"  
1
Light93

Vous devriez pouvoir associer des fichiers .sh à\CYGWIN\usr\bin\bash.exe. Le script devra changer son propre répertoire de travail, je suggère de coller quelque chose comme ça en haut:

cd `dirname "$0"`
1
Sparr

J'utilise PuttyCyg (génial PuTTY dans la fenêtre Cygwin), voici comment le faire fonctionner:

Créez un script batch, par exemple. sur ma machine j'ai utilisé

C:\Dev\scripts\cygbashrun.bat

avec contenu

SET CYGWIN=nodosfilewarning
C:\Cygwin\bin\PuTTY.exe -cygterm /bin/bash.exe %1

Évidemment, adaptez-vous pour contenir les chemins de votre installation de PuttyCyg.

Ensuite, dans l'Explorateur de fichiers Windows, accédez à Outils - Options des dossiers - Types de fichiers

Créez une entrée ".sh" s'il n'y en a pas déjà (ou .bash selon ce que vous voulez que vos scripts aient) .. puis Avancé ..

[étape facultative] modifiez l'icône et sélectionnez l'icône Cygwin dans votre installation

Ensuite:

  1. Nouveau..
  2. Action = exécuter Bashscript ..
  3. Application utilisée pour effectuer cette action = C:\Dev\scripts\cygbashrun.bat "% 1"

Fonctionne comme un charme pour moi: O)

0
HaveAGuess

Regardez les commandes assoc et ftype dans une boîte de dos. Voici un exemple pour .jpg sur ma machine

c:\>assoc .jpg
.jpg=jpegfile

c:\>ftype jpegfile
jpegfile="C:\Program Files\Common Files\Microsoft Shared\PhotoEd\PHOTOED.EXE" "%1"

assoc .sh=bashscript

ftype bashscript="c:\cygwin\bin\bash.exe" "%1"

Assurez-vous de modifier le chemin d'accès à bash dans la commande ftype pour correspondre à l'endroit où vous avez installé cygwin

0
Jim Riblett

Une solution qui fonctionne est de créer un .bat fichier qui ouvrira cygwin et exécutera votre script.

Le script pour exécuter le script go.sh situé dans mon répertoire personnel:

@echo off

C:
chdir C:\cygwin\bin

bash --login -i ./go.sh
0
Vladimir

J'ai développé moi-même un script .bat (ne provenant pas de la réponse d'un autre) pour associer un type de fichier (par exemple * .cygwin) à ouvrir avec ce .bat, comme suit:

=== fichier run-script-with-Cygwin-in-same-dir.bat ===

@echo off
REM   Info: A script created by Johnny Wong.  (last modified on 2014-7-15)
REM   It is used to pass a file argument to run a bash script file.  The current directory is setting to the path of the script file for convenience.
REM   Could be copied to C:\cygwin;  and then you manually associate .cygwin file extension to open with this .bat file.
set CYGWIN=nodosfilewarning

C:\cygwin\bin\bash --login -i -c 'cd "`dirname "%~1"`"; exec bash "%~1" %2 %3 %4 %5 %6 %7 %8 %9'

REM finally pause the script (press any key to continue) to keep the window to see result
pause

=== fichier run-script-with-Cygwin-in-same-dir.bat ===

Explications détaillées sur la syntaxe utilisée (si vous êtes intéressé):

  1. % 1 est "..." entre guillemets s'il est associé à un fichier à ouvrir avec ce .bat. Pour faire glisser un fichier vers ce fichier .bat, il n'est "..." cité que si le chemin d'accès au fichier comporte des espaces.
  2. % ~ 1 est identique à% 1 avec les guillemets environnants supprimés, s'ils existent
  3. pour supprimer les guillemets autour de% p%, utilisez for %%a in (%p%) do set p=%%~a
  4. vous devez utiliser "%~1" pour forcer le chemin du fichier de script entre guillemets, afin que ses séparateurs de dossier '\' (dans% 1) ne soient pas supprimés par bash lorsqu'ils sont traités comme des caractères d'échappement. Sinon, cela ne fonctionne pas lorsque vous faites glisser un fichier, qui ne contient aucun espace sur son chemin, vers ce fichier .bat.
  5. "exec bash" peut être simplement "bash", le premier sert à économiser des ressources pour un autre processus bash.

Aime :)

0
Johnny Wong

Je n'ai pas pris la peine. J'ai associé des fichiers .sh à Crimson Editor (car je passe autant de temps à résoudre les bogues que je les exécute). Il s'agit maintenant de faire fonctionner la bonne combinaison "ouvrir avec/modifier avec" dans Types de fichiers> Avancé. Si je savais quel code DDE Crimson Editor utilisait, cela faciliterait les choses; à partir de ce post, je n'ai pas pu le trouver, cependant.

Cela me rappelle mes jours Mac (1993-2008) lorsque j'essayais de numériser des applications pour plus de scriptabilité AppleScript rudimentaire.

BZT

0
silversleevesx