Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating batch file to start cygwin and execute specific command

I want to create a batch file thats start cygwin and executes a specific command (The command is to read a bash file and executes some command inside it).

This is the batch file that I have developed, it works to some extent. the cygwin terminal opens and tries to read the bash file, but cannot execute the commands inside:

@ECHO OFF

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

PAUSE

How can I make this work?

like image 585
manifertal Avatar asked Apr 07 '17 05:04

manifertal


2 Answers

From your batch file, launch Cygwin's bash shell and use the login flag. This provides a foundation for setting path and environment variables through your .bash_profile or .bashrc files. I believe this may be the source of your difficulties.

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

If you provide more details about the nature of your bash file, I can be more specific. Good luck.

like image 62
Patrick Kelly Avatar answered Oct 14 '22 14:10

Patrick Kelly


Patrick Kelly's helpful answer points out that not running bash as a login shell in Cygwin may be the source of the problem.

Indeed: Always run Cygwin bash as a login shell, because crucial initializations will otherwise not take place; notably, the $PATH variable won't contain /usr/local/bin:/usr/bin, and the locale won't be set correctly.

In order to make bash start a login shell, the bash executable must be passed the -l option (or its longer alias, --login).

  • To execute your script:

    • in the current console window, see Patrick's answer.

      • Note that unless the target script relies on a particular working directory, use of -c with separate cd and execution commands is not strictly necessary; something like the following will do:

        C:\cygwin64\bin\bash -l c:\path\to\your\script
        
    • in mintty.exe, the terminal application that Cygwin comes with (as you've tried):

      C:\cygwin64\bin\mintty /bin/bash -l c:\path\to\your\script
      
      • Note that executing mintty from a Command Prompt or batch file invariably opens a new console window, and does so asynchronously.

Note how a Windows-style path can (alternatively) be used to specify the target script (which means you could have used c:\cygwin64\bin\bash instead of /bin/bash too).

More importantly, note how an explicit reference to the bash executable is required in both cases, which contrasts with what you tried:


Options you pass to mintty.exe are specific to it - they're not passed through to bash. Specifically, mintty.exe options you're using are (see all of them by running mintty --help):

  • -l, --log FILE|- ... Log output to file or stdout
  • -i, --icon FILE[,IX] ... Load window icon from file, optionally with index

Therefore, -li creates a log file named i in the current directory, because i is interpreted as the l's option-argument, not as separate option i.

The specified script (/cygdrive/c/...) still executes, however - but, crucially, not in a login shell.

What you meant to do requires an explicit call to the bash executable, as demonstrated above, so that the options are interpreted by Bash:

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

Also, as noted, executing mintty.exe from a batch file invariably creates a new console window, and does so asynchronously - that is, your batch file immediately proceeds to the PAUSE command, irrespective of whether the mintty.exe process has terminated yet or not.

Obviously, whatever is output in that new window will not be visible in the original window.


Optional reading: interacting with a mintty.exe window:

Caveat: mintty.exe runs asynchronously even when using the usual start /wait approach from a batch file; that is, the following attempt to block a batch file / command prompt until mintty.exe terminates does not work:

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

When passed a script / command, the Bash session created by mintty.exe will invariably exit when the script terminates, because bash - even when it's passed -i to indicate an interactive session - will automatically exit in that case.

If all you need is to inspect the output after the script terminates, run:

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

Note that no shell is running in that window once the script exits, so all you can do is inspect the script's output - nothing more.

To keep a shell open, you need a workaround:

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

Note that this creates a new shell instance after the script exits.

like image 30
mklement0 Avatar answered Oct 14 '22 15:10

mklement0