Subject: Cygwin/Windows/DOS integration: Tips and Tricks
From: Jeff <[email-masked]>
To: [email-masked]
Date: Fri, 21 Dec 2007 13:29:51 -0800
Newsgroups: lists.cygwin
List-Id: <cygwin.cygwin.com>

These are an assortment of command lines, shortcuts, and such things
that I use to launch Cygwin tools from Windows Explorer, and from
console-mode programs, both native Win32 msvcrt-based and DOS. I offer
them to you all for whatever they are worth (if anything). I run these
under Windows XP Pro; some of them will likely work under 9x/ME as
well.

                                  ~~~

PATHS AND ENVIRONMENT

I've found that most of the console-mode Cygwin tools that I use run
just fine without being invoked by BASH; consequently, I have the
Cygwin binaries directories in my command path, and several environment
variables that Cygwin and specific Cygwin tools use; all of these are
set system wide. On Win XP Pro, these settings are accessed through "My
Computer/Properties/Advanced/Environment Variables/System Variables".
You will of course need Administrator access to modify these. I do not
recall if Win 9x has a GUI for setting environment variables (and I've
never had a chance to try ME), but 9x/ME will run autoexec.bat on
startup if it is found in the root directory of the boot drive;
environment variables set there will be available system-wide.

BASH inherits this environmnt when it starts up. $PATH is converted
somewhere in the startup process by something functionally equivalent
to 'cygpath -p'. Since many Win32 and DOS console-mode programs run
fine under BASH, I want BASH to preserve the $PATH it inherits, but to
add a few Cygwin directories to the front of it:

--------------------
PATH="/usr/local/bin:/bin:/sbin:/usr/sbin:/usr/sbin/awk:$PATH"
--------------------

Sure, /bin and /usr/local/bin are now seen twice in the $PATH string,
but it seems to harm nothing. This path statement insures that BASH
looks for Cygwin tools and apps first.

Other system-wide environment variables set for use by Cygwin and
Cygwin tools have path strings in POSIX format:

BASH_ENV=/etc/profile
HOME=/home
LYNX_CFG=~/lynx.cfg
SHELL=/bin/bash

To simplify path strings (including the $PATH string that BASH
inherits), explicitly mount each drive on your system:

$ mount -ft 'D:' /d

$ mount
[...]
A: on /a type system (textmode)
C: on /c type system (textmode)
D: on /d type system (textmode)
E: on /e type system (textmode)

This eliminates the necessity of prepending "/cygdrive" to every path
name outside of Cygwin.

With these tweaks, the following batch file...

>Jeff Lange wrote:
>> 
>> I use a bat file that looks like this:
>> 
>> ------------
>> @echo off
>> c:
>> chdir c:\cygwin\bin
>> bash --login -i -c /script.sh
>> ------------
>> 
>> -Jeff
>> 
>> 
>> On 4/18/06, gohans <[email-masked]> wrote:
>>>
>>> hello,
>>>
>>> i was wondering if it was possible to make a .bat file that could launch
>>> .exe and .sh files, on windows.
>>> If you have any idea about that, i would really appreciate.
>
>-- 
>View this message in context: http://www.nabble.com/making-.bat-to-launch-.exe-and-.sh-tp3964281p14454138.html
>Sent from the Cygwin list mailing list archive at Nabble.com.

..can be simplified to one command line (assuming that "script.sh" is
in a directory that is on the $PATH that BASH has):

--------------------
bash -li script.sh
--------------------

If "script.sh" takes parameters, just add them on to the end of the
command string. BASH will exit when "script.sh" is done.

Another consequence of having Cygwin in your system-wide PATH is that
the little cygwin.bat file in your "\cygwin" directory is no longer
necessary. Just create (or modify) your Cygwin short cut so that the
"Target:" is "bash -li" and "Start in:" is "drive:\path\to\cygwin\home".

RXVT

I use Cygwin RXVT in native mode (no X11 server) to make Cygwin
accessible to me: I just can't see the text in the default colors and
font with which BASH starts in a console-mode window, and the font and
color choices available in the shortcut properties is not flexible
enough to produce something that I /can/ see easily. If you are
perfectly happy with running BASH in a standard console window and do
not use RXVT, simply clip the 'rxvt -e' bits off of the following
command strings.

My .Xdefaults file:

*background: #00008A
*foreground: #DADA00
*colorBD: #D0D0D0
*colorUL: #8CD70F
*font: "DejaVu Sans Mono Bold-23"
font: "Lucida ConsoleP-bold-19"
*visualBell: True
*loginShell: True
*termName: rxvt-cygwin-native
*saveLines: 300
*geometry: 80x25

As suggested in the RXVT README, this .inputrc also helps:

"\e[3~": delete-char
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[H": beginning-of-line
"\e[F": end-of-line
"\e[7~": beginning-of-line
"\e[8~": end-of-line

I had some problems with RXVT and DejaVu fonts-- see:

http://cygwin.com/ml/cygwin/2007-12/threads.html#00158

The 23-point size is still highly visible (24 would be preferable), and
an 80x25 RXVT window with that font size fits nicely within a 1024x768
display. You will have to try different font sizes for other display
resolutions.

Lucida Console is a reasonably good monospaced font (it is what I was
using until even that became difficult for me to see), seems to work
well with RXVT at any size and, I believe, comes bundled with WinXP.

About Lucida ConsoleP: "Lucida Console TrueType font, encoded for DOS
codepage 437, rather than "ANSI" or a different national font. Why?
Because cp437 has lots of linedraw characters which are used by
bashprompt. Unlike the fonts in vgafonts.tar.gz, this font is a
TrueType outline font, and works with the native non-X port of RXVT,
available from the cygwin distribution." (available at
http://cygutils.fruitbat.org/bashprompt/ or through this Google search:
http://www.google.com/search?hl=en&q=%22lucida+consolep%22&btnG=Google+Search)

Given the environment variable settings and .Xdefaults file described
above, RXVT can be launched with BASH as the login shell by creating a
simple shortcut with the "Target:" as "rxvt" and "Start in:" as
described above for making a shortcut to BASH.

The maintainer of RXVT advises that RXVT be explicitly told to start in
native mode with 'rxvt -display :0'. According to the man page, RXVT
looks for DISPLAY to be set in the environment, and uses that if it is
found. I've never had a problem, but put 'DISPLAY=:0' in my system-wide
environment settings as described above, just to be safe.

INTEGRATION WITH WINDOWS EXPLORER

The Cygwin "chere" package, which will put a "<shell> here" item on
your Windows Explorer context menu for folders, is just the beginning
of what you can do.

*NOTE* Some of the following describes operations with regedit, the
Windows registry editor. All standard disclaimers about how it is
possible to corrupt your registry (to the point where your system will
no longer start normally, if at all) with this tool apply. Use at your
own risk. Make backups, at least of the branch you are modifying,
before proceeding. If you have never used regedit before, read up on
the Windows registry (and on what some of its various branches do)--
there is plenty of material on the 'net (Google is your friend)-- and
then browse through your registry *WITHOUT CHANGING ANYTHING* until you
have some basic familiarity with it, and with regedit. If you're really
not sure, back up your entire boot drive with a HDD imaging app like
Norton Ghost. Once again, you will need Administrator access to make
these changes.

HKEY_CLASSES_ROOT, which for convenience is displayed in regedit as a
separate branch right under "My Computer," contains all of your file
associations, where file extensions, folders, drives, and other items
are associated with applications. Opening this branch displays a long
list of file extensions. The very first key under this branch is simply
named `*'. Items placed under it show up in the Explorer context menu
for all /files/ (but not for folders and other items). Commands placed
under "HKEY_CLASSES_ROOT\*\shell" (create subkey "shell" if it doesn't
exist) also appear on the context menu and, if selected, perform the
desired command on the selected file. Note: While it is possible (and
perhaps safer) to edit file associations in Windows Explorer by
selecting "Tools/Folder Options/File Types", "HKEY_CLASSES_ROOT\*" is
not accessible from there.

Here is a *.reg script (translated from Unicode to ANSI) for placing
three Cygwin apps on the context menu:

--------------------
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell]

[HKEY_CLASSES_ROOT\*\shell\JOE]
@="Edit with &Joe"

[HKEY_CLASSES_ROOT\*\shell\JOE\command]
@="c:\\cygwin\\bin\\rxvt.exe -e bash -li cnvpath joe \"%1\""

[HKEY_CLASSES_ROOT\*\shell\Less]
@="View with &Less"

[HKEY_CLASSES_ROOT\*\shell\Less\command]
@="c:\\cygwin\\bin\\rxvt.exe -fn \"Lucida ConsoleP-bold-19\" -e bash -li cnvpath \"less -inmQ\" \"%1\""

[HKEY_CLASSES_ROOT\*\shell\Lynx]
@="View with &Lynx"

[HKEY_CLASSES_ROOT\*\shell\Lynx\command]
@="c:\\cygwin\\bin\\rxvt.exe -e bash -li cnvpath \"lynx -force_html\" \"%1\""
--------------------

To import this into your WinXP registry, copy and paste it into
Notepad, select "File/Save As" from the menu, give it a filename with a
".reg" extension, and select Unicode encoding. For Win 9x/ME, if I
recall correctly, simply paste it into any text editor and then save it
with a ".reg" extension. Then double-click on the resulting *.reg file
in Explorer, or open regedit and select "File/Import". The results will
show immediately-- there is no need to reboot for them to take effect.

Labels such as "Edit with &Joe" and "View with &Less" are what appear
on the context menu (the `&' is not displayed-- it tells Explorer to
use the next character as a keyboard shortcut). The apps being invoked
are detected to be console-mode, so the command lines are passed to
'cmd.exe /c' or 'command.com /c' (this works on 9x/ME systems, too).
The "%1" parameter contains the absolute path to the selected file-- if
the app is Win32 (msvcrt-based or whatever), it will be in long file
name format; if the app is DOS, it will be in DOS 8.3 format.

For some reason, I was not able to get variations of 'bash -li -c
<commands> $(cygpath "%1")' to work in this context so, as a workaround, I
wrote a tiny shell script to handle it:

$ cat /usr/local/bin/cnvpath
#! /bin/bash
ppath=$(cygpath "$2" | sed 's/ /\\ /g')
if [ -n $3 ] ; then
  eval $1 "$ppath" $3
else
  eval $1 "$ppath"
fi

You will notice that this script itself contains a workaround: the
current cygpath (1.42.4.1) does not escape spaces when it converts long
file names to POSIX (previous versions did), so that its output must be
filtered through sed. The double-quotes around "$ppath" are also
necessary.

The three command lines, without all the escapes that have to be in a
*.reg script, are:

Edit with &Joe
rxvt.exe -e bash -li cnvpath joe "%1"

Opens the selected file in my favorite text editor. Substitute
whichever editor you prefer.

View with &Less
rxvt.exe -fn "Lucida ConsoleP-bold-19" -e bash -li cnvpath "less -inmQ" "%1"

Opens the file in my favorite text file pager. Note the double quotes
around 'less' and its options. This is necessary for cnvpath to work.
Set LESSCHARSET=iso8859 in your system-wide environment settings to
make less properly display 8-bit characters, and use Lucida ConsoleP
instead of DejaVu to display DOS linedraw characters (which is
occasionally useful).

View with &Lynx
rxvt.exe -e bash -li cnvpath "lynx -force_html" "%1"

Opens the file in the lynx console-mode web browser, and tells lynx to
render any html found, no matter what extension the file name has. If
the file is plain text, lynx serves as a pager.

INTEGRATION WITH WIN32 AND DOS CONSOLE-MODE APPS

With Cygwin variables (and Cygwin binaries directories included in the
$PATH) loaded into the initial system-wide environment (so that any
command processor that the user or the system launches inherits them),
it becomes a relatively simple matter to launch shell scripts and
interactive sessions with a single command line. This command line can
then be called from a batch file, the "Target:" of a Windows shortcut,
an option on the Explorer context menu, and even the default action to
be performed on associated file (or other object) types. (Remember,
Windows Explorer is just another shell...)

They can also be called from any application (DOS, Win32 console mode,
or GUI) that accepts user-defined command strings for the purpose of
launching external apps. Launching a Cygwin interactive app (such as a
text editor or file browser) from a DOS or Win32 console mode app could
present a problem, though, since Windows will launch it in the same
console window by default.

This very most definitely becomes a problem if the command string calls
RXVT, because RXVT "hides" [sic - that's what the docs call it] the
console that launches it. RXVT does not hide its initiating console, it
/closes/ it entirely. When the RXVT session is closed, the console that
called it does not return. If that console had a process running in it
that was waiting for an external app to return control to it so that it
could resume, it will be left as a zombie process without a tty.

Fortunately, there is a solution. cmd.exe includes an internal command
called 'start', which launches a command in a new console window. If
called with 'start /wait', then it waits for the new console and it's
associated process to close before it returns. This is perfect. RXVT
can then close this new console, and 'start /wait' waits for RXVT to
close before returning control to the app that called it. The command
string to launch all of that would look like this (with [possibly]
optional elements in square brackets):

[cmd.exe /c] start /wait rxvt -e [bash -li] cnvpath \
<command | "command [options]"> <"path\to\file.ext"> [more options]

It may or may not be necessary/better/cleaner/whatever to use 'start
/wait' to launch BASH (without RXVT) in a separate console. Try it both
ways, and see which looks best.

It is my understanding that Win 9x/ME includes an external 'start.exe'
that does the same thing. I do not know, however, if it includes a
'/wait' option. Without '/wait', 'start' returns control to whatever
called it immediately after launching the new console window. This
behaviour is undesirable in most instances-- for example, a news
reader/mail user agent that creates a temporary file, opens it in an
external editor, and then reads the file back in when the editor exits.
With 'start /wait', a console-mode newsreader/MUA can call your
favorite Cygwin editor up in the environment and terminal program in
which it expects to run, and handle your article/post when you exit
your editor (which also exits RXVT); that is precisely the setup on
which I am writing this article. :)

EXPERIMENTATION

The command strings described in this article may work for you on your
setup exactly as written-- then again, they might not. :D It's just
like writing software: 40 minutes of debugging per every 20 minutes of
coding (and that's if you're really good). I had to try different
variations on each of these command strings (and write a couple of
small shell scripts into the bargain) to get them to work-- and you may
have to, as well. For example, I use a "shell" or "wrapper" utility
that stands between my newsreader/MUA and editor, which can
conditionally insert headers, add .sigs, pass a starting line number to
the editor, and other useful stuff. Here's a snip from its config file
(and the shell script it calls), which will illustrate what it is
sometimes necessary to do:

--------------------
true_editor = cmd.exe
add_params = "/c start /WAIT rxvt -e yarnjoe"
;jump_to_line     =  +%line   ; For the Thomson-Davidson Editor (TDE)!
jump_to_line     =  +%line   ; For the Vi IMproved editor (and joe)
--------------------

$ cat /usr/local/bin/yarnjoe
#! /bin/bash
joe $1 $(cygpath $2)

This script works because there are no spaces in the path name that
cygpath converts. $1 contains "+<line number>".

If you're not sure, make copies of config files and Windows shortcuts
and experiment with those, and /definitely/ export any branch of your
registry you plan to edit to a *.reg file before you modify your
registry. Having a system backup certainly doesn't hurt, either.

I hope these mods prove helpful to you, and extend the usability of
Cygwin for you as they have for me.

Jeff
-- 
"Sorry, my life is still in beta, and nowhere near stable enough for a
release."

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/