Why does Cygwin not start Bash as a login shell - bash

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.

Related

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.

Executing a script in MSYS2/MinGW

On Windows, if I start c:\msys64\mingw64.exe, it opens a shell, where I can build my project, let's say by calling a release bash script (to simplify). Everything works fine.
Now, I would like to execute my release script on mingw64 directly, without interaction.
I tried:
c:\msys64\mingw64.exe /c/the/full/path/release
A window opens and closes, it does not work.
I attempted to use bash directly, but it seems the environment is not correctly set:
> c:\msys64\usr\bin\bash -c ls
/usr/bin/bash: ls: command not found
> c:\msys64\usr\bin\bash -c /bin/ls
... it works ...
So it is obvious that the environment is not the same as when execute c:\msys64\mingw64.exe then call ls.
How to execute my release script as if I were in the shell started by mingw64.exe?
To run a Bash shell script in MSYS2 without showing a window, you should right-click on your Desktop or somewhere else in Windows Explorer, select "New", select "Shortcut", and then enter something like this for the shortcut target:
C:\msys64\usr\bin\mintty.exe -w hide /bin/env MSYSTEM=MINGW64 /bin/bash -l /c/Users/rom1v/project/release.sh
Note that there are 4 paths in here. The path to mintty and release.sh are absolute paths that you will need to adjust. The paths to env and bash are relative to your MSYS2 installation directory. Note also that the first path must be a standard Windows path, since Windows expects that when it is running a shortcut.
Explanation
It might seem odd to use MinTTY for a non-interactive script, but we need to use some program that was compiled for the Windows subsystem (-mwindows option to GCC), or else Windows will automatically start a new console when we run the program. We pass the -w hide option to MinTTY to tell it not to actually show a window. Everything after that option is interpreted by MinTTY as a command to run.
So MinTTY will run /bin/env from the MSYS2 distribution and pass the remainder of the arguments on to it. This is a handy utility that is actually a standard part of Linux as well as MSYS2. It sets the MSYSTEM environment variable to MINGW64 (which is important later) and then it runs /bin/bash with the remainder of the command-line arguments.
We pass -l to Bash so that it acts as a login script, and runs certain startup scripts. In particular, the /etc/profile script from MSYS2 is essential because it looks at the MSYSTEM environment variable, sees that it is MINGW64, and then sets a bunch of other environment variables (e.g. PATH) to give you the MinGW 64-bit shell environment.
Finally, we pass the name of your script as the main argument to bash, so it will run that script after running the initialization scripts.
Error handling
Note that if your Bash script has an error, you won't get any notification, because the shortcut above doesn't open any console windows. I personally would find that pretty annoying. I'd probably remove the -w hide option, then make a wrapper bash script that just does something like:
run_my_main_script || sleep 10000
So if the main script is successful, exit right away, otherwise keep the window open for 10000 seconds. You don't have to even put that wrapper script in its own file, you can just put it in the shortcut as the argument to Bash's -c option (don't forget to wrap it in double quotes).
Thanks to the answers from #David Grayson, I managed to call my release script with msys2/mingw from a Windows console (cmd), with additional directories (for Java and Meson) in $PATH:
c:\msys64\usr\bin\env MSYSTEM=MINGW64 c:\msys64\usr\bin\bash -l -c "PATH=\"/c/Program Files/Java/jdk1.8.X_XXX/bin:/c/Program Files/Meson:$PATH\" /c/Users/rom1v/project/release"
add an supplement to the above: if u want to the output of shell script
reference:https://mintty.github.io/mintty.1.html
-l, --log FILE|-
Copy all output into the specified log file, or standard output if a dash is given instead of a file name. (Implies -o Logging=yes.)
If FILE contains %d it will be substituted with the process ID. See description of equivalent option "Log file" (Log=) below for further formatting options and hints.
Note that logging can be toggled from the extended context menu.
Add A complete example:
C:\msys64\usr\bin\mintty.exe -w hide -l - c:\msys64\usr\bin\env MSYSTEM=MINGW64 c:\msys64\usr\bin\bash -l -c "PATH=\"$PATH\" /C/Users/Administrator/Desktop/myProject/Demo_C_C++/shell/textProcess/bookNoteHandler.sh" | find /v "/v:Displays all lines that don't contain the specified"
=========

Set up path on prompt on pycharm terminal windon

I just upgrade pycharm into 2016.3.1. Before upgrade, I do not have problem to see the current directory path under the prompt on terminal window. After upgrade into pycharm 2016
3.1. All directory path on prompt on terminal window seems like messed up with 133;C;133;D;01337;RemoteHost=hawkins#pc_name.home1337;CurrentDir=/Users/hawkins/path133;MAC:path hawkins$ 133;B for some reason. Anyone have expereience on how to resolve this?
MAC:path$
133;C;133;D;01337;RemoteHost=hawkins#pc_name.home1337;CurrentDir=/Users/hawkins/path133;MAC:path hawkins$ 133;B
133;C;133;D;01337;RemoteHost=hawkins#pc_name.home1337;CurrentDir=/Users/hawkins/path133;MAC:path hawkins$ 133;B
133;C;133;D;01337;RemoteHost=hawkins#pc_name.home1337;CurrentDir=/Users/hawkins/path133;MAC:path hawkins$ 133;B
I had a similar problem. It turned out my problem was due to have iTerm shell integration installed.
As you have tagged the question [osx], I assume that you might also have done this.
There is a nice explanation to what these strange symbols mean in this answer: https://unix.stackexchange.com/a/294886/47407
I figured I could avoid having to uninstall Shell Integration by clearing my PROMT_COMMAND, and setting PS1 again. I made a shell script called pycharm_terminal.sh with the following
export PROMT_COMMAND=
export PS1="\[\e[31m\]\u\[\e[0m\] at \[\e[33m\]\h\[\e[0m\] in \[\e[32m\]\w\[\e[0m\] at [\A] \[\033[31m\]`git branch 2> /dev/null | grep -e ^* | sed -E s/^\\\\\*\ \(.+\)$/\(\\\\\1\)\ /`\[\033[35m\]\n$ \[\033[00m\]"
bash -i
The PS1 variable can be set to whatever you had before. This is just how I like mine.
Now, in PyCharm Settings: Go to Tools > Terminal and in "Shell path" set it to /bin/bash <path_to_pycharm_terminal.sh>.
Now try opening a new terminal in PyCharm. It shouldn't have those control character errors.
Solution that worked for me:
Go to Settings > Plugins
Find plugin "Python Terminal" and disable it
Restart PyCharm
The only negative effect I've noticed - auto activation of virtualenv on terminal start doesn't work.
for some reason, I figure it out by create a .pycharmrc under by user directories
and setting up /usr/local/bin/bash --rcfile ~/.pycharmrc under Tool->Terminal on shell path. It seems like it fixed but i have no idea why
MAC: path$ cat ~/.pycharmrc
exec bash
This is what worked for me:
Created new file pycharm_terminal.sh with one command bash -l
Then I set PyCharm Settings: to Tools > Terminal and in "Shell path" set it to /bin/bash/path_to_pycharm_terminal.sh.
Restart PyCharm and all work as expected
bash -l, by man, is a: -l Make bash act as if it had been invoked as a login shell (see INVOCATION below).
which is probably mean, that when PyCharm starts the Terminal and executing the pycharm_terminal.sh with bash -l, everything in .bash_profile is include by default
Found this question while trying to resolve similar issue for 'Geany' on mac osx. I had an install of iterm2 on my machine and was getting garbage in front of the terminal prompt.
similar solution as KPLauritzen offered also works for 'Geany' terminal as such.
Hope this helps someone:
Create shell script in home directory using desired PS1 & CLICOLOR settings:
~/geany_terminal.sh
export PROMT_COMMAND=
export PS1='[\e[1;32m][\u#\h \W] \D{%F %T}\n\$[\e[0m]'
export CLICOLOR=1
export LSCOLORS=gxBxhxDxfxhxhxhxhxcxcx
bash -i
Then I went to 'Edit -> Preferences --> Terminal' and set my 'Shell' to:
/bin/bash /Users/myusername/geany_terminal.sh
Upon reloading Geany, the Terminal now displays with PS1 and CLICOLOR settings exactly as I have set in my .bash_profile without garbage in front.
You can just activate your .bash_profile
/bin/bash --rcfile ~/.bash_profile

Set Default Shell in Cygwin

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

Windows shortcut to run a Git Bash script

Assuming I have a test.sh script that runs a server and Git Bash installed, how do I create a Windows shortcut that I can double click to run tesh.sh in Git Bash in the foreground and allows me to see the output of the server?
Git bash is already a batch file with content similar to this :
C:\WINNT\system32\cmd.exe /c ""C:\Git\bin\sh.exe" --login -i"
If you want run (and leave running) a shell script in the context of the shell, specify it at the command line. The trick is that when the script file name is interpreted, it uses the Windows path, not the equivalent path in the sh/Git environment.
In other words, to run the file D:\temp\test.sh in the Git shell and leave it running, create this batch file :
C:\WINNT\system32\cmd.exe /c ""C:\Git\bin\sh.exe" --login -i -- D:\temp\test.sh"
On the other hand, if you want to run a script and get your shell back, you should :
Open the shell as is
Edit or create ~/.profile (try vi ~/.profile)
Add this line : ~/test.sh (ajdust the path if needed)
So with a .profile that looks like this :
echo Executing .profile
/bin/sh ~/test.sh
And test.sh that looks like this :
echo Hello, World!
You will get this prompt :
Welcome to Git (version 1.7.11-preview20120710)
Run 'git help git' to display the help index.
Run 'git help <command>' to display help for specific commands.
Executing .profile
Hello, World!
ixe013#PARALINT01 ~
$
Other answers work, but there is a shorter solution, that fully answers the question, which was:
How to create a Windows shortcut that I can double click to run
tesh.sh in Git Bash
The answer is: add the following command to the Target: field of the shortcut:
"C:\Git\bin\sh.exe" -l "D:\test.sh"
Where, -l is the short for --login.
To better understand what this command does, consult with official GNU docs about Invoking Bash:
-l (--login): Make this shell act as if it had been directly invoked by login. When the shell is interactive, this is equivalent
to starting a login shell with exec -l bash. When the shell is
not interactive, the login shell startup files will be executed.
exec bash -l or exec bash --login will replace the current
shell with a Bash login shell.
Also note that:
You either need the full path to sh.exe or have it in your PATH environment variable (as others have already pointed out).
If you really need to force shell invocation in interactive mode, you can add the -i option
The last parameter is the path to the script that has to be executed. This path should be in Windows format.
Best solution in my opinion:
Invokes the right shell
No unnecessary windows
Invokes a bash script afterwards
Window will stay open after the script exits
Do the following:
Create a shortcut to mintty.exe on your desktop, for example. It is found under %installation dir%/Git/usr/bin/mintty.exe
Edit properties of the shortcut and change the target (keep the path):
"C:\Program Files\Git\usr\bin\mintty.exe" -h always /bin/bash -l -e 'D:\folder\script.sh'
Explanation of the parameters:
-h always keeps the window open when the script finished, so the window won’t disappear while you are still reading the output (remove if you don’t need to read the output and want the window to close automatically).
-l makes this shell act as if it had been directly invoked by login.
-e exits immediately if a pipeline returns a non-zero status (more info).
I'd recommend to use environment variable %ComSpec%, instead of absolute path to cmd:
%ComSpec% /c ""C:\Program Files (x86)\Git\bin\sh.exe" --login -i"
or even just cmd command, which is usually available from %PATH%:
cmd /c ""C:\Program Files (x86)\Git\bin\sh.exe" --login -i"
if your C:\Program Files (x86)\Git\bin added to PATH (which is also common solution and one of cases on TortoiseGit installing) you can use just:
cmd /c "sh --login -i"

Resources