9

Using Cygwin, I installed Environment Modules by downloading source code, running configure, make, and make install. Every time I run a module command, I get:

init.c(718):WARN:165: Cannot set TCL variable '!::'

I've traced this down to the fact that Cygwin has the following environment variable set:

$ env | grep ::
!::=::\

Does anyone know what this is, where it is set, why it might be necessary, or how to get rid of it?

I might add that it's exceedingly difficult to Google, or even get to display correctly in Markdown.


From the comments:

$ unset '!::' 
-bash: unset: `!::': not a valid identifier
6
  • It's really odd for sure. temporarily remove it with unset '!::'
    – Otheus
    Dec 23, 2015 at 16:49
  • How did you install "Environment Modules"? A quick search on Cygwin's site came up empty.
    – Jeff Schaller
    Dec 23, 2015 at 16:51
  • It looks to me as if someone tried to use history expansion mechanism in some weird way, something went wrong and instead set a nonsensical variable.
    – jimmij
    Dec 23, 2015 at 17:10
  • $ unset '!::' -bash: unset: `!::': not a valid identifier
    – Ben Fulton
    Dec 23, 2015 at 18:34
  • I installed EM by downloading the source and running configure - make - make install
    – Ben Fulton
    Dec 23, 2015 at 18:35

2 Answers 2

9

This is nothing to do with Unix or Linux. It's entirely Win32 and Cygwin.

As first discussed in the Microsoft doco for Win32 and various Win32 programmers guides almost a quarter of a century ago, the Windows NT kernel doesn't have a notion of multiple drives each with their own individual working directories. This MS-DOS paradigm is emulated in Win32 using environment variables, not normally displayed by Win32 command interpreters' set commands (but fairly easily accessible programmatically), with names in the form =D: (where D is a drive letter). This pretense of multiple working directories, just like good old MS-DOS, is a shared fiction consulted and maintained by the Win32 API, Microsoft's command interpreter cmd, and the runtime libraries for various languages including some C and C++ compilers.

When a Cygwin process starts up, it converts the Win32 environment block into a "more UNIX-y" form. It has a whole set of hardwired special conversion rules for various specific variables, such as PATH. It's not in the Cygwin doco, but it also likewise deals with the =D:=D:\path environment strings by converting the leading = into a !. This yields environment strings, as Cygwin program execution sees them, of the form !D:=D:\path. It reverses this conversion when it needs to generate a new Win32 environment for whatever reason, such as spawning a new process, turning the ! back into a =.

To get Microsoft's command interpreter to display these environment variables, one simply runs

set ""
whereupon one will see output beginning something like

=C:=C:\Users\Jim
…

Sometimes, an extra one of these environment variables crops up, with : as the drive letter. Running the same set command as above yields output beginning

=::=::\
=C:=C:\Users\Jim
…

After this has been made "more UNIX-y" by Cygwin, this is of course the very !::=::\ that you are seeing.

Because these are a mechanism that is embedded within Win32 applications (within Microsoft's command interpreter most especially) and that is partly entangled in the Win32 API itself, it's not exactly trivial to prevent their existence.

Further reading

  • "CreateProcess()". Microsoft Win32 Programmer's Reference: Functions, A–G. Microsoft Press. 1993. ISBN 9781556155178. p. 213.
  • Jeffrey Richter (1995). Advanced Windows: The Developer's Guide to the Win32 API for Windows NT 3.5 and Windows 95. Microsoft Press. ISBN 9781556156779. pp. 26–27.
2

To make Modules exclude !:: from its TCL setup, modify init.c as shown in this unified diff, and recompile.

@@ -703,6 +703,11 @@

        envsize += strlen( environ[i]) + 1;

+#ifdef __CYGWIN__
+       if( *environ[i] == '!')
+           continue;
+#endif
+
        /**
         **  Locate the equal sign and terminate the string at its position.
         **/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .