Oh My Zsh How to run multiple `omz` commands - zsh

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?

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.

Related

WSL PATH environment variable is incorrect / zsh config not loaded [duplicate]

I am using Ubuntu via WSL 2.0 on Windows 10 and would like to run Texlive from the Windows command line. To do so I prepended the Texlive folder to the path in /etc/environment (I also tried a number of other locations eg. $HOME/.bashrc):
C:\Users\scott\Documents>wsl echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Windows/system32:...
C:\Users\scott\Documents>wsl
scott#SCOTT-PC:/mnt/c/Users/scott/Documents$ echo $PATH
/usr/local/texlive/2020/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Windows/system32:...
Why is there a difference between these two paths? Is it possible to change the first PATH variable?
To be honest, when I first looked at this question, I thought it would be an easy answer. Oh how wrong I was. There are a lot of nuances to how this works.
Let's start with the fairly "easy" part, though. The main difference between the first method and the second:
wsl by itself launches into a login (and interactive) shell
the shell launched with wsl echo $PATH is neither a login shell nor an interactive shell
So the first will source both login scripts (e.g. ~/.profile) and interactive startup scripts (e.g. ~/.bashrc). The second form does not get to source either of these.
You can see this a different way (and get to the solution) with the following commands:
wsl -e bash -c 'echo $PATH'
wsl -e bash -li -c 'echo $PATH'
The -li forces bash to run as a login and interactive shell, thus sourcing all of the applicable startup scripts. And, as #bovquier points out in the comments, a single quote is needed here to prevent PowerShell from interpolating the $ before it gets to Bash. That, or escape it.
You should be able to run TeX Live the same way, just replacing the "echo $PATH" with the startup command you need for TeX Live.
A second option would be to create a script that both adds the path and runs the command, and just launch that script through wsl /path/to/script.sh
That said, I honestly don't think that your current login/interactive PATH is coming from /etc/environment. In my testing, at least, /etc/environment has no use in WSL, and that's to be expected. /etc/environment is only sourced by PAM modules, and with no login check performed by WSL, there's no reason to invoke PAM in either the wsl nor the wsl echo $PATH commands.
I'd expect that you still have the PATH setting in ~/.bashrc or somewhere similar), and that's where the shell is picking it up from at the moment.
While this isn't necessarily critical to understanding the answer, you might also wonder, if /etc/environment isn't used for setting the default (non-login, non-interactive) path in WSL, what is? The answer seems to be that it is hard-coded into the init that starts up WSL. That init is also what appends the Windows path (assuming you don't have that feature disabled in /etc/wsl.conf).

Spawn shell and source in one command

I have sciprt that launches my development environment with multiple tmux tiles. I want to spawn a shell that sources my environment so I dont have to source it myself.
I usually do the following each time I open the tmux tile:
source env/bin/activate
I spawn my shell with $SHELL, I use zsh. I see that bash has the --init-file flag which sources a file, this also does not load the bashrc. I guess thats close but not good enough.
I am looking for something like this $SHELL --source ~/env/bin/activate. Or any workarounds also help
I don't think this is possible; Your best bet is to implement a workaround in your own .zshenv file, e.g.,
if [[ test -e "$MY_INIT_SCRIPT_675" ]] ; then
source "$MY_INIT_SCRIPT_675"
fi

Why can't zsh execute command compdef?

I have installed zsh and oh my zsh on Ubuntu 18.04. I would like to use autocompletion for kubectl. Therefore I have added source <(kubectl completion zsh) to my ~/.zshrc file.
On execution of this script zsh gets the following error:
complete:13: command not found: compdef
The kubectl documentation states that when one gets the error above, you should put the following on top of the .zshrc file:
autoload -Uz compinit
compinit
After doing this and restarting the terminal, I get the same error.
In a git-issue I found the following helped people with a common issue:
#This will perform chmod g-w for each file returned by compaudit to remove write access for group
compaudit | xargs -I % chmod g-w "%"
#This will perform chown to current user (Windows and Linux) for each file returned by compaudit
compaudit | xargs -I % chown $USER "%"
#Remove all dump files (which normally speed up initialization)
rm ~/.zcompdump*
#Regenerate completions file
compinit
zsh logs the following while running the script:
kubescript:12457: command not found: _bash_comp
Unfortunately this did not solve my problem. What else can I do to fix my issue? Or even still: what can I do to find out what is causing it?
I fixed the error by using the following code in .zshrc:
# K8s auto-complete
autoload -U +X compinit && compinit
source <(kubectl completion zsh)
You may also do it using oh-my-zsh plugin if you use oh-my-zsh.
I had the same issue and it was solved updating nvm
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
For my OSX 10.15.7 I did something similar
vi ~/.zshrc
alias k=kubectl
autoload -U +X compinit && compinit
[[ /usr/local/bin/kubectl ]] && source <(kubectl completion zsh)
Works like a charm!
I encountered this after installing the Angular CLI. Turns that Angular adds something into your .zshrc file.
If you recently installed Angular CLI, open ~/.zshrc and remove the lines added by Angular CLI.
After trying lot of options and going through diff treads. It worked for me after running below command
autoload -Uz compinstall && compinstall
This configures the ~/.zshrc and initialize the compinit by adding these 2 below lines:
autoload -Uz compinit
compinit
and then run below sudo commands which mentioned in link
$ sudo chmod -R 755 /usr/local/share/zsh
$ sudo chown -R root:staff /usr/local/share/zsh
$ compaudit | xargs chmod g-w
at last restart the terminal.
Hope this helps for someone.
In my case the issue was fixed after re-installing oh-my-zsh:
Deleted my old version rm -rf ~/.oh-my-zsh
Installed from https://github.com/ohmyzsh/ohmyzsh
I really tried every answer here, but nothing worked.
So, I tried this tutorial paying attention to the last observation:
"Note: Make sure you add this snippet before any call to compdef else you will still see the error"
I had a complete call from Terraform installation in my ~/.zshrc and ~/.bash_profile files.
https://thysmichels.com/2020/07/16/mac-solved-command-not-found-compdef/
For me I had this line:
source ~/.oh-my-zsh/plugins/git/git.plugin.zsh
In my ~/.zshrc file. Which was trying to source the plugin before it is loaded by plugins=(git)
Removing that line fixed it for me.
If you have added the plugins and everything works well, One of the reasons is you may be trying to use the plugin before it is loaded. As in my case.
This issue is (also) faced after installing Angular CLI (Angular Version 14.x) and accepting addition of autocompletion for the cli commands. Snippet from .zshrc:
# Load Angular CLI autocompletion.
source <(ng completion script)
Commenting out the source line resolved the issue for me (macOS 12.6 (21G115)).
# Load Angular CLI autocompletion.
# source <(ng completion script)
Still need to work out the root cause.

Zsh Docker Plugin not Working

I have been using oh-my-zsh for a while now and the docker plugin as recently stopped working for me for some reason.
I checked my ~/.zshrc file and the plugin is included
plugins=(git colored-man colorize github jira vagrant virtualenv pip python brew osx zsh-syntax-highlighting docker)
I checked the ~/.oh-my-zsh/plugins/docker directory and there is a _docker file in there. Yet when I type docker and press Tab, I get none of the autocomplete shortcuts that I used to get.
I can confirm that my git plugin works just fine but not the docker plugin. Tried doing exec zsh and source ~/.zshrc and restarted my terminal but no luck.
Am I missing something?
You might want to try and remove any .zcompdump-(...) files you may have on your user's home directory - using something like rm ~/.zcompdump* on a terminal, or some file browser - and then reload the .zschrc file with the command source ~/.zshrc or restart the terminal - whichever works best for you. See this
Then see if it works.
It seems oh-my-zsh is not loading plugins/docker/_docker file. You must add it to ~/.zshrc in an another way.
Add these lines to your ~/.zshrc file:
fpath+=($ZSH/plugins/docker)
autoload -U compinit && compinit
For me it was simply the case that I needed to launch Docker for the first time from spotlight on my Mac in order for Docker for Desktop to get the access it needed. Then the docker version command worked just fine.
Follow these steps if you are using oh-my-zsh and autocomplete is not working:
Make the following three links:
ln -s /Applications/Docker.app/Contents/Resources/etc/docker.zsh-completion /usr/local/share/zsh/site-functions/_docker
ln -s /Applications/Docker.app/Contents/Resources/etc/docker-machine.zsh-completion /usr/local/share/zsh/site-functions/_docker-machine
ln -s /Applications/Docker.app/Contents/Resources/etc/docker-compose.zsh-completion /usr/local/share/zsh/site-functions/_docker-compose
Either add autoload -Uz compinit; compinit to .zshrc or run in your shell:
echo "autoload -Uz compinit; compinit" >> .zshrc
In my case: Windows 10 + WSL2 + Hyper
I was having this error because I stopped Docker on Windows... Starting it again makes the error disappear in Hyper (thus, also in ZSH).
No .zshrc changes or additional commands to add inside.
#youhans's solution worked for me permanently. You might have permission issue to make needed adjustment on "zshrc". I have changed the permission to "read and write" and added the code snippet from #youhans's response to the end of "zshrc" file. Now completion system always works.
Before I had to type below snippet in command line whenever open a new terminal.
autoload -Uz compinit && compinit
In my case it occurred because of an alias. I had defined alias docker=docker.exe.
Removing that did it work again.
System & Environment
O.S.: Windows 10 Home, x64
Shell: Zsh (on Gitbash)
I think you may be missing ,'s in between each plugin.
plugins=(git, colored-man, colorize, github, jira, vagrant, virtualenv, pip, python, brew, osx, zsh-syntax-highlighting, docker)
Alternatively you can place each plugin on a separate line:
plugins=(
git
colored-man
colorize
github
jira
vagrant
virtualenv
pip
python
brew
osx
zsh-syntax-highlighting
docker
)

Why isn't my ZSH shell not changing the prompt?

I was using bash before switching to zsh.
On my ~/.zsh I have export PS1="\w ~ " but it is not making those changes to reflect the prompt. I want my prompt to show something like Documents/Rails_App/views ~
I have opened a new tab and closed re-opened the app.
The first level prompt of Zsh can be set in with either PROMPT, prompt or PS1.
Zsh uses other escapes than Bash. Most notably do they start with % not \. The equivalent to Bash's \w would be %~.
So just putting setting the following line in your ~/.zshrc should do the trick:
PROMPT='%~ ~'
Note: There is (usually) no need to export PROMPT in Zsh - or Bash for that matter.
If it does not work for you, it most likely has to do with Oh-My-Zsh as it already provides its own settings for PROMPT. So you have to make sure that you set PROMPT after Oh-My-Zsh has been sourced.
If you used the template that came with Oh-My-Zsh it should be after this line:
source $ZSH/oh-my-zsh.sh
On Debian distro.
After installing zsh from standard source apt install zsh comment #prompt adam1 inside .zshrc file and reload settings source ~/.zshrc.
Now add custom prompt: PROMPT='Greetings %n '
Image: zsh custom prompt
Use _PROMPT in zsh:
export _PROMPT='%d ~ '

Resources