La commande find
est complètement différente dans Windows et Unix. Sous Windows, il s’agit d’un utilitaire de type fgrep
- répertoriant les lignes correspondantes dans un fichier; Sur Unix - et sur Cygwin -, il liste les noms de fichiers correspondant à certains critères.
Cygwin bash prepends ses répertoires standard dans le chemin actuel, donc à l'intérieur de bash $PATH
est typiquement /bin:/usr/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS
.
Commencez la mise à jour pour fournir des détails supplémentaires
Par exemple, de nombreux scripts utilisent la commande gnu find
, par exemple des scripts pour purger les arborescences de répertoires ne contenant aucun fichier:
purge-empty-dirs.sh
find . -depth -type d -empty | xargs rmdir -p
J'ai aussi un fichier bat pour commencer ma construction, qui utilise la commande windows find, qui recherche les lignes correspondant à une chaîne (similaire à gnu grep
).
build.bat
...
dir | find "target"
if errorlevel = 1 goto no_target_dir
...
Maintenant, pour que mon script bash fonctionne, j'ai besoin de /bin
être dans le chemin avant c:\windows\system32
. Mais pour que mon fichier bat puisse fonctionner, j'ai besoin de c:\windows\system32
être dans le chemin avant /bin
En général, nous pourrions peut-être prétendre que tous les fichiers bat doivent être exécutés avec l'environnement d'origine hérité par bash, pas celui modifié . Cela a-t-il du sens?
Fin de la mise à jour
C'est comme ça que ça devrait être, mais ça casse les fichiers de chauve-souris exécutés à partir de bash. Quelle est la meilleure façon de résoudre ce problème?
Existe-t-il un moyen de forcer Cygwin à exécuter des fichiers bat (ou même tous exécutables Windows) avec l'environnement avec lequel il a commencé? Je pense à start /i
comportement de cmd.exe. Je songe à écrire mon propre utilitaire comme celui-ci, cygstart
, en sauvegardant l'environnement (ou du moins, $PATH
) dans .bash_profile
/.bashrc
. Cela a-t-il du sens?
D'autres suggestions?
Edit: Voir aussi Démarrer new cmd.exe et NE PAS hériter de l’environnement
Si vous chmod +x your.bat
Ça marche.
./your.bat
est exécuté via cmd /c
Déjà répondu dans Pourquoi Cygwin peut-il exécuter des scripts .bat?
J'ai testé une solution de ici et cela fonctionne bien:
start "clean Shell" /i "%windir%\Explorer.exe" "\path\to\your\script.bat"
to-run.bat
script:
echo %PATH%
echo "TODO: some commands"
cmd
cygwin
script bash, run-me.sh
:
#!/bin/bash -e
set -x
SCRIPT_WINPATH=`cygpath --windows --absolute "$1"`
Explorer_CYGPATH=`which Explorer`
Explorer_WINPATH=`cygpath --windows --absolute "${Explorer_CYGPATH}"`
cmd /C start "clean Shell" /I "${Explorer_WINPATH}" "${SCRIPT_WINPATH}"
tester:
chmod +x to-run.bat
chmod +x run-me.sh
./run-me.sh to-run.bat
Vous pouvez utiliser un wrapper, disons, launcher.bat
, dont le contenu est
@echo off
setlocal
rem modify here based on your needs
set PATH=%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem
call %*
endlocal
exit %errorlevel%
Dites que vous voulez appeler cmdFUBAR.bat
avec arg wellDoneMS
à partir d’un script cygwin bash, au lieu de simplement cmdFUBAR.bat wellDoneMS
, tu fais cygstart -w launcher.bat cmdFUBAR.bar wellDoneMS
. Bien sûr, vous devez mettre launcher.bat
dans votre chemin, ou appelez-le avec chemin complet.
La réponse donnée par @ruslo est très utile et fonctionne parfaitement, mais elle comporte une redondance: le start "clean Shell" /I
ne fait rien ici :-) C’est le Explorer
qui supprime l’env cygwin actuel, et non pas start /i
! Essayez de l'omettre de la dernière ligne du script, comme suit:
cmd /C "${Explorer_WINPATH}" "${SCRIPT_WINPATH}"
Même résultat - "chemin vierge"!
En parcourant l’aide de start
, on lit: Le nouvel environnement sera l’environnement original transmis au cmd.exe et non l’environnement actuel. Bien, mais l’environnement est passé à cmd
dans ce cas est celui de cygwin
, donc start /i
ne fera rien d’utile ici, comme on peut le constater en tapant:
cmd /c start /i cmd /c "path && pause"
Le chemin est toujours celui de cygwin
, pas le système Windows!
=== Dans le script build.bat ...
SET DOS_FIND_EXE=%SYSTEMROOT%\system32\find.exe
...
dir | "%DOS_FIND_EXE%" "target"
if errorlevel = 1 goto no_target_dir
...