How to use function on git-prompt on Git Bash for Windows? - windows

I want to use the last exit code to customize my bash prompt. So following this question I should add $? inside a function:
PROMPT_COMMAND=__prompt_command
__prompt_command() {
local EXIT="$?"
...
I tried many times, but whenever I add a function on my C:\Program Files\Git\etc\profile.d\git-prompt.sh file, Git Bash can't run this file, and it doesn't use it.
Is there a way to use a function on git-prompt.sh on Git Bash for Windows, or another approach to use the last exit code to customize the bash prompt?

Follow these instructions to configure your git-bash prompt.
First, open git-bash, and cd to your ~ directory.
Using vim or nano, edit your ~/.bash_profile file to contain the following two lines:
test -f ~/.profile && . ~/.profile
test -f ~/.bashrc && . ~/.bashrc
Then create a ~/.bashrc file and add your custom prompt command function in this file:
PROMPT_COMMAND=__prompt_command
__prompt_command() {
local EXIT="$?"
# The rest of your code here
}
Make sure your changes saved correctly for both your ~/.bash_profile and ~/.bashrc files.
Open a new git-bash window. Assuming you have no bugs in your __prompt_command() function, your custom prompt should display properly.
If you quickly want to test your prompt, you can instead just run source ~/.bashrc in your current git-bash window rather than launching a second one.

Related

How to set `pipenv shell` prompt to match the Terminal's PS1 prompt?

I'm using MacOS and bash.
I'm using pipenv for virtual environments and I really want to make the look of my virtual shell match the look of my standard shell.
When I'm outside of pipenv, I set my .bash_profile so I could have the time, a green command prompt that shows the full path of my working directory and, if that directory has a git repo, it shows my current branch at the end.
I've searched for the correct file to edit to get the same look for each new pipenv shell, but I'm not having any luck finding the right file to copy my profile preferences to.
I'm wondering how I can set it up with my standard PS1 terminal appearance (colors and current git branch, etc).
pipenv-FAQ
Look at the shell does not show the virtualenv’s name in prompt:
This is intentional. You can do it yourself with either shell plugins, or clever PS1 configuration. If you really want it back, use
And for the "shell plugins"
You need to look not for "pipenv+bash" but for virtualenv+bash prompt solutions, such as:
How do I change the default virtualenv prompt?
It's hard for me to recommend "Which way is the best?"
(I'm using zsh myself)
I've searched for the correct file to edit to get the same look for each new pipenv shell, but I'm not having any luck finding the right file to copy my profile preferences to.
For bash, you can create and modify ~/.bashrc.
The pipenv shell command is a wrapper for virtualenv, which checks for a ~/.bashrc file when it activates a virtual environment for a bash shell. Anything in the ~/.bashrc file gets used in the spawned shell, including prompts, aliases, and other things you customized in your shell.
$ cat ~/.bashrc
cat: /Users/gino/.bashrc: No such file or directory
$ pipenv shell
Launching subshell in virtual environment…
bash-5.0$ . /Users/gino/.venvs/test-oiEjhH94/bin/activate
(test) bash-5.0$ ll
bash: ll: command not found
(test) bash-5.0$ exit
$ vim ~/.bashrc
$ cat ~/.bashrc
PS1='\[\e[1;33m\]\u#\W\$\[\e[0m\] '
alias ll="ls -Flh"
$ pipenv shell
Launching subshell in virtual environment…
gino#test$ . /Users/gino.mempin/.venvs/test-oiEjhH94/bin/activate
(test) gino#test$
(test) gino#test$ type ll
ll is aliased to `ls -Flh'
What you can do is to have a ~/.bash_prompt file where you set all your prompt configs (PS1) and a ~/.bash_aliases file where you set all your aliases. Then, source them both in the ~/.bash_profile (for the standard shell) and in the ~/.bashrc (for the pipenv shell).
~/.bash_prompt
# Format the prompt
# Shows up as:
# machine-name#current-working-directory$
PS1='\[\e[1;33m\]\u#\W\$\[\e[0m\] '
# other prompt configs
~/.bash_aliases
alias ll="ls -FlhpG"
# other aliases
~/.bash_profile
# For "main" shell (i.e. Terminal, VS Code terminal)
. ~/.bash_prompt
. ~/.bash_aliases
~/.bashrc
# For `pipenv shell`
. ~/.bash_prompt
. ~/.bash_aliases
A better solution would be to tell pipenv shell or virtualenv to reuse the configs in the ~/.bash_profile, but I haven't got that successfully to work (Terminal, pipenv, VS Code).
macOS 10.15
bash 5.0 (installed via Homebrew)
pipenv 2020.8.13

ROS installation: no such file or directory

According to ros wiki, to set up environment,
I typed
echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
The error is
/opt/ros/kinetic/setup.bash:.:8: no such file or directory: /home/pikashun/setup.sh
In ~/.bashrc file, there is the source /opt/ros/kinetic/setup.bash line.
I use Ubuntu on WSL.
How can I improve?
Thank you!
I had the exact same issue. The problem is not due to setup.bash either ~/.bashrc but the shell that you are using. It turned out that you may be using a different shell than bash (i.e., zsh). When you are executing the setup.bash of ROS, zsh interprets the following command (whici is in /opt/ros/kinetic/setup.bash) differently:
_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)
It is setting the _CATKIN_SETUP_DIR to your user directory. That is why you are getting error, cause you using the wrong path:
/home/user/setup.bash instead of /opt/ros/kinetic/setup.bash
To check whether this is the issue of your problem, you can check the shell that you are using by execute the following in the terminal:
echo $0; echo $SHELL
It may return something like:
zsh
/bin/zsh
To switch from zsh to bash, use:
exec bash
Once done this, you can use source without any problem.
And to switch back to your previous shell (assuming that is zsh), just use:
exec zsh
The file /opt/ros/kinetic/setup.bash does nothing but loading /opt/ros/kinetic/setup.sh from the same directory. I might be that you are not running bash (check which terminal you run), or that WSL has some different behavoiour than expected.
However, your can just alter your append command like so:
echo "source /opt/ros/kinetic/setup.sh" >> ~/.bashrc
or in your case, since the entry exists already in your ~/.bashrc, edit the line source /opt/ros/kinetic/setup.bash to source /opt/ros/kinetic/setup.sh
The packages or files were not actually downloaded from the "http://wiki.ros.org/melodic/Installation/Ubuntu". To overcome this error first open terminal
check your directory pwd. If your directory is like /home/'Your PC Name' it won't actually work.
Change the directory : Type cd /
Continue the installation process from start which mentioned in "http://wiki.ros.org/melodic/Installation/Ubuntu"
melodic can change to kinetic or other version if you wish

How to load .bash_aliases from perl/bash script

Lets say I have a perl script that setups a bash_aliases as follow
source file: bash_aliases.sh
alias w="cd /var/www"
install.pl
#!/usr/bin/perl
my $aliase_src= "${installation_dir}/bash_aliases.sh";
my $aliase_target="$ENV{'HOME'}/.bash_aliases";
if (! copy($aliase_src,$aliase_target))
{
print "Failed to copy file $aliase_src to Destination:$aliase_target. Reason:$! .";
die;
}
[command required to load .bash_aliases file]
I should be able to go as follow:
./install.pl
w
I dont want to :
./install.pl
source ~/.bash_aliases
w
I am unable to find command to load these aliases such that once the file is moved to home directory these aliases should be available to current script (install.pl) as well as all other script without running another command from command line e.g source ~/.bash_aliases OR . .bash_aliases
Edit
auto_load_aliases.sh using PROMPT_COMMAND (trying to following l0b0, answer)
#!/bin/bash
echo 'alias test="echo tested"' > $HOME/.bash_aliases
export PROMPT_COMMAND="$HOME/.bash_aliases";
this also did not work :
./auto_load_aliases.sh
test
What I expected what that auto_load_aliases.sh script sets the PROMPT_COMMAND , once it's set I have test aliase available.But that did not work.
~/.bash_aliases is not loaded by Bash by default, it is just a common convenience to avoid putting too much stuff in ~/.bashrc. If you want the aliases to be available in new Bash shells you have to source ~/.bash_aliases somewhere in ~/.bashrc. Some popular distributions (I believe Ubuntu is one) does this by default.
If you want to automatically source ~/.bash_aliases after changing it, you could try adding this in ~/.bashrc to source it after each command:
PROMPT_COMMAND='source ~/.bash_aliases'
If your alias file is very complex, you could make this faster by using inotifywait and only reloading the file when it changes.
Another way of loading aliases after changing them would be to replace the current shell with another one:
exec "$SHELL"
Bottom line, something has to change to automatically load new aliases. There is no built-in runtime configuration option in Bash to do this (and even then you'd have to enable that option).

.bash_history does not update in Git for Windows (git bash)

I am using Git for Windows (ver. 1.7.8-preview20111206) and even though I have a .bash_history file in my HOME folder, it never automatically gets updated. When I start Git Bash, I can see in the history commands that I manually added to the .bash_history file, but it does not get updated automatically.
I used the shopt -s histappend command to make sure that the history gets saved every time I close the shell, but it does not work.
If I manually use the history -w command, then my file gets updated, but I would want to understand why the shopt command does not work as I understand it should.
Anyone can tell me why is this behavior happening?
I put this in my ~/.bash_profile
PROMPT_COMMAND='history -a'
Create the following files
~/.bash_profile
~/.bashrc
And put the following line in both of them
PROMPT_COMMAND='history -a'
To do this from the console (Git Bash) itself, use the following commands:
echo "PROMPT_COMMAND='history -a'" >> ~/.bash_profile
echo "PROMPT_COMMAND='history -a'" >> ~/.bashrc
What history -a means
From the history --help command
-a append history lines from this session to the history file
What is PROMPT_COMMAND?
Bash provides an environment variable called PROMPT_COMMAND. The contents of this variable are executed as a regular Bash command just before Bash displays a prompt.
Difference between .bash_profile and .bashrc
.bash_profile is executed for login shells, while .bashrc is executed for interactive non-login shells.
When you login (type username and password) via console, either sitting at the machine, or remotely via ssh: .bash_profile is executed to configure your shell before the initial command prompt.
But, if you’ve already logged into your machine and open a new terminal window (xterm) then .bashrc is executed before the window command prompt. .bashrc is also run when you start a new bash instance by typing /bin/bash in a terminal.
On OS X, Terminal by default runs a login shell every time, so this is a little different to most other systems, but you can configure that in the preferences.
References
https://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x264.html
https://apple.stackexchange.com/questions/51036/what-is-the-difference-between-bash-profile-and-bashrc
As it was said here, to save git bash history on Windows you must not close the terminal with X button. Use exit command instead. History of commands will be saved then regardless of configuration mentioned in the accepted answer.
If you're using Git bash in VSCode please see C.M.'s comment above.
This worked for running git's bash in Visual Studio Code, but I had to put it ~/.bashrc not ~/.bash_profile. – C.M. Jul 29 at 14:43
This solved it for me.
There is a more complete answer on Unix Stackexchange, by Pablo R. and LinuxSecurityFreak. Add the following to your ~/.bashrc:
# Avoid duplicates
HISTCONTROL=ignoredups:erasedups
# When the shell exits, append to the history file instead of overwriting it
shopt -s histappend
# After each command, append to the history file and reread it
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
Please be careful, though:
The problem with this PROMPT_COMMAND solution is that the numbers for each history item changes after each command. For example, if you type history(1) ls (2) rm, then you do !1 to repeat (1), the history number might change and might run the rm command. Chris Kimpton
If you use git bash for windows 8, just put this in your ~/.bash_logout file:
history > .bash_history
Obviously you need a ~/.bash_history file.
Regards.
For me what worked was going into C:\Users\MY_USER\ and deleting the .bash_profile file.
Ps: I am using windows 10
I am using Windows 10 for me it was a permission problem, my temporary solution was to add Everyone group and give it Full control on ~/.bash_history file.
By the way, for those using the Portable version of Git for Windows, there's no need to create .bash_profile or .bashrc. Simply add to C:<path to your Git Portable folder>\etc\bash.bashrc:
PROMPT_COMMAND='history -a'
Found an answer in another post : https://superuser.com/questions/555310/bash-save-history-without-exit
If you want to have an history updated between two terminals.
As a window user I created a file .bash_profile inside my user folder. And then I add the following content : PROMPT_COMMAND='history -a;history -c;history -r'
Just run this in your git bash
echo 'HISTFILE=$HOME/.bash_history' >> $HOME/.bashrc

How to reload .bash_profile from the command line

How can I reload file .bash_profile from the command line?
I can get the shell to recognize changes to .bash_profile by exiting and logging back in, but I would like to be able to do it on demand.
Simply type source ~/.bash_profile.
Alternatively, if you like saving keystrokes, you can type . ~/.bash_profile.
. ~/.bash_profile
Just make sure you don't have any dependencies on the current state in there.
Simply type:
. ~/.bash_profile
However, if you want to source it to run automatically when terminal starts instead of running it every time you open terminal, you might add . ~/.bash_profile to ~/.bashrc file.
Note:
When you open a terminal, the terminal starts bash in (non-login) interactive mode, which means it will source ~/.bashrc.
~/.bash_profile is only sourced by bash when started in interactive login mode. That is typically only when you login at the console (Ctrl+Alt+F1..F6), or connecting via ssh.
If you don't mind losing the history of your current shell terminal, you could also do
bash -l
That would fork your shell and open up another child process of bash. The -l parameter tells Bash to run as a login shell. This is required, because .bash_profile will not run as a non-login shell. For more information about this, read here.
If you want to completely replace the current shell, you can also do:
exec bash -l
The above will not fork your current shell, but replace it completely, so when you type exit it will completely terminate, rather than dropping you to the previous shell.
You can also use this command to reload the ~/.bash_profile for that user. Make sure to use the dash.
su - username
I like the fact that after you have just edited the file, all you need to do is type:
. !$
This sources the file you had just edited in history. See What is bang dollar in bash.
You just need to type . ~/.bash_profile.
Refer to What does 'source' do?.
Save the .bash_profile file
Go to the user's home directory by typing cd
Reload the profile with . .bash_profile
Add alias bashs="source ~/.bash_profile" into your Bash file.
So you can call bashs the next time.
If the .bash_profile file does not exist, you can try to run the following command:
. ~/.bashrc
or
source ~/.bashrc
instead of .bash_profile.
You can find more information about bashrc.
Use
alias reload!=". ~/.bash_profile"
Or if want to add logs via functions:
function reload! () {
echo "Reloading bash profile...!"
source ~/.bash_profile
echo "Reloaded!!!"
}
While using source ~/.bash_profile or the previous answers works, one thing to mention is that this only reloads your Bash profile in the current tab or session you are viewing. If you wish to reload your bash profile on every tab/shell, you need to enter this command manually in each of them.
If you use iTerm, you can use CMD⌘ + Shift + I to enter a command into all current tabs. For terminal it may be useful to reference this issue;
I use Debian and I can simply type exec bash to achieve this. I can't say if it will work on all other distributions.
I am running macOS v10.12 (Sierra) and was working on this for a while (trying all recommended solutions). I became confounded, so I eventually tried restarting my computer! It worked.
My conclusion is that sometimes a hard reset is necessary.
Simply re-sourcing the file won't "reload" in the sense that something is first unloaded, then loaded again. If that is what you want you can do:
hash -r && _SHOW_MESSAGES=1 exec -a -bash bash

Resources