# What does eval $(opam env) do, does it activate a opam environment?

**URL:** <https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990>\
**Category:** Learning\
**Created:** [June 7, 2022, 8:55pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990 "2022-06-07T20:55:50Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![brando90](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/brando90/32/1745_2.png) [@brando90](https://discuss.ocaml.org/u/brando90)\
**Post date:** [June 7, 2022, 8:55pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/1 "2022-06-07T20:55:50Z")

</div>

I keep seeing

```auto
eval $(opam env)

```

e.g. when I try to install coq:

```auto
# brew install opam # for mac
# for ubuntu
conda install -c conda-forge opam
opam init
# if doing local env?
# eval $(opam env)

# - install coq
# local install
#opam switch create . 4.12.1
#eval $(opam env)
#opam repo add coq-released https://coq.inria.fr/opam/released
#opam install coq

# If you want a single global (wrt conda) coq installation (for say your laptop):
opam switch create 4.12.1
opam switch 4.12.1
opam repo add coq-released https://coq.inria.fr/opam/released
opam install coq

```

but I never know what it does (nor no one I talk to knows) and when I google it this comes up instead: [ocaml - What is the use of eval `opam config env` or eval $(opam env) and their difference? - Stack Overflow](https://stackoverflow.com/questions/30155960/what-is-the-use-of-eval-opam-config-env)

cross posted: [What does eval $(opam env) do, does it activate a opam environment? - Stack Overflow](https://stackoverflow.com/q/72522412/1601580)

* * *

# Clarification

Note that

```auto
eval `opam config env`

```

might be very similar. In the sense that I think the dashes `''` are also command substitution as in `$(...)` but not sure. Which might make [ocaml - What is the use of eval `opam config env` or eval $(opam env) and their difference? - Stack Overflow](https://stackoverflow.com/questions/30155960/what-is-the-use-of-eval-opam-config-env?noredirect=1&lq=1) very related (though I don’t know the difference for sure)

---

<div class="post-metadata">

**Author:** ![dbuenzli](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dbuenzli/32/18_2.png) [@dbuenzli](https://discuss.ocaml.org/u/dbuenzli)\
**Post date:** [June 7, 2022, 9:10pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/2 "2022-06-07T21:10:35Z")

</div>

Be curious ;–) invoke `opam env`.

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [June 7, 2022, 9:26pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/3 "2022-06-07T21:26:52Z")

</div>

If you check [Get Up and Running With OCaml · OCaml Tutorials](https://ocaml.org/docs/up-and-running) , there is a note there which explains it.

---

<div class="post-metadata">

**Author:** ![brando90](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/brando90/32/1745_2.png) [@brando90](https://discuss.ocaml.org/u/brando90)\
**Post date:** [June 8, 2022, 2:00pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/4 "2022-06-08T14:00:42Z")

</div>

> [@brando90](#):
>
> `opam env`

Honestly you are right, I could have been more curious (btw I did run that before your post).

It just seemed bizarre to me that there was no explanation or question of such a common and cryptic command. You need to know what `$()` is and also the `' '` since there are different ways to do the same. The difference of that and eval, what `opam env`…and to be honest, who truly likes coding in bash? Hard to be curious about such an ugly language. Ocaml and Coq are so much better 🙂

Anyway, will post an answer soon. I’ve made good progress on this.

* * *

Actually, in case I forget to answer here, I most likely will post my answer here: [What does eval $(opam env) do, does it activate a opam environment? - Stack Overflow](https://stackoverflow.com/questions/72522412/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/72537901#72537901)

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [June 8, 2022, 2:47pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/5 "2022-06-08T14:47:12Z")

</div>

> [@brando90](#):
>
> It just seemed bizarre to me that there was no explanation or question of such a common and cryptic command.

Explanation in the link I posted:

> **Please note** : The back ticks shown around `opam env` after `eval` are essential. They change the order of application, which is very important. The back ticks tells the system to first evaluate `opam env` (which returns a string of commands) and then `eval` executes those commands in the string. Executing them doesn’t return anything, but it initializes the Opam environment behind the scenes.

---

<div class="post-metadata">

**Author:** ![brando90](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/brando90/32/1745_2.png) [@brando90](https://discuss.ocaml.org/u/brando90)\
**Post date:** [June 8, 2022, 3:29pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/6 "2022-06-08T15:29:02Z")

</div>

**tldr: it activates your opam context according to your current switch – similar to how a python virtual env is activated in python but for opam.**

What `eval $(opam env)` does is command substitute `$(opam env)` i.e. run `opam env` in a subshell (that’s what `$( )` does) return the string it outputted and then give it to `eval` to evaluate as bash code. Command substitution is usually done to next the output of commands in bash. In python `eval` would interpret the input string to it as literal python code to evaluate, parse, run here similarly it would do the same but assume it’s bash (is my guess).

What does `opam env` does? It returns the current bash env variables for the current swithc (i.e. siwth approximately euqal to opam environment). So therefore, doing:

```auto
eval $(opam env)

```

does this:

1. first runs in a subshell because thats what `$(cmd)` does. It’s [command substitution][1]. Usually used to nest commands.
2. then it’s output (so the output string of `$(opam env)`) is given to `eval`. `opam env` returns a string of env variables needed to "activate: the current opam env (similar to how you activate virtual envs in python).
3. finally `eval` evaluates the string it receives from the command substitution i.e. it parses the string as a bash command and runs it.

For compeleteness see the output of `opam env`:

```auto
(iit_synthesis) brandomiranda~ ❯ opam env
OPAM_SWITCH_PREFIX='/Users/brandomiranda/.opam/4.12.1'; export OPAM_SWITCH_PREFIX;
CAML_LD_LIBRARY_PATH='/Users/brandomiranda/.opam/4.12.1/lib/stublibs:/Users/brandomiranda/.opam/4.12.1/lib/ocaml/stublibs:/Users/brandomiranda/.opam/4.12.1/lib/ocaml'; export CAML_LD_LIBRARY_PATH;
OCAML_TOPLEVEL_PATH='/Users/brandomiranda/.opam/4.12.1/lib/toplevel'; export OCAML_TOPLEVEL_PATH;
PATH='/Users/brandomiranda/.opam/4.12.1/bin:/Users/brandomiranda/miniconda/envs/iit_synthesis/bin:/Users/brandomiranda/miniconda/condabin:/usr/local/bin:/Users/brandomiranda/.opam/4.12.1/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin'; export PATH;

```

* * *

# Comment on backard ticks:

> **Please note** : The back ticks shown around `opam env` after `eval` are essential. They change the order of application, which is very important. The back ticks tells the system to first evaluate `opam env` (which returns a string of commands) and then `eval` executes those commands in the string. Executing them doesn’t return anything, but it initializes the Opam environment behind the scenes.  
> ref: [Installing OCaml · OCaml Documentation](https://ocaml.org/docs/up-and-running)

* * *

also see:

- [What does eval $(opam env) do, does it activate a opam environment? - Stack Overflow](https://stackoverflow.com/questions/72522412/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/72537901#72537901)
- [ocaml - What is the use of eval `opam config env` or eval $(opam env) and their difference? - Stack Overflow](https://stackoverflow.com/questions/30155960/what-is-the-use-of-eval-opam-config-env?noredirect=1&lq=1)
- [Installing OCaml · OCaml Documentation](https://ocaml.org/docs/up-and-running)

---

<div class="post-metadata">

**Author:** ![brando90](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/brando90/32/1745_2.png) [@brando90](https://discuss.ocaml.org/u/brando90)\
**Post date:** [June 8, 2022, 3:51pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/7 "2022-06-08T15:51:17Z")

</div>

related: [Why does command substitution with a command in front e.g. eval interprets the string as literal bash commands to execute? - Stack Overflow](https://stackoverflow.com/questions/72548704/why-does-command-substitution-with-a-command-in-front-e-g-eval-interprets-the-s) details of how command substitution works

---

<div class="post-metadata">

**Author:** ![brando90](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/brando90/32/1745_2.png) [@brando90](https://discuss.ocaml.org/u/brando90)\
**Post date:** [June 8, 2022, 4:41pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/8 "2022-06-08T16:41:35Z")

</div>

@yawaramin Trying to understand a few things. First when is `eval $(opam env)` or  
eval ‘opam env’ (use the other tick sorry don’t know how to display it) supposed to be ran? If I understand it correct, it “activates the opam environmen for a switch” so one is supposed to get into a switch first (e.g. `opam switch 4.12.1`), then one does `eval $(opam env)` to fully activate the env for that switch. Is that correct?

Related, I’m actually not sure what `opam init` does or why it’s needed despite reading multiple resources but my guess is that its only needed once during the first set up of opam. Is that right?

* * *

Context for question, I was told the following and trying to understand when to call `eval $(opam env)` correctly for the right switch I choose:

If you want a single global coq installation (for say your laptop):

opam switch create 4.12.1 opam switch 4.12.1 opam repo add coq-released [Index of /opam/released](https://coq.inria.fr/opam/released) opam install coq

If you want a local installation with a local opam environment:

opam switch create . 4.12.1 eval $(opam env) opam repo add coq-released [Index of /opam/released](https://coq.inria.fr/opam/released) opam install coq

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [June 8, 2022, 5:20pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/9 "2022-06-08T17:20:22Z")

</div>

The answer to both of your questions is, yes that is correct.

Now, another question may be, why even should opam require this `eval $(opam env)` dance? Can’t it just set up the environment without it? After all, we already need to run `opam switch ...` to select the opam switch we want to work in.

And that’s a valid question! Perhaps you would be interested in filing a ticket on the opam GitHub repo asking about this and seeing if it could be improved?

---

<div class="post-metadata">

**Author:** ![jbeckford](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jbeckford/32/3027_2.png) [@jbeckford](https://discuss.ocaml.org/u/jbeckford)\
**Post date:** [June 8, 2022, 9:40pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/10 "2022-06-08T21:40:35Z")

</div>

At least to answer the question of what `opam init`, `opam switch` and `opam env` do:

```bash
opam init --help
opam switch --help
opam env --help

```

For Opam, Dune and many other commands you will encounter in the OCaml community, they have decent `--help` pages. This fact won’t be obvious to people using OCaml for the first time. (An analog would be the Python community standardizing their documentation on Sphinx webpages like [https://readthedocs.org](https://readthedocs.org), or the OpenBSD community standardizing their documentation on man pages. If someone hadn’t told you, you could get lost).

* * *

What is missing, and what I think you are asking, is how do all the individual commands connect? A `--help` page may not be sufficient. Here is a stab at describing the typical flow:

| Command | When | DESCRIPTION from `--help` |
| --- | --- | --- |
| `opam init` | Once per machine | `opam init --help`: The init command initialises a local “opam root” (by default, ~.opam) that holds opam’s data and packages. This is a necessary step for normal operation of opam. The initial software repositories are fetched … |
| `opam switch create` | Once per project | `opam switch --help`: This command is used to manage “switches”, which are independent installation prefixes with their own compiler and sets of installed and pinned packages. … `opam switch set` sets the default switch globally, but it is also possible to select a switch in a given shell session. |
| `opam env --switch SWITCH` | Everytime you open a shell (ex. `bash`) terminal | `opam env --help`: Returns the bindings for the environment variables set in the current switch, e.g. PATH, in a format intended to be evaluated by a shell. … This is most usefully used as `eval $(opam env)` to have further shell commands be evaluated in the proper opam context. |

> Note: There is a way to avoid having to type `eval $(opam env)` every time you open a terminal: use `opam init --auto-setup` once and use `opam switch set SWITCH` once. See the `--help` for what those do. I personally don’t use that approach; YMMV.

---

<div class="post-metadata">

**Author:** ![brando90](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/brando90/32/1745_2.png) [@brando90](https://discuss.ocaml.org/u/brando90)\
**Post date:** [June 16, 2022, 5:31pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/11 "2022-06-16T17:31:08Z")

</div>

@yawaramin when do we run `eval $(opam env)`? is `eval $(opam env)` supposed to be ran before `opam init` or after it or after the switch has been activated e.g. `opam switch create debug_proj_4.09.1 4.09.1; opam switch debug_proj_4.09.1`?

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [June 16, 2022, 6:31pm UTC](https://discuss.ocaml.org/t/what-does-eval-opam-env-do-does-it-activate-a-opam-environment/9990/12 "2022-06-16T18:31:36Z")

</div>

This is explained in the ‘Up and Running’ page I linked to above and also in Jonah’s great answer above. If anything is not clear, would you mind filing an issue? There’s a link at the bottom right of the ‘Up and Running’ page.
