Set Default Shell in Cygwin - shell

I've been using Cygwin for quite a while now. I now want to switch to fish from bash. Everyone is saying that you should use chsh -s /usr/bin/fish, but for some reason, chsh does not work for me. Trying to modify my Cygwin.bat file doesn't work either, and neither does changing my /etc/passwd file.
I really don't understand what's going on. Could someone please help me?

Try editing /etc/nsswitch.conf instead of /etc/passwd
Instead of creating a passwd file, which Cygwin recommends against1, you could edit /etc/nsswitch.conf. Add or edit the following line:
db_shell: /usr/bin/fish
The down/up side of this method is that, if you have multiple users, this change affects all of them. The up/up side is that it's dead simple. The only catch is that you have to restart Cygwin.
If you do use mkpasswd after this change, it will use your new default shell for all users that are allowed to log on.
References
1 The mkpasswd documentation says this:
Don't use this command to generate a local /etc/passwd file, unless you really need one. See the Cygwin User's Guide for more information.
I can't really find any solid reasoning in the user's guide, other than a mention that you'll have to regenerate the /etc/passwd and /etc/group files if your users and groups change, which I suppose is a decent enough reason. I can say that the process is somewhat error prone for newbies.

I randomly meet the same problem, and now I providing my solution for you.
0- Open cygwin by mintty.exe
1- Build passwd file manually (mkpasswd)
$mkpasswd > /etc/passwd
2- Change default shell in passwd file
$vim /etc/passwd
user:*:1976XX:1971XX:U-user\user,S-1-5-21-XXXX:/home/user:/bin/fish
3- Restart mintty.exe

There's an answer on SuperUser that is even simpler. Set the SHELL environment variable in Windows. Set it to your preferred shell (e.g. /bin/tcsh) and newly-launched shells should use it.
To set environment variables:
Go to the "System" control panel (right-click on the Start menu and select "System")
Click on "Advanced system settings" in the left-side column
From the "System Properties" window that pops up, click the "Environment Variables..." button
In either the "User variables" or "System variables" box (depending on whether you want the change to affect just yourself or all users), click the "New..." button.
Type "SHELL" in the "Variable name" box and the path (relative to the Cygwin file system) to your preferred shell in the "Variable value" box.
Click OK on the three open windows to save your changes.

I'm not sure how 'proper' of a solution this is, but I just added /usr/bin/zsh; exit to the bottom of my .bashrc file. You can substitute /usr/bin/zsh for the path to your shell of choice. It seems to work just fine so far.

If you're running Cygwin through ConEmu I found the easiest way is to replace commands line to run fish instead of default shell (Settings->Startup->Tasks):
""c:\cygwin64\bin\fish.exe" --login -i" (please change path to your cygwin folder accordingly)

I wanted to comment on the accepted answer, but not enough rep.
Regarding this method
$ mkpasswd > /etc/passwd
While this works to generate an /etc/passwd file, the odds are you're installing cygwin for yourself, and if your computer belongs to a domain, mkpasswd may run out and attempt to consume the entire domain user list. I had a 500MB+ /etc/passwd file from exactly this condition, and cygwin wouldn't even start until I deleted the file.
I strongly recommend, if using the mkpasswd route to use the -c switch, so it puts an entry in only for yourself.
$ mkpasswd -c > /etc/passwd
On a machine with a shared cygwin service (assuming you have write permissions)
$ mkpasswd -c >> /etc/passwd

I was trying to change my default shell in cygwin to zsh and I found parts of the answers
here helpful, but none of them gave a full solution. The best instructions I found were in the "installing zsh" instruction in the oh my zsh github repo by Robby Russel that you can find here
At the top of the page it has general instructions for installing zsh and then specific instructions for many different platforms. You can scroll down to the Cygwin section and follow the steps:
"The easiest way to change the default shell is to set your SHELL user environment variable. Search for "Edit Environment variables for your account" to bring up the environment variables window, create a new variable named "SHELL" and give it the value "/usr/bin/zsh/"."
(On Windows 7:
Press Windows key.
Start typing "environment".
When it appears, select "Edit environment variables for your account" and add the new variable as stated above.)
After I did this I closed and reopened my Cygwin shell window and tested that it worked with echo $SHELL. Expected result: /bin/zsh or similar.
Hope this helps!

Go to c:\cygwin or c:\cygwin64 (whatever is your cygwin home directory) and edit cygwin.bat. Instead of
bash --login -i
write, for example,
rem bash --login -i
tcsh -l

One simple way to do this is call tcsh at the end of .bashrc file
# x2=$(dirs +${cnt} 2>/dev/null)
# [[ $? -ne 0 ]] && return 0
# [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
# if [[ "${x2}" == "${the_new_dir}" ]]; then
# popd -n +$cnt 2>/dev/null 1>/dev/null
# cnt=cnt-1
# fi
# done
#
# return 0
# }
#
# alias cd=cd_func
tcsh
alias g=gvim
source ~/.cshrc
source ~/.aliases

Related

Git bash in Windows: change the default directory when opening mintty (pwd)

I am loosing a lot of time searching in internet for the following simple setting.
I installed git (and git bash) in Windows. What I want is just to open Git Bash and be in the directory I want. I don't want to change my home directory, just be in a given directory when I open the program.
More detailed, when I open Mingw / Git bash in Windows, I would like to be in the following folder:
/c/blabla/my_git_repositories
(this corresponds to the windows-style path: C:\blabla\my_git_repositories).
At the moment, I must write the following command every time I open GitBash:
cd /c/blabla/my_git_repositories
is this possible? Which file should i modify?
Actually the program is installed here:
C:\Program Files\Git\mingw64
Thanks
If you want it happening every time you start an interactive shell, add
cd /c/blabla/my_git_repositories
to your shell startup. If your install includes the manpages say man bash and find the INVOCATION section, in a decent pager just /^INV will do it. Or Google knows to interpret a search for man bash as a search for the bash manpage.
Windows doesn't ordinarily support shell logins at all so a lot of the shell's startup-circumstance detection is overkill on Windows. Executing it is extremely fast, but describing exactly how it decides takes a page or two.
The short form is, if the startup was told it's a login shell it reads the login startup files, including (your) ~/.bash_profile, which generally should check for an interactive login and if so source the normal interactive shell startup ~/.bashrc, so ~/.bash_profile should end with something like
[[ $- = *i* && -f ~/.bashrc ]] && . ~/.bashrc
and put whatever you want in ~/.bashrc. That cd, set up your prompt colors, define your favorite shell aliases, add your personal scripts directory to PATH, whatever.
Partial solution when opening the program by clicking on a link.
Right click on the link → properties → Start in: set the value to "C:\blabla\my_git_repositories".
This will work only when you open the application from that link, but could be fine (depending by your needs).

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.

Why does Cygwin not start Bash as a login shell

Apparently, when I start cygwin, bash is not invoked as a login shell with the consequence that my ~/.profile is not read.
I am not sure if this by design or if I have goofed with some setting somewhere.
Is there a canonical way to start cygwin's bash in a way that it executed my ~/.profile?
How I am starting cygwin: I go to the start button and click the Icon named Cygwin Terminal. It's properties show as target C:\tools\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -
The default shell for mintty is specified in /etc/passwd. If it does not exist, do the following:
Run mintty.exe as administrator and enter: mkpasswd -l -p "$(cygpath -H)" > /etc/passwd
This will create your log in credentials and should fix the issue. Leave the shortcut target as it is assuming the bin path you have stated is correct.
For more information: Cygwin mkpasswd documentation
Hope this helps.

Compact cygwin terminal

I'm looking for a way to make the cygwin terminal more compact, or an alternate terminal that is more compact. Currently, every command I enter has a header line above it with username and pwd, and there is a blank line trailing every command. For instance:
username ~
$ cd tmp
username ~/tmp
$
3 lines for every 1 line of command. I frequently work on a small screen, which makes all this wasted space quite irritating. Is there a setting somewhere I can alter to prevent all this wasted space? Or, perhaps another terminal?
Thanks in advance.
That's the default shell prompt set by Cygwin.
To use a smaller prompt in your current terminal:
PS1='$ '
To make the change permanent, put that command in your ~/.bashrc file.
You can set the prompt to just about anything you like, as explained by the bash manual (there are several variables that control different prompts; $PS1 is the main one).
It's important to remember than in Cygwin (as in Linux and Unix), the terminal program is a separate program from the shell that runs in it. The prompt is controlled by the shell; bash is the default. The graphical display is controlled by the terminal emulator, which could be rxvt, mintty, xterm, or even the Windows terminal that normally runs a DOS-like shell.
What you're seeing there is the prompt, as stored in the environment variable PS1
echo $PS1
will show you how it's created. By the way, that prompt is managed by the bash shell, not by the terminal.
export PS1=$
will give you just a $ prompt
export PS1="$ "
will leave some room behind the prompt. There are many more possibilities, here is a nice tutorial.
bash reads its settings from a file called ~/.bashrc aka a file called .bashrc in your home directory. Note that due to the initial dot in the name ls won't show the file by default, ls -a or ls -la will.
I would Recommend we go with modern terminals using Cygwin-X as shown in the below interactive menu
I love Xfce Terminal which allows creating tabs and new windows with font options and color options

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\$ '

Resources