Not being able to run bash script on windows - linux

I am trying hard to run a bash script on windows but the message I am getting is "Sorry, only Linux and MacOS are supported."
I have installed Cygwin and Clink in order to be able to run sh scripts on windows platform but still it is of no avail.
Here is my bash script,
#!/bin/bash
for ((j=0;j<10;j++)); do
rtg map -i sample_NA19240/SRR003988 -t hg19 -o map_sample_NA19240/SRR003988- $j --start-read=$[j*1000000] --end-read=$[(j+1)*1000000]
done

It's in the program you are using, "rtg" :
# Pre-flight safety-belts
if [ "$(uname -s)" != "Linux" ] && [ "$(uname -s)" != "Darwin" ]; then
# If you comment this check out you are on your own :-)
echo "Sorry, only Linux and MacOS are supported."
exit 1
You can try the "suggestion", that is, remove the check in the file installer/rtg. If it works, you are lucky. Else use a vm or ask the rtg author.

Related

Extension .exe needed for WSL! How to write a generic script? (WSL, Cygwin, Linux, MacOS)

I use docopts in my Shell scripts. That works nicely from Cygwin.
I just need to be sure that docopts is present, at the top of my scripts:
command -v docopts > /dev/null 2>&1 || { echo >&2 "docopts not found"; exit 2; }
...
parsed="$(docopts -h "$help" -V "$version" : "$#")"
eval "$parsed"
But, in WSL, it needs the extension .exe to find the program to launch.
Should I adapt all my scripts this way?
DOCOPTS=
command -v docopts > /dev/null 2>&1 && DOCOPTS=docopts
command -v docopts.exe > /dev/null 2>&1 && DOCOPTS=docopts.exe
[ -z "$DOCOPTS" ] && { echo >&2 "docopts not found"; exit 2; }
...
parsed="$($DOCOPTS -h "$help" -V "$version" : "$#")"
eval "$parsed"
Or is there a much smarter way to do that, so that my scripts will work in any environment?
My recommendation is to install docopts in WSL rather than attempting to use the Cygwin docopts.exe version. That will (a) allow you to use the same config (without an .exe extension) in both, and (b) likely be more compatible. I've noticed and heard of a few idiosyncrasies when attempting to use Cygwin executables inside of WSL. WSL does a great job of providing the compatibility layer between Linux and Windows EXE, but Cygwin does some "magic" that might cause issues.
This looks good. Suggestion would be to have it configured based on the "uname".If uname is "cywgin" then DOCOPTS= docopts or docopts.exe based on WSL.This would be easier to maintain and would be readable.
Regards

Most efficient if statement in .zshrc to check whether Linux OS is running on WSL?

In my .zshrc file I conditionally set my PATH variable depending on whether I'm running on Linux or macOS - I'm now trying to figure out if there's a way I can efficiently detect from my .zshrc if I'm working on Linux running on WSL.
I'm wondering if I can somehow check for the existence of /mnt/c/Program Files or similar - but figure there must be a better way?
Example of my current .zshrc:
PATH="/usr/local/sbin:$PATH"
if ! [[ "$OSTYPE" == "darwin"* ]]; then
export PATH="$HOME/.nodenv/bin:$HOME/.rbenv/bin:$PATH"
fi
eval "$(rbenv init -)"
eval "$(nodenv init -)"
PATH="$HOME/.bin:$PATH"
if [[ "$OSTYPE" == "darwin"* ]]; then
export ANDROID_SDK_ROOT="$HOME/Library/Android/sdk"
export PATH="$PATH:$ANDROID_SDK_ROOT/tools:$ANDROID_SDK_ROOT/tools/bin:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/build-tools:$ANDROID_SDK_ROOT/tools/lib/x86_64"
export PATH="$PATH:/usr/local/share/dotnet"
fi
If anyone has any better ideas than somehow checking for the existence of /mnt/c/Program Files I'd very much appreciate it!
There are many possible way to check WSL in any shell. Most reliable ways are:
From uname -r command output.
From /proc/version file.
From /proc/sys/kernel/osrelease file.
#!/bin/bash
if uname -r |grep -q 'Microsoft' ; then
echo True
fi
if grep -q -i 'Microsoft' /proc/version ; then
echo True
fi
if grep -q -i 'Microsoft' /proc/sys/kernel/osrelease ; then
echo True
fi
Also there are many file existence can be checked with shell script. For example, only WSL has 1. /dev/lxss 2. /bin/wslpath 3. /sbin/mount.drvfs 4. /proc/sys/fs/binfmt_misc/WSLInterop 5. /etc/wsl.conf files but GNU/Linux distributions has not.
See more:
screenFetch
netfetch
In WSL, there is a special file for checking interoperability called /proc/sys/fs/binfmt_misc/WSLInterop which is WSL specific file. You can check using the following command:
#!/bin/bash
if [ -f /proc/sys/fs/binfmt_misc/WSLInterop ]; then
echo True
fi
or more simple one-line code(in bash):
[ -f /proc/sys/fs/binfmt_misc/WSLInterop ]
This will return exit code 0 if true, exit code 1 if false.
Thanks to Biswapiryo's comment - I came up with this solution to detect WSL:
if [[ $(uname -r)] == ^*Microsoft$ ]]; then
# Code goes here
fi
Short/current answer:
To detect either WSL1 or WSL2, you can use a modified version of #MichaelSmith's answer:
#!/bin/zsh
if [[ $(uname -r) == (#s)*[mM]icrosoft*(#e) ]]; then
echo test
fi
More detail:
When this question was originally asked, only WSL1 existed, and uname -r would return something like:
4.4.0-22000-Microsoft
This is not a "real" kernel in WSL1, but just the number/name that Microsoft chooses to provide in response to that particular syscall. The 22000, in this case, is the Windows build number, which currently corresponds to the WSL release. Note that this is the case even in the current WSL Preview in the Microsoft Store, even though it is decoupled from the Windows release.
With WSL2, however, Microsoft provides a real Linux kernel, which returns something like:
5.10.102.1-microsoft-standard-WSL2
Earlier versions may have left off the -WSL2 portion.
Of course, if you build your own WSL2 kernel, you should update the test to match the kernel name you provide.

How to detect whether Node installed when node is not available in Environment

I am trying to package an app that I have built for the Mac OS using the Packages software. For the app to install, there are pre-requisites which should be already installed on the system, one of which is node. I am checking for the pre requisites by Defining Requirement based on the result of an external shell script.
Basically, the packager software runs the specified external script and if the script returns a given value it proceeds else it throws an error.
I have written the following script to detect whether node is installed
#! /bin/sh
echo "Checking PreReq Node"
node --version | grep "v" &> /dev/null
if [ $? == 0 ]; then
echo "Node Installed"
exit 0;
else
echo "Node not installed"
exit 1;
fi
This works as expected when I run it in the shell, but when running within the context of the installer, node is not available in the environment so it fails. If I change the script to use the full path of node it works
#! /bin/sh
echo "Checking PreReq Node"
/usr/local/bin/node --version | grep "v" &> /dev/null
if [ $? == 0 ]; then
echo "Node Installed"
exit 0;
else
echo "Node not installed"
exit 1;
fi
However, node may be installed in a different location on a different system.
How can I check whether node is installed on a system without actually running node?
This may help you:
whereis node | grep ' ' -ic

vncserver bash script error in ubuntu 14.04.4 LTS

I use Ubuntu 14.04.4 LTS and installed vnc4server.
The basic script starting vncdesktops is under /etc/init.d/vncserver which is a bash script. This works fine for all users specified in /etc/vncserver/vncservers.conf with their arguments. But when a user is using csh instead of bash, the vncserver command doesn't work because of a syntax error in the vncserver script. The error occurs in the start() function which I show here.
start() {
. /lib/lsb/init-functions
REQ_USER=$2
echo -n $"Starting $prog: "
ulimit -S -c 0 >/dev/null 2>&1
RETVAL=0
for display in ${VNCSERVERS}
do
export USER="${display##*:}"
if test -z "${REQ_USER}" -o "${REQ_USER}" == ${USER} ; then
echo -n "${display} "
unset BASH_ENV ENV
DISP="${display%%:*}"
export VNCUSERARGS="${VNCSERVERARGS[${DISP}]}"
su ${USER} -c "cd ~${USER} && [ -f .vnc/passwd ] && vncserver :${DISP} ${VNCUSERARGS}"
fi
done
}
When I give the command 'sudo service vncserver restart' the vncserver script runs and give me this error for a user using csh.
Starting VNC server: 8:test1 [: No match.
user 'test1' is using csh and its display number is 8. I can see this error is coming from the line
su ${USER} -c "cd ~${USER} && [ -f .vnc/passwd ] && vncserver :${DISP} ${VNCUSERARGS}"
and I understand what it's doing but I don't know why the bracket condition is giving me this error and that only for a user using csh.
Can anyone give me a clue?
I don't know exactly why, but I found my /bin/csh was linked as below.
/bin/csh -> /etc/alternatives/csh
So I installed tcsh (apt-get install tcsh) and made the link like this.
/bin/csh -> /bin/tcsh
Then the problem is gone!
The su command and the command executed by -c option is being processed in the su'ed user's shell which was /etc/alternatives/csh which probably could not handle the [ -f ] condition. and I gues the /etc/alternatives/csh is a kind of default csh linked to when there is no real full fledged csh(like tcsh).

Is subversion installed

I am creating a bash script in linux, is there a way to detect if subversion is installed on the computer?
I am wanting to detect if its installed and if it isnt prompt the user to install it, I can prompt the user but I cant detect if the program is installed
PROG=$(which svn 2> /dev/null)
if [ -z "$PROG" ] ; then
echo "cannot find subversion" 1>&1
else
echo "Subversion installed at $PROG"
fi

Resources