"source: command not found" running script with git sh via cmder - bash

I'm using cmder on windows https://github.com/bliker/cmder
I created my custom cmder task with the following commands
-new_console:d:C:\project > "C:\Program Files (x86)\Git\bin\sh.exe" --login -i -cur_console:d:C:\project
I need to add another command when this tab opens
source script.sh
But when I add it above in the commands I get
'source' is not recognized as an internal or external command

You can use -c to pass a command to sh to have it run that but I don't believe you can do that and get an interactive session.
Which means if you need a command to be run at the start of an interactive session you want to use the --init-file or --rcfile to specify your startup file (instead of the default file). Though those might both be bash specific. I'm not sure.
If they are then you could try setting the ENV variable to the (absolute or variable/etc. expansion-able) path to your script before running the shell.

Related

When program uses Command to open Bash to run a script, Bash closes immediately without running the script

I have a simple, already-working bash script set up to launch specific files with specific programs in the gaming frontend EmulationStation on Windows.
But the frontend routes its actions through a Command Prompt. And when Command is used to run the script through Bash, the Bash shell just opens and then closes immediately.
Here's an image of what shows for the instant before Bash closes.
This is only happening when going through a separate Command Prompt first, such as Windows Command Prompt or Git Command Prompt. Running the script with an appropriate argument directly through the git-bash shell works just fine.
In case you want to see the script for any reason, here it is:
#!/bin/bash
defaultemulaunch="V:/Emulation/.emulationstation/systems/retroarch/retroarch.exe -L "V:/Emulation/.emulationstation/systems/retroarch/cores/bsnes_mercury_accuracy_libretro.dll" \"$1\""
emu1names=(\
"(1999) Fire Emblem - Thracia 776.smc")
emu1launch="V:/Emulation/.emulationstation/systems/retroarch/retroarch.exe -L "V:/Emulation/.emulationstation/systems/retroarch/cores/snes9x_libretro.dll" \"$1\""
gamename=`basename "$1"`
for index in ${!emu1names[*]}
do
game=${emu1names[index]}
if [ "$game" == "$gamename" ]; then
eval "$emu1launch"
fi
done
eval "$defaultemulaunch"
But it's worth pointing out that this is happening when trying to run any bash script when starting the process from a separate Command Prompt.
Note: Git is installed on the hard drive that houses the emulation frontend (V:)---not in the user directory or programs directory of the system's OS/boot drive (C:). I mention this because git-bash's failure at an apparent "login" step except when launched directly feels like it could be a default filepath issue.
Check if that program would still open/close a Windows when executed from the CMD with:
bash -c '/v/path/to/bash/script'
In your case:
set PATH=V:\Emulation\
set GIT_HOME=V:\Emulation\Git
set PATH=%GIT_HOME%;%GIT_HOME%\bin;%GIT_HOME%\usr\bin;%GIT_HOME%\mingw64\bin;%PATH
Then:
cd V:/Emulation/.emulationstation/roms/snes/
bash -c './gamelaunch.sh "./(1990) F-Zero.sfc"'
I usually make a run.bat script which would:
set the correct PATH
launch the correct script
That way, for any of my project, I just type run.
And it runs.

Executing a script in MSYS2/MinGW

On Windows, if I start c:\msys64\mingw64.exe, it opens a shell, where I can build my project, let's say by calling a release bash script (to simplify). Everything works fine.
Now, I would like to execute my release script on mingw64 directly, without interaction.
I tried:
c:\msys64\mingw64.exe /c/the/full/path/release
A window opens and closes, it does not work.
I attempted to use bash directly, but it seems the environment is not correctly set:
> c:\msys64\usr\bin\bash -c ls
/usr/bin/bash: ls: command not found
> c:\msys64\usr\bin\bash -c /bin/ls
... it works ...
So it is obvious that the environment is not the same as when execute c:\msys64\mingw64.exe then call ls.
How to execute my release script as if I were in the shell started by mingw64.exe?
To run a Bash shell script in MSYS2 without showing a window, you should right-click on your Desktop or somewhere else in Windows Explorer, select "New", select "Shortcut", and then enter something like this for the shortcut target:
C:\msys64\usr\bin\mintty.exe -w hide /bin/env MSYSTEM=MINGW64 /bin/bash -l /c/Users/rom1v/project/release.sh
Note that there are 4 paths in here. The path to mintty and release.sh are absolute paths that you will need to adjust. The paths to env and bash are relative to your MSYS2 installation directory. Note also that the first path must be a standard Windows path, since Windows expects that when it is running a shortcut.
Explanation
It might seem odd to use MinTTY for a non-interactive script, but we need to use some program that was compiled for the Windows subsystem (-mwindows option to GCC), or else Windows will automatically start a new console when we run the program. We pass the -w hide option to MinTTY to tell it not to actually show a window. Everything after that option is interpreted by MinTTY as a command to run.
So MinTTY will run /bin/env from the MSYS2 distribution and pass the remainder of the arguments on to it. This is a handy utility that is actually a standard part of Linux as well as MSYS2. It sets the MSYSTEM environment variable to MINGW64 (which is important later) and then it runs /bin/bash with the remainder of the command-line arguments.
We pass -l to Bash so that it acts as a login script, and runs certain startup scripts. In particular, the /etc/profile script from MSYS2 is essential because it looks at the MSYSTEM environment variable, sees that it is MINGW64, and then sets a bunch of other environment variables (e.g. PATH) to give you the MinGW 64-bit shell environment.
Finally, we pass the name of your script as the main argument to bash, so it will run that script after running the initialization scripts.
Error handling
Note that if your Bash script has an error, you won't get any notification, because the shortcut above doesn't open any console windows. I personally would find that pretty annoying. I'd probably remove the -w hide option, then make a wrapper bash script that just does something like:
run_my_main_script || sleep 10000
So if the main script is successful, exit right away, otherwise keep the window open for 10000 seconds. You don't have to even put that wrapper script in its own file, you can just put it in the shortcut as the argument to Bash's -c option (don't forget to wrap it in double quotes).
Thanks to the answers from #David Grayson, I managed to call my release script with msys2/mingw from a Windows console (cmd), with additional directories (for Java and Meson) in $PATH:
c:\msys64\usr\bin\env MSYSTEM=MINGW64 c:\msys64\usr\bin\bash -l -c "PATH=\"/c/Program Files/Java/jdk1.8.X_XXX/bin:/c/Program Files/Meson:$PATH\" /c/Users/rom1v/project/release"
add an supplement to the above: if u want to the output of shell script
reference:https://mintty.github.io/mintty.1.html
-l, --log FILE|-
Copy all output into the specified log file, or standard output if a dash is given instead of a file name. (Implies -o Logging=yes.)
If FILE contains %d it will be substituted with the process ID. See description of equivalent option "Log file" (Log=) below for further formatting options and hints.
Note that logging can be toggled from the extended context menu.
Add A complete example:
C:\msys64\usr\bin\mintty.exe -w hide -l - c:\msys64\usr\bin\env MSYSTEM=MINGW64 c:\msys64\usr\bin\bash -l -c "PATH=\"$PATH\" /C/Users/Administrator/Desktop/myProject/Demo_C_C++/shell/textProcess/bookNoteHandler.sh" | find /v "/v:Displays all lines that don't contain the specified"
=========

How to open multiple ConEmu/CygWin Bash terminals at different directories

I have a Windows environment set up using ConEmu and CygWin64 and I frequently have to open up four different Windows directories and run a script there to launch a server.
In total I have these four things running in order to have a local version of our environment operating.
Like so;
C:\code\project1\private-api
C:\code\project2\public-api
C:\code\project2\management-agent
C:\code\project3\back-office
So far I have just been manually opening new ConEmu/CygWin Bash tabs and navigating via command line to each directory I need then running the scripts. This is tedious though and I figure there must be a way to have ConEmu launch multiple CygWin Bash tabs in different, specific directories (and maybe even run a script in each directory) but I am at a loss as to how to accomplish this.
I considered trying to do this via a Windows batch script too but I couldn't figure out how to launch ConEmu/CygWin bash windows from a batch file. I'm thinking it's not possible.
I have followed the documentation for ConEmu Tasks but the docs for Task parameters and commands are still confusing me. I tried following the answer in this question as well with little success;
ConEmu: Open multiple Git Bash tabs on different locations
Anyway, here is how I have my current ConEmu CygWin Bash task set up, which works great when opening single tabs in my home directory (had to provide a link, I keep getting errors when trying to upload an image here);
ConEmu CygWin Bash Task config
Name
Bash::CygWin bash
Task parameters
None
Commands
set CHERE_INVOKING=1 & %ConEmuDrive%\cygwin64\bin\sh.exe --
login -i -new_console:C:"%ConEmuDrive%\cygwin64\Cygwin.ico"
Is it actually possible with a ConEmu/CygWin64/CygWin Bash set up to accomplish what I want?
Tasks allow to run as many tabs/panes as you wish.
Docs explain how to run your shell in specific directory.
Ways to execute some command in bash shell on startup.
Example for two tabs with directories
set CHERE_INVOKING=1 & %ConEmuDrive%\cygwin64\bin\sh.exe -l -i -new_console:d:"C:\code\project1\private-api" -new_console:C:"%ConEmuDrive%\cygwin64\Cygwin.ico"
set CHERE_INVOKING=1 & %ConEmuDrive%\cygwin64\bin\sh.exe -l -i -new_console:d:"C:\code\project2\public-api" -new_console:C:"%ConEmuDrive%\cygwin64\Cygwin.ico"
I know nothing about ConEmu, but you should be able to run a shell script like:
#!/bin/sh
mintty --dir /c/code/project1 --exec ./task1 &
mintty --dir /c/code/project2 --exec ./task2 &
...
or
#!/bin/sh
mintty --exec /c/code/project1/task1 &
mintty --exec /c/code/project2/task2 &
...

How to pass arguments to Bash Shell in Babun when integrated in Conemu?

I'm using Babun 1.2.0 with Conemu 161206 [32] and I'm trying to run bash in interactive mode.
I'm using the following Conemu Task paramaters:
/icon "%BABUN%\cygwin\bin\mintty.exe" /dir "%userprofile%"
(The %BABUN% environment variable points to the directory containing .babun)
The command is:
%BABUN%\cygwin\bin\mintty.exe /bin/env CHERE_INVOKING=1 /bin/bash.exe --login -i
The --login -i is getting ignored.
What I've tried:
Placing /bin/bash.exe in quotes causes Conemu to crash. So this does not work: %BABUN%\cygwin\bin\mintty.exe /bin/env CHERE_INVOKING=1 "/bin/bash.exe --login -i"
Moving --login -i and placing it after ...\mintty.exe also does not work.
What is the correct way to pass arguments (--login -i) to bash?
I'm answering my own question with a solution for my problem. It does not answer my question about passing arguments to bash, but it does allow me to run the Bash shell in Babun's Cygwin in interactive mode with ConEmu.
In ConEmu go to Settings --> Startup --> Tasks. Select the predefined Babun task (or create one) and enter the following for...
Task parameters: /icon "%BABUN%\cygwin\bin\mintty.exe" /dir "%userprofile%"
Commands: %BABUN%\cygwin\bin\bash.exe --login -i
Instead of point the command to mintty.exe I'm pointing it to bash.exe directly.

Windows shortcut to run a Git Bash script

Assuming I have a test.sh script that runs a server and Git Bash installed, how do I create a Windows shortcut that I can double click to run tesh.sh in Git Bash in the foreground and allows me to see the output of the server?
Git bash is already a batch file with content similar to this :
C:\WINNT\system32\cmd.exe /c ""C:\Git\bin\sh.exe" --login -i"
If you want run (and leave running) a shell script in the context of the shell, specify it at the command line. The trick is that when the script file name is interpreted, it uses the Windows path, not the equivalent path in the sh/Git environment.
In other words, to run the file D:\temp\test.sh in the Git shell and leave it running, create this batch file :
C:\WINNT\system32\cmd.exe /c ""C:\Git\bin\sh.exe" --login -i -- D:\temp\test.sh"
On the other hand, if you want to run a script and get your shell back, you should :
Open the shell as is
Edit or create ~/.profile (try vi ~/.profile)
Add this line : ~/test.sh (ajdust the path if needed)
So with a .profile that looks like this :
echo Executing .profile
/bin/sh ~/test.sh
And test.sh that looks like this :
echo Hello, World!
You will get this prompt :
Welcome to Git (version 1.7.11-preview20120710)
Run 'git help git' to display the help index.
Run 'git help <command>' to display help for specific commands.
Executing .profile
Hello, World!
ixe013#PARALINT01 ~
$
Other answers work, but there is a shorter solution, that fully answers the question, which was:
How to create a Windows shortcut that I can double click to run
tesh.sh in Git Bash
The answer is: add the following command to the Target: field of the shortcut:
"C:\Git\bin\sh.exe" -l "D:\test.sh"
Where, -l is the short for --login.
To better understand what this command does, consult with official GNU docs about Invoking Bash:
-l (--login): Make this shell act as if it had been directly invoked by login. When the shell is interactive, this is equivalent
to starting a login shell with exec -l bash. When the shell is
not interactive, the login shell startup files will be executed.
exec bash -l or exec bash --login will replace the current
shell with a Bash login shell.
Also note that:
You either need the full path to sh.exe or have it in your PATH environment variable (as others have already pointed out).
If you really need to force shell invocation in interactive mode, you can add the -i option
The last parameter is the path to the script that has to be executed. This path should be in Windows format.
Best solution in my opinion:
Invokes the right shell
No unnecessary windows
Invokes a bash script afterwards
Window will stay open after the script exits
Do the following:
Create a shortcut to mintty.exe on your desktop, for example. It is found under %installation dir%/Git/usr/bin/mintty.exe
Edit properties of the shortcut and change the target (keep the path):
"C:\Program Files\Git\usr\bin\mintty.exe" -h always /bin/bash -l -e 'D:\folder\script.sh'
Explanation of the parameters:
-h always keeps the window open when the script finished, so the window won’t disappear while you are still reading the output (remove if you don’t need to read the output and want the window to close automatically).
-l makes this shell act as if it had been directly invoked by login.
-e exits immediately if a pipeline returns a non-zero status (more info).
I'd recommend to use environment variable %ComSpec%, instead of absolute path to cmd:
%ComSpec% /c ""C:\Program Files (x86)\Git\bin\sh.exe" --login -i"
or even just cmd command, which is usually available from %PATH%:
cmd /c ""C:\Program Files (x86)\Git\bin\sh.exe" --login -i"
if your C:\Program Files (x86)\Git\bin added to PATH (which is also common solution and one of cases on TortoiseGit installing) you can use just:
cmd /c "sh --login -i"

Resources