Date: Tue, 17 Nov 1998 10:59:11 +0200 (IST) From: Eli Zaretskii X-Sender: eliz AT is To: Jeff Williams cc: djgpp AT delorie DOT com Subject: Re: Environment variables with BASH In-Reply-To: <199811161556.JAA19107@kendall.> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp AT delorie DOT com On Mon, 16 Nov 1998, Jeff Williams wrote: > For example, if I set HOME in autoexec.bat, then start bash, HOME will > sometimes (and sometimes not) be set in bash. I can't figure out what > I'm doing differently when this happens. This has never happened to me. Please post details, in particular, if you invoke Bash in several different ways. > SYSROOT= > HOME= > PATH_EXPAND= > PATH_SEPARATOR= > PATH_SLASH= > TMPDIR= > > Do these variables have to be set in autoexec.bat, or in _bashrc, > or does it matter? It shouldn't matter. > Do these variables have to be EXPORTed if they are set in _bashrc? If Bash runs interactively, it always reads _bashrc, so you don't need to EXPORT them. But if you want them to be in effect when Make runs Bash, then you do need to EXPORT them. > Do these variables have to be set in any particular order? No. > Is the value for any of these variables determined by pre-existing DOS > environment variables, e.g., if PATH uses `;' must PATH_SEPARATOR be > `;' too? No. When you set PATH_SEPARATOR=:, Bash will automatically convert the value of PATH to replace ; with : and x: with //x/ (where x is any drive letter). > In general, how should these variables be set to achieve maximum > portability of my applications (mostly C programs, makefiles, and sh > scripts) from my Sun Unix box at work to my DJGPP box at home? If you want to have a portable Unix/DOS environment, you will need to make some effort in order to make it work. Here are some hints; ask more specific questions if they don't solve all your problems. 1) Makefiles and shell scripts--the easy way: The easy way is to set PATH_SEPARATOR=: and PATH_EXPAND=y in your DJGPP setup. This converts PATH to Unix-style form, but Bash will convert any //x/foo/bar pathnames back to their DOS form x:/foo/bar when invoking external programs. This works in many simple cases. Unfortunately, it does NOT work well enough in some non-trivial cases. The reason is that only Bash supports these //x/foo file names, and it only converts them to the DOS format when running EXTERNAL programs. This means that if the script/Makefile uses an internal command like `echo', you get the unconverted //x/foo. One example where this would bite you is when a script such as the GNU-standard configure creates a Makefile. If you use PATH_SEPARATOR=:, you will typically see a line like this in a generated Makefile: INSTALL=//d/djgpp/bin/ginstall And this will of course fail when Make will later try to run this Makefile. 2) Makefiles and shell scripts--take 2: If PATH_SEPARATOR+PATH_EXPAND don't work, you will have to make your shell scripts and Makefiles OS-aware. There are several differences between Unix and DOS/Windows that should be handled differently (see below). A portable script should find out on which type of system does it run and behave accordingly. Here's one way of detecting the OS type: if test -z "$COMSPEC$ComSpec"; then os_type=unix else os_type=dosish fi (The $ComSpec thing is for the NT, in case you are running a Win32 port of Bash.) If a Makefile, use either the conditional directives or the $(shell) function to do the same. Typically, you will run this test at the beginning of a script or a Makefile, and then use the result wherever an OS-dependent behavior is called for. 3) Things to watch for: Here are some subtle differences between Unix and DOS/Windows that need to be resolved once $os_type is set as above: - The PATH separator (: as opposed to ;). One way to handle this is to have a variable, say, $sep which is set to : or ; depending on $os_type. - Looking for an executable program: do NOT use "test -f gcc", because on DOS/Windows you will have gcc.exe. "test -x gcc" is the way to go, as the ported Bash knows to look for executable extensions when you use the -x switch. If your shell on the Unix side doesn't support "test -x", compute the switch dynamically using $os_type. - The format of an absolute file name. Some scripts test file names for being absolute and behave differently if they aren't. Typically, they think that "/*" is the wildcard pattern for an absolute file name. But on DOS/Windows you need to use something like "/*|[A-z]:/*" instead. - Hard-wired names for standard programs: do NOT use names like "/bin/rm" and "/tmp"; use "rm" and "${TMPDIR-/tmp}" instead. - Temporary files: avoid names like mytemp-$$.foo or temp.foo-$$, since they might clash in the DOS 8+3 namespace. Since $$ can produce up to 5 characters in DJGPP, don't use more than 3 characters in addition to $$, and don't put $$ into the extension. The best way to use temporary files safely is to create a temporary DIRECTORY and then put any files there without caring about their names. - End-of-line format. Do NOT assume that every line in a text file ends with a single Newline: most DOS files end with a CR-LF pair. This means, for example, that you need to use `diff' as opposed to `cmp' when comparing text files for identity. 4) It is advisable to put a line like this on your DJGPP.ENV in the [bash] and [sh] sections: PATH=%/>PATH% This converts PATH to lower-case and mirrors all backslashes to the forward Unix style, and avoids some subtle problems which are too long to describe. 5) Last, but not least: always make sure your shell scripts say "#!/bin/sh" on its first line, and your Makefile have a line which says "SHELL=/bin/sh". This causes Bash, Make, and all other DJGPP programs behave correctly when they run such Makefiles and shell scripts.