Terminal prompt on new Mac is not the same as on my existing Mac - macos

MacOS Ventura 13.1
M2 Silicon
Trying to set up a new mac. On my existing Mac, I have a .zshrc, and in it, I have the following:
## begin Git branch prompt
git_branch_test_color() {
local ref=$(git symbolic-ref --short HEAD 2> /dev/null)
if [ -n "${ref}" ]; then
if [ -n "$(git status --porcelain)" ]; then
local gitstatuscolor='%F{red}'
else
local gitstatuscolor='%F{green}'
fi
echo "${gitstatuscolor} (${ref})"
else
echo ""
fi
}
setopt PROMPT_SUBST
PROMPT='%/ $(git_branch_test_color)%F{none} $ '
# add 24h time the right side
RPROMPT='%D{%m-%d-%Y %k:%M:%S}'
## end Git branch prompt
And I would get something like:
/Users/jmac/Development/repos/p1 (development) $ 02-16-2023 19:20:56
(development) is in red, because I have not checked in my changes and the full path is there for me to see.
On the new Mac, there is no .zshrc by default, so I added the code to the .zprofile file, and it's not working the same. I see the date/time on the right, but I don't see the full path and the prompt looks like this:
/Users/jmac p1 % 02-16-2023 19:20:56
Any ideas? prompt modification is not my forte.

The short answer: create a ~/.zshrc file and move that code into it.
The slightly longer answer: something is overriding the value in the PROMPT variable. There isn't anything in the default zsh installation that'll turn the $ in your prompt into a %.
That 'something' could be in a few different forms. There may be code that is modifying the PS1 variable, which is essentially a synonym for PROMPT. Or there may be something hidden in scripts or functions called from ~/.zprofile (for example, oh-my-zsh does this, albeit usually from ~/.zshrc).
Some options
Try to trace what's happening in the zprofile file. One way to do that is to run these commands:
setopt xtrace
. ~/.zprofile
The main challenge here is often the sheer volume of the output; it may be difficult to find the spot where the prompt is being set.
Move the PROMPT assignment to the bottom of ~/.zprofile. Then your assignment should override whatever is setting the value earlier in the process.
Move the PROMPT assignment into ~/.zshrc. This is a better place for the assignment anyway, since .zshrc is only loaded for interactive shells, and setting the prompt is only used in interactive shells.
The code in ~/.zshrc is loaded after the code in ~/.zprofile, so this has a similar effect to the prior option.
If none of these options have any effect, then you'll need to look for other startup files, e.g. ~/.zlogin. There's a nice overview of how the various dot files are handled in zsh in this answer.

Related

Why VS Code on macOS suggests add $PATH to zprofile instead of zshrc?

I am studying zsh on macOS and I find when adding software to $PATH you are usually supposed to write them in .zshrc (zsh). However, Visual Studio Code documentation suggests
To add VS Code to your path, to do so run the following commands:
cat << EOF >> ~/.zprofile
# Add Visual Studio Code (code)
export PATH="\$PATH:/Applications/Visual Studio Code.app/Contents/Resources/app/bin"
EOF
I find zprofile set the environment for login shells while zshrc sets the environment for interactive shells. However, I cannot really see differences between two methods on macOS terminal since each terminal tab is a login session on macOS by default.
Is there any reason why Visual Studio Code on macOS suggests add $PATH to zprofile instead of zshrc and what will be the good practice?
If you read this and this answer as well as the man page (man zsh under STARTUP/SHUTDOWN FILES) you might come to the following conclusion:
You are using MacOS, therefore every zsh you open is a login shell, that way you made sure, that .zprofile will always be read. So if you append your $PATH in your .zprofile and and use zsh as a non interactive-shell you will be able to access your appended $PATH. This might happen in a script of if other programs try to use a program that you added to your $PATH.
Now on the other hand if you added VSCode to your .zshrc it will always be available in an interactive shell. Which mean if you use VSCode 'manually' you will always have it at your disposal in zsh. But other programs/scripts might not find it.
If you set environment variables in .zshrc or .zshenv it can be awkward if you want to use a different value. Say you install a different version of vscode in a different directory. Any new shell will reset the environment variable instead of inheriting it. As environment variables are inherited, there is no need to reset them for every new shell. So .zprofile is often a better choice - the variable is set on first login and inherited but can be changed for a shell and its children. Another option is to set them from .zshenv but use a condition around them such as if [[ ! -o privileged && -o rcs && $SHLVL = 1 ]]; then

WSL hide /mnt/c/Users/

It is possible to view shorter path in my terminal (VS Code & Hyper) with WSL (Ubuntu). On top of the Ubuntu, I have installed zsh. Currently, I am using a git bash and path looks Lukas#Y50-70 ~/Coding but with the Ubuntu, I have something like this lukas#Y50-70 /mnt/c/Users/Lukas/Coding. When I have a project in another 2 folders or so and I have a long branch name it is annoying to have a full row unnecessary info (for me).
Here is a comparison of Ubuntu and git bash:
Thanks
I was able to solve this using Named Directories - by adding this line to your ~/.zshrc file
hash -d c=/mnt/c
you will see '~c/' in your prompt rather than '/mnt/c/' which I think is a lot nicer.
This has a similar effect to setting an alias for the directory but the name is reflected in how your path is displayed.
As an added bonus you can then switch to that directory at any time by typing ~c
Check if the zsh installation guide under WSL can help (from neurogenesis):
Install zsh with sudo apt-get install zsh
bash.exe is the entrypoint to the WSL / linux subsystem. You'll have to modify the windows shortcut to specify bash -c --login or modify ~/.bashrc with exec /bin/zsh to properly load a different shell.
/etc/passwd isn't consulted because it's not a full login process. Be sure to set your SHELL env var as well. See #846 for details.
Fix your umask before you start installing things, otherwise tools like zsh will complain.
Specifically, "group" and "other" permissions will have the same privileges that owner do. This causes zsh's compaudit and compinit to fail (both are related to command completion).
See #352 for details. umask 022 can be added to your ~/.bashrc.
NOTE: This should be done before trying to install zsh plugin managers like antigen (otherwise the directory/file permissions issues from git clones).
You should also do this before installing RVM or rbenv.
I ended up inserting a few lines to the top of my ~/.bashrc, something like the following:
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
## Fix missing umask value
umask 022
## Launch Zsh
if [ -t 1 ]; then
cd $HOME
export SHELL=/bin/zsh
exec -cl $SHELL
fi
Issue 846 (mentioned in point 2) includes the comment:
A normal -c zsh symlink opened up in the wrong directory to me, but I managed using this (note the tilde):
C:\Windows\System32\bash.exe ~ -c /bin/zsh
See also "How to Use Zsh (or Another Shell) in Windows 10".
I know this isn't exactly the fix you were hoping for. I was looking to solve the same issue. The prompt was just too long and it was causing some of my commands to wrap to the next line. After seeing the comments on VonC's answer, I'm deciding to keep my next-best solution.
What I did in my ~/.bashrc file is this:
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u#\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\n\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u#\h:\w\n\$ '
fi
I added a \n right before the \$
So when I'm at my Windows home folder, it looks like this
ryan#DESKTOP-RSKAA4F:/mnt/c/Users/ryank
$
And I start typing my commands after the $. It takes up more vertical space, but at least I don't have to maximize my terminal window just to avoid text wrap.
It appears to me that just running 'cd' after starting the terminal session, re-bases the prompt to the normal '/home/(user)'
there should be no need for installing zsh or anything else. It works for me anyway.
also when starting the session at the root folder from windows, seems to do the trick.
I keep my sessions under
C:\vms
sample:
cd -d C:\vms\minikube\ubu_jenkinsX\rootfs
C:\vms\minikube\ubu_jenkinsX\rootfs>wsl -d ubu_jenkinsX
Yours may be under your userprofile in local data. Search for the rootfs folder
The reason your WSL prompt shows such a long path is because you're not actually in your home directory. You see, WSL has its own virtual filesystem separate from Windows, and Windows paths (like your C:\Users\Lukas\...) are stored under /mnt/c/Users/Lukas/.... Your WSL home directory would be /home/Lukas (since your WSL username is capitalized), but of course, that's not where your project is.
The fish shell has a prompt_pwd function that shortens a path to something like this:
0 ---- /m/c/U/L/Documents cd Something
0 ---- /m/c/U/L/D/Something prompt_pwd
/m/c/U/L/D/Something
Is that something you're interested in? You could port the function to Bash, or just switch to Fish, or just display the current directory name instead of path.

Zsh show fail every time when I open my terminal

I'm using a Mac with OS X Yosemite and Zsh.
By accident,I delete the content of three files below:
.bashrc
.bash_profile
.profile
After that ,when I open my terminal.
The Zsh will show fail under the last login information,it confused me ,and I want to know why.
You might want to look at a duplicate question: Zshell starts up with exit status of 1 after uninstalling RVM
It has an answer that solved the issue for me:
I found a .zlogin file on my system that contained some rvm-related code. I've deleted the code, and the problem is solved!
Zsh (by default) doesn't read from .bashrc, .bash_profile, or .profile, so the contents of these files shouldn't matter. You also didn't mention which .bashrc, .bash_profile, and .profile were erased… These files exist in both your /Users/username directory and /etc. The files sourced by zsh at startup are listed in the OS X zsh man page (man zsh in a terminal) under "STARTUP/SHUTDOWN FILES". The only reason it would call one of the previously mentioned files is if they were explicitly sourced in one of the default files.
My suggestions:
Check the contents of /etc/zshenv (this is the only zsh-specific file in my etc directory). Mine has only the following:
# system-wide environment settings for zsh(1)
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
Can you log in at all using zsh? If not, can you log in using another shell? You can do this in the OS X Terminal.app by going to Preferences -> General and changing the option for "Shells open with:" from "Default login shell" to Command (fill in another shell, i.e., /bin/bash or /bin/sh). If you can log in with any shell, try the following solution from this question:
Looking for the error
All shell output goes to the terminal, so you could just redirect it
when starting it. As you are looking for error messages during
initialisation, I'd suggest the following procedure:
Disable the problematic configurations
Open a terminal
Check the value of SHLVL: echo $SHLVL
Re-enable the configurations
Start a new z-shell from within the running shell with zsh 2> zsh-error.log, this redirects stderr to the file 'zsh-error.log'.
Check the value of SHLVL again. If it is bigger then previous value then exit the current shell (exit). (Explanation below)
Have a look at 'zsh-error.log' in the current directory.
If 'zsh-error.log' does not show anything, you may want to run zsh -x
2> zsh-error.log in step 5 instead. This provides a complete debug
output of anything zsh does. This can get quite huge.
As the answer suggests, those logs can get enormous if you are sourcing man files at startup. Just a bare shell should result in a reasonably small log file.
Finally, you can retrieve a list of all the files sourced by zsh on startup by running zsh -o sourcetrace.
Hope this helps.

Bash - Set a default prompt

I've set a bash prompt like this:
PS1='\W\[\e[31m\]$(git branch &>/dev/null; if [ $? -eq 0 ]; then \
echo " $(git branch | grep '^*' |sed s/\*\ //)"; fi)'
I want to make it default in order not to enter it every time I open the terminal.
(I'm using OSX lion / Terminal Version 2.2.1)
Solution: I put the PS1=... line in ~/.bash_profile as Hai Vu suggested.
Thank you all for your answers
Put the PS1=... line in ~/.bash_profile and it should work.
In general, look also for /etc/profile, /etc/bashrc, ~/.sh_profile, or ~/.profile ( usually for root it's .profile, and for non-root .bash_profile ), etc. In various versions of bash and host platforms, successful hit may vary :) Theoretically, bashrc and bash_profile (shrc, sh_profile) are for different purpose, rc file for shell configuration, and profile for various settings not related to shell itself, they're processed in fixed order, including system-wide and per-user configuration.
And I'm not sure, if executing an external command like "git" and piping to sed, grep and more is wise to use with prompt setup.
Disclaimer: I know nothing about OSX...
As I stated in my comment, your ~/.bashrc file is the place to put the command.
Depending on how the the shell is invoked you might need to add the following lines to
the file ~/.bash_login
if [ -f ~/.bash_login ]; then
. .bashrc
fi
And again, don't do the sed-thingie yourself to get the git-branch name into your prompt.
USe the amazing bash-script from here.
BTW, this is how my prompt looks like (using the script above):
PS1='\[\e]0;\w\a\]\n\[\e[32m\]\u#\h\[\e[31m\] $(__git_ps1 "%s") \[\e[0m\]\[\e[33m\]\w\[\e[0m\]\n\$ '

How to "source" ~/.bashrc automatically once it has been edited?

I would like to create an alias that does the following:
Opens TextMate with ~/.bashrc and allows me to edit it
Once I close TextMate, "sources" ~/.bashrc (so if I add a new alias, for example, it will be available immediately)
I tried the following:
alias b="/usr/bin/mate -w ~/.bashrc; source ~/.bashrc"
but it doesn't work: when I close TextMate, the shell doesn't return.
Any ideas?
I hesitate to suggest it, but if this is a feature you really want, you can make something similar happen by setting the PROMPT_COMMAND variable to something clever.
PROMPT_COMMAND is run every time the shell shows the shell prompt So, if you're okay with the shells updating only after you hit Enter or execute a command, this should nearly do it.
Put export PROMPT_COMMAND="source ~/.bashrc" into your ~/.bashrc file. Re-source it into whichever shell sessions you want the automatically updating behavior to work in.
This is wasteful -- it re-sources the file with every prompt. If you can get your editor to leave the old version in a specific file, say ~/.bashrc~ (where the first ~ means your home directory and the last ~ is just a ~, a common choice for backup filenames) then you could do something more like (untested):
export PROMPT_COMMAND="[ ~/.bashrc -nt ~/.bashrc~ ] && touch ~/.bashrc~ && source ~/.bashrc "
then it would stat(2) the two files on every run, check which one is newer, and re-source only if the ~/.bashrc is newer than its backup. The touch command is in there to make the backup look newer and fail the test again.

Resources