Search code examples
zshoh-my-zshzshrc

Oh My Zsh How to run multiple `omz` commands


I have a basic script that installs and configures Oh My Zsh taking advantage of the omz command.

Here is a snippet:

/bin/zsh -i -c "\
omz theme set pygmalion &&\
omz plugin enable nvm &&\
omz plugin enable zsh-autosuggestions"

Unfortunately only the first command runs.

Even if I try to run

omz theme set pygmalion && omz plugin enable nvm && omz plugin enable zsh-autosuggestions

directly in my shell only the first theme command will be executed.

How to run all of those commands at once, inside of a script?


Solution

  • The omz function runs exec zsh after changing the configuration in order to reload zsh with the changes. That completely replaces the shell instance, which means anything else the shell was planning on doing (e.g. the commands after && or ;) will be discarded.

    You can see this in a short example:

    > print BEFORE; exec zsh; print AFTER
    BEFORE
    

    Some possible work-arounds.

    Option 1 - Call zsh multiple times.
    zsh -i -c 'omz theme set pygmalion'
    zsh -i -c 'omz plugin enable nvm'
    zsh -i -c 'omz plugin enable zsh-autosuggestions'
    

    The omz function will relaunch the shell within each call, but since there is only one command in each instance, nothing will be lost when the exec zsh is performed.


    Option 2 - Non-interactive zsh.

    In the omz function, the exec zsh is only run in an interactive shell, so launching zsh without the -i option should allow the subsequent commands to execute.

    Unfortunately, in the default oh-my-zsh setup, the omz function is set from .zshrc and is therefore only available in interactive shells. This means a bit more code is needed to load the function:

    zsh -c "
    . $ZSH/lib/cli.zsh
    omz theme set pygmalion
    omz plugin enable nvm
    omz plugin enable zsh-autosuggestions"
    

    If the ZSH variable isn't set when you make this call, you'll need to figure out its value (it's often ~/.oh-my-zsh/).


    Option 3 - Set .zshrc directly.

    It appears that the omz calls are just changing some lines in the .zshrc file, so you could make those changes from the script. A simple form might look something like this:

    print 'ZSH_THEME="pygmalion"
    plugins+=(nvm zsh-autosuggestions)' >> ~/.zshrc
    

    A more complex version could check to ensure that this isn't adding duplicate lines to the file (which is one of the things the omz script is doing).


    All of this seems kinda cumbersome. You may want to ask the OMZ maintainers if there is another option for updating configurations that avoids this issue.