4

When I run printenv one of the returned variables is !::=::\. I noticed that the variable exists because docker does not work correctly with it set.

$ printenv | grep ::
!::=::\

$ docker stack deploy keycloak -c keycloak.yml unexpected environment "=::=::\"

I am using git-bash on windows. The strange thing is that this variable only exists when I am using some terminal emulators such as ConEmu, Window terminal, Git-bash terminal while it does not exist when using VSCode's builtin terminal.

Why does this variable exist, and how do I remove it?

I tried the following methods with no success:

$ unset !::
bash: :: unrecognized history modifier

$ unset !::

$ unset !::

$ echo $!:: ::

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

$ printenv | grep :: | cat -A !::=::$

$ export !::= bash: :: unrecognized history modifier

$ export !::= bash: export: !::=: not a valid identifier

$ export $!::= bash: export: ::=: not a valid identifier

$ set +H $ unset !:: $ unset !:: $ env | grep :: !::=::

The following works:

$ env -u \!:: env | grep::

$ env -u !:: docker stack deploy keycloack -c keycloak.yml Creating network keycloack_default ...

My environment:
OS: Windows with git-bash (MSys based)
Bash version: 5.2.15(1)-release

  • Which OS do you use? What's your bash version (echo $BASH_VERSION or bash --version)? I can't even create this variable in bash, a variable name in bash must begin with alphabetic character or an underscore. Can you please also show the result of printenv | grep :: | cat -A? I want to see if there are some invisible characters there. – aviro May 22 '23 at 11:41
  • I am using git-bash on windows. BASH_VERSION=5.2.15(1)-release printenv | grep :: | cat -A shows !::=::\$ – anderio Moga May 22 '23 at 11:43
  • 1
    As far as bash is concerned, this is an invalid name for an environment variable, and it doesn't provide tools to manipulate it. The best solution would be to figure out where it comes from: either it's set in Windows, or it's set by some common library that some terminal emulators use, or it's set by some buggy Windows compatibility code in the initialization of git-bash (before user init files). Investigating this requires Windows expertise and is off-topic here, I suggest [su]. – Gilles 'SO- stop being evil' May 22 '23 at 12:20
  • I see this question was closed as a duplicate, but the answers to the duplicate question don't provide a workaround, they just explain why it happens. – aviro May 23 '23 at 08:24
  • The question is still a duplicate though, because the dupe does ask how to remove it – muru Jul 20 '23 at 14:30
  • Is it really duplicate? The goal of other the question is to get an explanation, and the goal of this question is to change the behaviour. – anderio Moga Jul 21 '23 at 12:01
  • It literally asks "how to get rid of it?" – muru Jul 22 '23 at 06:46
  • The question is indeed a duplicate, but close votes say, the question already has an answer, while that old question didn't get an answer that explains how to get rid of it. So while this question adds nothing, the answers are worth not to be hidden by the duplicate close. – Philippos Jul 27 '23 at 06:08
  • @Philippos-prostrike- that makes a case for the answers here to be merged there, not reopening, though. – muru Jul 27 '23 at 09:24

2 Answers2

4

Here how I solved it. I created a .profile file that if it identifies a variable with ::, it starts a new bash without this variable.

$ cat $HOME/.profile
if env |grep -q ::
then
        exec env -u \!:: bash
fi

By the way, I tried to see where it comes from; The bash process is created by a mintty process whose parent is 1:

$ ps -p $$
      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
     2150    2149    2150      12536  pty1     1234897 15:34:37 /usr/bin/bash

$ ps -p 2149 PID PPID PGID WINPID TTY UID STIME COMMAND 2149 1 2149 9644 ? 1234897 15:34:37 /usr/bin/mintty

And this mintty process is created with this environment variable:

$ grep -z :: /proc/2149/environ
!::=::\

But since there isn't actually an init process (pid 1), I don't know how exactly this mintty process is created by git-bash, and why it starts with this environment variable. But anyway, the workaround above worked for me.

aviro
  • 5,532
  • The variable originates from windows itself. If you launch a terminal from an existing terminal, the !::=::\ variable does not exist. If you launch a terminal using the UI, both git-bash (msys1) and msys2 will have the variable set.

    I have posted a superuser.com question here https://superuser.com/questions/1785348/bash-terminals-launched-from-windows-ui-have-an-invalid-variable-set

    – anderio Moga May 22 '23 at 13:00
  • I have accepted your answer because it does work even if it is a workaround. Hopefully the users at superusers.com will find a better solution. – anderio Moga May 22 '23 at 13:09
3

I have no idea why it exists, but you can unset it with env -u:

$ env | grep ::
!::=::
$ env -u \!:: bash -c 'env | grep ::'
$
choroba
  • 47,233
  • Wow, that seems to work. I can unset it that way; but is there any way that I can make the change persistent? – anderio Moga May 22 '23 at 11:41
  • Did you have this variable in the shell, or did you create it somehow? – aviro May 22 '23 at 11:42
  • @anderioMoga, please try unset \!:: – aviro May 22 '23 at 11:43
  • As written in the original question, unset \!:: does not work. – anderio Moga May 22 '23 at 11:44
  • @anderioMoga To make it persistent, you would need to track down what creates that environment variable and prevent it from doing so. – Kusalananda May 22 '23 at 11:56
  • There is one slight problem; I do not know where this variable is created. It is not consistent across different terminal emulators. And bash does not show it being created when its launched with -x set. – anderio Moga May 22 '23 at 11:57
  • I was able to set it from Perl: perl -lwE '$ENV{"!::"} = "::"; print "before"; system q(env | grep ::); print "after"; system q(env -u !:: bash -c "env | grep ::")' – choroba May 22 '23 at 12:05
  • @anderioMoga Since that is a different question, maybe you should ask it separately. Check existing questions first though, like this one: How to determine where an environment variable came from? – Kusalananda May 22 '23 at 12:16
  • I know it is a different question, and I have checked that. I am confident that it is not being set by any startup profiles or scripts. grep -r \!:: /etc/* and grep -I -r \!:: ~/* do not show any results. – anderio Moga May 22 '23 at 12:21
  • @Kusalananda That thread isn't relevant because here the variable is not set in shell code, it's clearly coming from some Windows thing (or a bug in some Windows-specific code in the bash port). – Gilles 'SO- stop being evil' May 22 '23 at 12:21
  • @Gilles'SO-stopbeingevil' That's fine, they can just ask a new question then, if it's on-topic on this site. Or on the https://superuser.com/ site if it turns out to be Windows-related. – Kusalananda May 22 '23 at 12:44
  • I have discovered that the variable only exists if the terminal session is launched using the graphical windows UI. If I launch my terminal from another terminal, it does not have the magic !::=::\ variable. So I will create a new post on superuser.com – anderio Moga May 22 '23 at 12:52
  • @choroba Unfortunally, this question was closed as a duplicate, but that original question fails to answer how to unset the variable. To help future users find their answer, please add your answer to the original question, too. Thank you. – Philippos Aug 15 '23 at 10:50