How to create a .bat file which execute python file - windows

I'm new to bat file and started to implementing it. I have a list of linux application commands which starts my application. I have a windows system to deploy, used to git bash to execute those commands, but in every system restart have to start the application manually so I started implementing bat file which mapped in system start up
#echo off
title ML_autostart_API
start "" "C:\Program Files\Git\git-bash.exe"
using the above script I've opened the git bash. In further need to perform below commands
# To activate python Environment
source E:/ML_APIs/Python_Environment/python3.8.10/Scripts/activate
# To navigate the project dir
cd E:/ML_APIs/API/Call_SessionV1
# To set the environment variables
source config/config.sh
# To run python application
python application.py
have to execute the above using git bash since it is open source commands and doesn't execute in windows. git bash is opening and further commands is not working.

You will need to make 2 files, one for the windows command line (.bat) another for the bash script (.sh). The reason being, after you start the bash console, it will work on different window and it has no idea what your .bat contains. We shall call our scripts as boot.bat and start.sh respectively.
boot.bat
#echo off
title ML_autostart_API
start "C:\Program Files\Git\git-bash.exe" start.sh
Notice the start.sh is added at the end of the start command as parameter.
start.sh
# To activate python Environment
source E:/ML_APIs/Python_Environment/python3.8.10/Scripts/activate
# To navigate the project dir
cd E:/ML_APIs/API/Call_SessionV1
# To set the environment variables
source config/config.sh
# To run python application
python application.py
Note
Both scripts are in the same directory.
This answer assumes python is actually recognized in git-bash paths.
Should this is not the case, you can just use the full path to the executable to call it.
A better alternative would be to just execute the bash script directly on start up (using that start "C:\Program Files\Git\git-bash.exe" start.sh), no mixing stuff.

Related

Running shell script on Windows via Cygwin mintty.exe doesn't execute runcoms

Problem summary
I'm trying to launch a .sh script via Windows 10 Cygwin (i.e. mintty.exe > bash.exe) but neither .profile, .bash_profile, or .bashrc are loading, which I need to update PATH env variable with Cygwin's bin directory.
Background
I'm trying to launch a script finder.sh:
#!/bin/bash
find .
read
from C:\Users\Bo\Temp\. It has unix line endings and executable bit set.
I have Cygwin installed at C:\Users\Bo\AppData\Local\Programs\cygwin64\. I do not have this path in either System or User Windows' Environment Variables (and I don't want to!). My runcoms all live in this directory under /home/Bo. My .bash_profile (and ATM .bashrc) have an export PATH="/cygdrive/c/Users/Bo/AppData/Local/Programs/cygwin64/bin":${PATH} in them.
I want to launch the script from Windows Explorer. I tried using the bash.exe and mintty.exe in the cygwin64\bin\ folder via Open > Choose another app > More apps > Look for another app on this PC. In either case the mintty window displays:
FIND: Parameter format not correct
meaning the Windows' find command was used not Cygwin's. So I have my script echo $PATH and the Cygwin/bin directory is not in PATH. If I add the proper export PATH statement from above to my own script it works fine. So, now to debug the launcher and runcoms...
I've put echo ${0} statements in .profile, .bash_profile, and .bashrc, none of which trigger which I run the .sh script, they are never run. I've read SO and the mans. I've tried creating a Shortcut to both mintty.exe and bash.exe passing a variety of -l -i -e - commands to each using Properties > Shortcut > Target and they are never run. E.g. running simply [..]\mintty.exe -h always doesn't even leave the window open.
How do I get my script to run in Windows Explorer via Cygwin's mintty.exe/bash.exe, and to read from a runcom to update PATH (to find Cygwin Linux commands, vs. updating Windows Environment Variable)?
Two part fix:
A) set a Windows Environment Variable for BASH_ENV to a .bash_env under your Cygwin HOME, and export the PATH variable to include the Cygwin/bin directory from that file. I cannot find a decent reference for this in Cygwin documentation because it seems to be simply a bash thing, but this variable is what bash looks for when running non login/interactively. Best reference: Cygwin shell doesn't execute .bashrc.
And B) run the .sh with bash.exe from Cygwin/bin using Open With....
ALSO, annoying Windows bug: when you select a program to Open With... your .sh script, it will always run 1x with a CWD from your C:\Windows\System32 directory(?!) and all other times will run fine with the CWD as the directory from your .sh script.

How to call PowerShell script from WSL?

In my Windows directory
C:\Users\jholmes\pichak\analytics
I have run1.ps1 code.
I run wsl.exe, now my pwd is
/mnt/c/WINDOWS/system32
How to point to the first path and execute the script?
In WSL2, using the -File option worked for me:
powershell.exe -File path/to/script.ps1
When running wsl (or wsl.exe) from PowerShell, it should start in the same directory that you were in under PowerShell, just with the Linux version of it. For instance, if you are in PowerShell in C:\Users\jholmes\pichak\analytics, and you run wsl, you should end up in /mnt/c/Users/jholmes/pichak/analytics.
If not, then you may have something in your startup file already like the other answer recommend. You should remove any cd commands from your .bashrc, .zshrc, .profile, .bash_profile, or any other startup file you may have edited.
The wsl command provides a few handy arguments for specifying the starting directory:
wsl ~ will start in your Linux user's home directory (e.g. /home/jholmes)
wsl --cd c:\ will start in /mnt/c (or whatever the equivalent Linux directory is to the Windows version passed in).
wsl --cd \\wsl$\<distroname>\etc will start in your /etc directory (or whatever WSL path you passed in. Note that you will need to specific your distribution name (obtained from wsl -l -v).
Let's say that you are in /home/jholmes, and you want to execute the PowerShell script C:\Users\jholmes\pichak\analytics\run1.ps1. You first need to translate the Windows path to the Linux version:
/mnt/c/Users/jholmes/pichak/analytics/run1.ps
You can then run it via:
powershell.exe /mnt/c/Users/jholmes/pichak/analytics/run1.ps
It's also possible to set up a PowerShell script with a "shebang" line to execute it directly. If you add the following as the first line of run1.ps1:
#!/usr/bin/env -S powershell.exe -ExecutionPolicy Bypass
Then set it to be executable via chmod +x /mnt/c/Users/jholmes/pichak/analytics/run1.ps, then it becomes a "command" of sorts (technically, an "executable script") that you can execute directly by just typing the fully qualified name of the script at the command line:
/mnt/c/Users/jholmes/pichak/analytics/run1.ps
or
cd /mnt/c/Users/jholmes/pichak/analytics
./run1.ps
There are two ways to go about this:
You can change your working directory to that of your shell script and execute it normally. To do so, follow these steps:
Mount the relevant drive cd /mnt/c/.
Change directories according to the path of the script.
This approach is more of a hack that I use for the sake of convenience. I have created a folder in my Windows storage wherein I store all Ubuntu WSL related files. Say, D:\Ubuntu. To avoid changing the working directory every time you open WSL, you can modify the shell profile file (bashrc, zshrc etc.) to load the relevant directory at the end.
i.e., Add cd /mnt/d/Ubuntu/ at the end of your ~/.zshrc file if you use zsh or the relevant profile file otherwise.
Here is the evidence, that with the WSL2, our software can make the Powershell script encrypted and protected:
See this picture:
And it can detect and kill the process that uses fanotify because we think it can be used by attackers to hide critical file change (it also can find and kill dtrace/strace/stap/bpftrace/debuggers and process that opens /dev/kmem, /dev/mem, /proc/kcore, and the protected process' /proc/pid/mem etc):
This picture shows the encrypted PowerShell script now can detect and kill possible attackers' processes
For me this answer was almost the good one but when running for instance:
powershell.exe -File /mnt/c/path/to/script/script.ps1
I got following error:
The argument '/mnt/c/path/to/script/script.ps1' to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter.
I then have to:
cd /mnt/c/path/to/script
powershell.exe -File script.ps1

How do I write a batch file that opens a msys shell and then run commands in the shell?

I'm trying to automate the process of building ffmpeg on Windows 10. I'm following the guide here: https://trac.ffmpeg.org/wiki/CompilationGuide/MSVC
Everything works fine when I do it manually, however I want to write a batch file that I can run to go through the entire process automatically.
Building requires me to set up the Visual Studio environment and the MSYS environment. This is where I'm having trouble, since running the MSYS environment opens up a new shell. I want to pass the configure/make/make install commands to the MSYS shell after it is opened.
I've tried the solution here: How to open a new shell in cmd,then run script in a new shell?
The problem they had looks similar to mine, but the solutions posted there didn't work for me.
Here is the bat file currently:
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\vcvars64.bat"
call "C:\workspace\windows\mingw-get\msys\1.0\msys.bat" start cmd.exe /k bscript
pause
and bscript:
./configure --enable-shared --toolchain=msvc --arch=amd64
make
make install
I've tried all sorts of variations like:
call "C:\workspace\windows\mingw-get\msys\1.0\msys.bat" /k bscript
call "C:\workspace\windows\mingw-get\msys\1.0\msys.bat" bscript
start "C:\workspace\windows\mingw-get\msys\1.0\msys.bat" /k bscript
start "C:\workspace\windows\mingw-get\msys\1.0\msys.bat" bscript
And I've also tried leaving the bscript code in the original batch file.
The configure/make commands will either run in the original cmd window, a new cmd window or wont run at all.
Is there a way to pass commands to the MSYS shell like that?
This might be considered somewhat of a late answer but in the spirit of helping out those who come along here in the future:
The MSYS2 documentation contains a page specific to launching MSYS2: https://www.msys2.org/wiki/Launchers/
From there, we learn that one can launch an MSYS2 environment from a Windows shell like this:
C:\\msys64\\usr\\bin\\env MSYSTEM=MSYS /usr/bin/bash -li
If you place this in a *.bat file and execute the script, a new terminal window will spawn with bash running under the MSYS2 environment.
The documentation further illustrates how to run something within that bash shell:
C:\\msys64\\usr\\bin\\env MSYSTEM=MSYS /usr/bin/bash -lc python
The above would again spawn a new terminal window, load the MSYS2 environment, launch bash and then run the python executable in that bash instance.
From here, either directly run the program you want to (instead of python) or create a bash script and pass the parameter to that script to the bash invocation to execute a regular bash script within the MSYS2 environment from a Windows Batch file :)
I'm not sure if you get the result.
you can run command in windows console:
"C:\msys64\msys2_shell.cmd -mingw32 -shell test-script"
Command & paramerter comment:
C:\msys64\msys2_shell.cmd : msys launching bat
-mingw32 : arch, I use the 32bit
test-script : the startup script in /usr/bin
And you need to set the $PATH in startup script to launch your command

Starting embedded MSYS bash in the project directory in clion

How can I start the embedded terminal in Clion in the project directory if I am using a custom terminal (like MSYS or Cygwin bash.exe)?
Bash always seems to start in the home directory no matter what the startup directory is set to. Is there a way to force bash to start up in the directory that it is ran in? I tried adding
cd "`pwd`"
to the .bashrc, but that didn't work.
Here's a screenshot of the terminal settings page in Clion:
I solved that by using a windows batch file with the content
#echo off
set CHERE_INVOKING=1 && C:\dev\msys64\usr\bin\bash.exe --login
Then I put the batch file in CLion.
I derived that from the msys2 start script msys2_shell.cmd where the environment variable CHERE_INVOKING is used to specify that the calling directory is kept.

Why is it that Cygwin can run .bat scripts?

When I execute a .bat script from bash in Cygwin, by what mechanism is it running? I understand that if I run a .EXE it will launch, regardless of whether the .EXE is from Cygwin or from a more traditional environment. I understand that when I execute an executable script with #! at the beginning that Cygwin supplies the magic for it to run.
But why does a .bat script work? Is there some component inside of Cygwin that is aware of what a Windows .bat script is and what to do with it? Or is it that it is somehow impossible under Windows to execute a call to launch a .EXE file that won't automatically also work for a .bat script instead?
Running
./test.bat params
from bash seems to be equivalent to
cmd /c test.bat params
I believe that bash in cygwin sees the bat extension as being flagged executable (a cygwin hit-tip to windows convention). As such it loads and executes the file with it's associated interpreter (cmd.exe, per os configuration), much as it creates a new instance of bash to run your #! scripts (per posix standard).
And if you want to fork an *.cmd file execution like a ShellScript process and append his log to an file:
cmd /c test.bat > nohup.out &
Enjoy!

Resources