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

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.

Related

How to create a .bat file which execute python file

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.

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

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.

Run a remote bash script on a Mac using PuTTy

I want to run a bash script on a mac remotely from a batch script on a windows machine. On Windows I have this:
#echo off
echo bash /applications/snowflake/table-updater/test2.sh; exit>tmp_file
putty -ssh User#remote_machine -pw password -m tmp_file
And here is test2.sh on the remote machine
#!/bin/bash
# test2.sh
#
#
7za x table-apps.zip -y -o/Applications/snowflake/applications
When the batch file runs it logs in successfully, but for some reason fails to run the bash file. However the bash file runs fine from mac terminal, where it unzips the files perfectly. What could be happening here?
Please note test2.sh is actually in Applications/snowflake/table-updater as specified in the batch file. And the tmp file does write fine as well. My aim is to have a script to access a further 10 remote machines with the same directory structure.
Thanks in advance
The standard program which resembles the scriptable Unix command ssh in the PuTTy suite is called plink, and would probably be the recommended tool here. The putty program adds a substantial terminal emulation layer which is unnecessary for noninteractive scripting (drawing of terminal windows, managing their layout, cursor addressing, fonts, etc) and it lacks the simple feature to specify a command directly as an argument.
plink user#remote_machine -pw password /Applications/snowflake/table-updater/test2.sh
From your comments, it appears that the problem is actually in your script, not in how you are connecting. If you get 7za: command not found your script is being executed successfully, but fails because of a PATH problem.
At the prompt, any command you execute will receive a copy of your interactive environment. A self-sufficient script should take care to set up the environment for itself if it needs resources from non-standard locations. In your case, I would add the following before the 7za invocation:
PATH=$PATH:/Applications/snowflake/table-updater
which augments the standard PATH with the location where you apparently have 7za installed. (Any standard installation will take precedence, because we are adding the nonstandard directory at the end of the PATH -- add in front if you want the opposite behavior.)
In the general case, if there are other settings in your interactive .bashrc (or similar shell startup file) which needs to be set up in order for the script to work, the script needs to set this up one way or another. For troubleshooting, a quick and dirty fix is to add . /Users/you/.bashrc at the top of the script (where /Users/you should obviously be replaced with the real path to your home directory); but for proper operation, the script itself should contain the code it needs, and mustn't depend on an individual user's personal settings file (which could change without notice anyway).

cywin bash script command not found when called from batch

#!/bin/bash
echo "Testing"
cd "/cygdrive/x/Internal Communications/Riccardo/"
filename=htdocs-`date +%A`.tar.gz
tar cvzf $filename "/cygdrive/c/Program Files/Zend/Apache2/htdocs"
The above script is working when it is called inside cygwin console, but when I try to call it from a batch file I get "command not found" for date and tar command. I think that bash.exe does not have the PATH set up.
I need to run that script from that batch file because I want to add the script to the task scheduler.
As has already been said, you need to add the Cygwin binaries to your path. To do so, right click on "My Computer", click "Properties", then "Advanced", then "Environment Variables".
Create a new environment variable with name "CYGWIN_HOME" and value "C:\cygwin" (or wherever you installed cygwin. The default location is "C:\cygwin\" so this should probably work for you).
Then edit the environment variable named "PATH", and tack on the following to the end:
;%CYGWIN_HOME%\bin;%CYGWIN_HOME%\sbin;%CYGWIN_HOME%\usr\bin;%CYGWIN_HOME%\usr\sbin;%CYGWIN_HOME%\usr\local\bin;%CYGWIN_HOME%\usr\local\sbin
Close your command prompt, then reopen it. The cygwin binaries should now be available. You can double-check this by typing "which bash". It should report the location of your bash executable.
FWIW, Cygwin has cron.
Are you calling your script like this?
bash --login -i ./myscript.sh
Put your cygwin bin directory (likely C:\cygwin\bin) on your PATH environment variable.
This would also give you the benefit of being able to use commands like tar, ls, rm, etc. from a regular console windows and not just a Cygwin console.
If this script is invoked from a Windows command shell, the first line will result in an error since #!/bin/bash is not a recognized Windows command and # is not a valid comment delimiter in a batch file.
So, the bottom line is that this script runs as a regular batch file rather than from within Cygwin's bash. As noted by matt b, you likely do not have the Cygwin executable path in your PATH environment variable. Without this, the batch file cannot find the Cygwin utilities (tar and date).
I just had this problem.
Editing the environment variable works great. But if you are have no admin rights you canĀ“t do that.
In this case you can execute your commands by using the absolute path like:
/usr/bin/tar cvzf $filename
/usr/bin/cat $filename
If you do so your bash script works even if you call it from a batch file.

Resources