call blat from shell script, w8 - windows

Trying to execute blat http://www.blat.net/ from a shell script. I set the environmental PATH variable, and i can call blat from any location with the command prompt. Sending email from the command line works fine. But I'm not able to call it from within a shell script.
The (simplified) script
#!/bin/bash
blat
I get:
$ sh script.sh
script.sh: line 2: blat: command not found
I also tried by specifying the absolute path C:/Windows/System32/blat but that didn't work either.

There are many ways to solve this. If you will only run blat from Bash, you can
just put it in /usr/local/bin AKA C:\cygwin64\usr\local\bin.
If you need to run it from Bash and cmd/PowerShell, Windows "out of the box" has
pretty poor support for that. With Linux/Bash your PATH will usually look
something like this:
/usr/local/bin:/usr/bin
This is great because you have a system space, and a user space for programs.
However Windows looks like this:
C:\Windows\System32;C:\Windows
As you can see by default the PATH only has system space. This is bad because it
encourages people to do dumb things like put user programs alongside protected
operating system files. What Windows needs is the equivalent of
/usr/local/bin, a folder on the PATH, ahead of everything where people can
dump command line programs. Until that happens you just have to add your own:
Move blat.exe to C:\Users\<user>\Documents
Add that to PATH:
SETX PATH "%PATH%;C:\Users\<user>\Documents" /M
When you add it to Windows PATH, it automatically gets added to Bash PATH, so
the program should be available to all shells.

Related

Running a .bat script under Cygwin bash

I would like to use an existing DOS/Windows .bat script under a Cygwin bash shell. The .bat script creates a number of variables which need to exist after the .bat script ends.
This works, but the variables are not retained.
$ ./.phs_project_setup.bat .
It appears that this does not extend to sourcing a .bat script so that the variables it creates still exist in the environment.
$ . ./.phs_project_setup.bat .
-bash: #ECHO: command not found
-bash: SET: command not found
-bash: $'\r': command not found
-bash: REM: command not found
Any ideas on overcoming this obstacle?
What I have done is written the environment to a file, then iterated over the file using 'cygpath -u' on each value. Perhaps I have missed some, but it appears that cygpath will only change something that actually looks like a path. It does not change Oracle connect string for example; "user/pass#DB". I added 'export ' to the beginning of each line so that it can be sourced into a bash shell. It is not one step yet, but better.
Remember that Unix systems are generally case sensitive. cygwin's bash can run windows executables directly, but it's STILL case senstive. SET is not a valid bash command, while set is.
You can force it to source the file and try and run it, but it'll only be able to run shell built-in commands which have a 1:1 name correspondence to cmd commands. So set works, but #echo won't, because # means nothing to bash. Same goes for rem.
I would suggest trying to run the batch script using the batch interpreter (aka the COMSPEC environment variable, which is simply CMD) and then echoing out the environment it has set up as presented in this question: How I can use PowerShell with the Visual Studio Command Prompt?
You can then try and set up the environment in a similar fashion. Note that you may have a problem with the direction of slashes, drive names and other stuff like that
Sounds like you need to run the batch file and then start cygwin. If so, call the batch file from whatever file you use (cygwin.bat for example) to start cygwin. Then the variables should be available.
Alternatively, I've also moved the required bits into the proper unix configuration files to achieve the same results.

Run a bash script in cygwin using ./

I have a simple bash script that throw errors on a Windows machine in the Cygwin xterm terminal when I call it like so: ./myscript.bat. It runs fine when I call it like this: /cygdrive/c/cygwin/bin/bash.exe myscript.bat. I am thinking that my shell is not using bash by default. How can I set it to bash so that the next time I open the shell, I can execute my script using ./myscript.bat?
When you execute a file, Windows (or some component within Windows) decides how to execute it based on the extension part of the file name.
Cygwin inherits this functionality, letting you run Windows commands from within Cygwin. Cygwin also implements most of the usual UNIX functionality (running commands based on their content), but the combination of UNIX and Windows semantics can't always be perfectly clean.
The .bat suffix refers to a Windows batch file, so when you try to execute myscript.bat, the system treats it that way rather than as a bash script.
Change the file name from myscript.bat to myscript.bash or myscript.sh -- or just drop the extension altogether (since someone running your script shouldn't need to care how it's written).
There are several other filename extensions you should avoid (like .cmd), depending on how Windows is configured. A few quick experiments show that a .sh extension is safe, but really you don't need to use an extension at all for a shell script.
And, as R Sahu's answer says, you also need to make sure the script has execute permission if you haven't already done so:
mv myscript.bat myscript
chmod +x myscript
You'll probably need to change permissions of the file to make it an executable.
Try
chmod +x myscript.bat
./myscript.bat

Putting links to scripts in my cygwin bin

I have made a few python scripts, but is there an easier way to run them? I am using cygwin.
python "C:\Users\Desk\Dropbox\scripts\wsort.py" > data11414_unsorted.txt < data11414_sorted.txt
I want something like this (not typing the path name or "python"):
wsort > data11414_unsorted.txt < data11414_sorted.txt
where wsort is a link to my real wsort.py
Add a
Shebang
to the script
#!/bin/python
then invoke like this
wsort.py > data11414_unsorted.txt < data11414_sorted.txt
First, your question has a Windows-style path (backslashes, beginning with C:) rather than a Cygwin path (/cygdrive/c/Users/Desk/Dropbox/scripts/wsort.py). That implies you're not actually using Cygwin, or if you are, you're ignoring a bunch of warnings.
The below assumes you're using Cygwin Bash (which should be what you get if you start Cygwin Terminal from the Start Menu) and Cygwin Python (which you've installed using Cygwin's setup.exe, not a Windows Python installer). If your not, you're making life more difficult for yourself than you need to.
That out the way, there's a bunch of steps you need to take:
First, make the script executable. Use the chmod command for that, from a Cygwin Bash shell:
chmod +x /cygdrive/c/Users/Desk/Dropbox/scripts/wsort.py
Second, tell the system how to execute it. Add the following line to the top of the script:
#!/bin/python
(That's a "shebang". Python sees it as a comment, so doesn't do anything with it, but Cygwin and other Linux-like systems will use that line to see which program to run the script with. In this case, Python.)
Third, make sure your line endings are correct. Cygwin expects Linux line endings and will fail without them. This may not be a problem, but there's no harm in doing this. Run the following command:
dos2unix /cygdrive/c/Users/Desk/Dropbox/scripts/wsort.py
At this point, you'll be able to call the script by specifying the full path to it in Cygwin. You can't yet run it without specifying where the script is explicitly.
The fourth step is making sure the script is "in your path", ie in one of the folders where Cygwin looks for scripts to run. There are lots of ways to do this, but the most sensible is probably to just add your scripts directory to your path. The following command will add your scripts directory to your path whenever you start a new Cygwin session:
echo 'PATH="/cygdrive/c/Users/Desk/Dropbox/scripts:$PATH"' >>~/.bashrc
You will need to restart your Cygwin terminal for that to take effect, however.
At that point, you'll be able to run the script in Cygwin just by typing wsort.py (and thus use it with redirections and so forth as in your question).
Finally, to be able to call it simply as wsort, there's a number of options. The obvious one is just renaming the file. More usefully (and without copying the file or doing anything liable to break with Dropbox syncing things), try creating an alias:
echo 'alias wsort=wsort.py' >>~/.bashrc
Again, you'll need to restart your Cygwin terminal for that to take effect.
Maybe use an alias ?
alias wsort = "Command_Used"

Cygwin automatic script launch

Im trying to automatically run a script using Cygwin via CMD. I basically created a BAT file that goes to the directory and executes an .SH file. SH files are accosiated with Cygwin, and I tried something like "cygwin update.sh" in the command line. But all it really does is open Cygwin. I want Cygwin to automatically run the script file. Is there any easy way to do this, I've been trying to find but can't. Thank you!
You'll want to call the shell script with a particular shell, e.g. bash.
When having Cygwin open, call which bash to figure out where the binary is located. Cygwin also comes with tools that can convert paths between Cygwin and Win32 form, which is pretty helpful in cases like yours.
There is one other thing that may work, depending on your setup. There is an environment variable named PATHEXT which declares file extensions that are deemed "executable" by CMD. This can be used to your advantage, if Windows is configured so that the shell's "open" verb executes the correct shell for the file extension .sh (in your case).
Good luck.
From Cygwin Terminal, read man mintty. Try something like the following from a Windows Command Prompt:
c:\cygwin\bin\mintty --hold always --exec /cygdrive/c/path/to/bash/script.sh
I also found this!
http://rothmanshore.com/2011/01/26/kick-off-a-cygwin-script-from-a-windows-bat-file-with-a-different-working-directory/
I didn't quite understand it at first, but then it worked as I wanted it. Just if anyone knows, is there a way to make the script run without the CMD window open?? Thanks

Can I use cygwin to script a hudson build step?

I've tried executing the following:
#!C:\cygwin\bin\bash.exe
ls ${WORKSPACE}
But that doesn't find ls (even if it's on the windows path). Is there any way to set this up?
UPDATE: In other words, I want to be able to set up a build step that uses cygwin bash instead of windows cmd like this page shows you how to do with Python.
So put your cygwin's bin directory in your PATH.
In case you don't know how to do it (Control Panel -> System -> Advanced -> Environment Variables), see: http://support.microsoft.com/kb/310519
That shell-script has two errors: the hash-bang line should be "#!/bin/bash", and ${WORKSPACE} is not a shell-variable. Hudson has a bunch of variables of its own which are expanded in the commands you specify to be run (i.e. when you add commands in the web gui).
If you want to run Hudson build step on the Cygwin command line, you need to figure out what command Hudson runs and in which directory.
To give a more specific answer, you need to show us how your project is configured and what steps you want to run separately.
Provided cygwin's bin folder is in your path, the following works for me:
#!/bin/sh
ls ${WORKSPACE}
I find Hudson does not pick up environment variable changes unless you restart the server.
you might want to try to give a full path to ls
/cygdrive/c/cygwin/bin/ls
One other thing that seems to work is to use this:
#!C:\cygwin\bin\bash.exe
export PATH=$PATH:/usr/bin
ls
But it would be nice not to have to modify the path for every script.
Have you thought about power shell? as much as I like cygwin, it's always been a little flaky, powershell is a solid fully functional shell on windows, another option is Windows Services for UNIX it gives you korn shell or c shell not quite as nice as bash but it gets the job done
You will need to pass the --login (aka -l) option to bash so that it will source Cygwin's /etc/profile and set up the PATH variable correctly. This will cause the current directory to get changed to the default "home" but you can set the environment variable CHERE_INVOKING to 1 before running bash -l and it will stay in the current directory if you need to preserve that.

Resources