bash not finding function when new bash shell open - bash

I am on MacOS. I recently upgraded to Mojave. I'm running the Homebrew version of GNU bash, version 4.4.23(1)-release (x86_64-apple-darwin17.5.0).
When I open a new bash shell by issuing the bash command, I get the following error every time I issue a new command:
bash: parse_git_branch: command not found
The error is getting generated from the following line in my .bashrc file that customizes my command line with the git :
export PS1="\[\033[32m\]iMac5K# \[\033[33;1m\]\w:\[\033[m\]\[\033[33m\]\$(parse_git_branch)\[\033[00m\] "
(Note: my .bashrc file is sourced by my .bash_profile file.)
The parse_git_brach is in my .bashrc file so I'm not sure why I am getting this error. Even after I manually source .bashrc, I still get the error.
Issuing which bash yields:
/usr/local/bin/bash
Thanks.

When you just run bash without -l or -i, it doesn't execute .bash_profile or .bashrc itself, but only honors variables it received through the environment.
When you export a variable, you're exposing it to child processes... through the environment.
So, your child shell receives the PS1 definition, but it doesn't receive the function that PS1 requires!
You have some options here:
Export the function alongside the PS1 definition that uses it. That is, export -f parse_git_branch. This has an important caveat in that only shells which read exported functions (which is to say, in practice, bash) will get any benefit from this fix.
Stop exporting the PS1. That is, just take the export off the line PS1='...'.
Set BASH_ENV=$HOME/.bashrc and ENV=$HOME/.bashrc, which will instruct even noninteractive shells to run .bashrc (of course, this can change the way scripts execute, and is thus at a risk for causing bugs in other software; moreover, the latter means your .bashrc needs to be written to be safe for non-bash shells).

Related

Different java version in .sh file and terminal MAC

I'm trying to set JAVA_HOME in macOS 10.14. Currently there are 2 jdk versions (jdk-11.0.8.jdk, jdk-14.0.2.jdk) installed in /Library/Java/JavaVirtualMachines and I've exported env variable in .bash_profile
export JAVA_HOME=`/usr/libexec/java_home -v 11`
In terminal all is ok. java -version prints 11.0.8, echo $JAVA_HOME shows 11's directory.
But in ~/test.sh file java -version prints 14.0.2, $JAVA_HOME is empty. I tried to set env var in etc/profile but no success. Does anyone know what could possibly cause this?
Welcome to the wonderful world of POSIX semi-compatible shells :-)
From the bash man page:
When bash is invoked as an interactive login shell, or as a non-interactive shell
with the --login option, it first reads and executes commands from the file
/etc/profile, if that file exists. After reading that file, it looks for
~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and exe-
cutes commands from the first one that exists and is readable. The --noprofile
option may be used when the shell is started to inhibit this behavior.
Note that simply running a script does not execute the ~/.bash_profile script as the script is neither interactive nor a "login" shell. One solution is to set the BASH_ENV var to an appropriate initialization script.

Issue with environment variable on Mac OS sierra

I am seeing a strange problem with the storing of an env in mac os.
I set custom env in ~/.bash_profile
export MYENV=user
Then ran the . ~/.bash_profile and then I printed the env using
printenv then I can see the MYENV=user in the list.
If I close the terminal and reopen and execute printenv then I could not see MYENV in the list still I can see the export MYENV=user in ~/.bash_profile. It seems strange to me.
I am using Mac os High Sierra 10.13.6.
Could some body please tell me what mistake I am doing?
Note that ~/.bash_profile is only run for login shells. From the man page:
When bash is invoked as an interactive login shell, or as a non-interactive shell
with the --login option, it first reads and executes commands from the file
/etc/profile, if that file exists. After reading that file, it looks for
~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and exe-
cutes commands from the first one that exists and is readable. The --noprofile
option may be used when the shell is started to inhibit this behavior.
So if you terminal isn't launching the shell with -l, --login or with $0 having a leading hyphen it won't be a login shell and thus won't read ~/.bash_profile. You may need to reconfigure how your terminal launches the shell if you want the shell to read that config script.
On the other hand ~/.bashrc is always read by an interactive shell. So if you put the export in that script it should do what you expect. It certainly does for me. You replied to Amila that it didn't work for you. So I'd suggest a simple experiment. Open two terminal windows. In one edit ~/.bashrc and add these two lines:
echo running .bashrc
export WTF=abc
In the other window just run bash. It should echo that message and echo $WTF should print abc. Now open a new terminal window. If you don't see that message and the env var isn't present then something is inhibiting reading that config script. Possibly the shell is being run with the --norc flag.
~/.bash_profile is executed before the initial command prompt is returned to the user, which means after a new login. Try adding the environment variable to ~/.bashrc instead.

Getting error for command not found in less and shell

according to less manual,
!command Execute the shell command with $SHELL.
I have an alias pbcopy='nc localhost 2224'
I tested but get
!pbcopy
/bin/bash: pbcopy: command not found
!done (press RETURN)
What I tried
put alias in .bash_profile, .bashrc, .profile, none of them works
!source .bash_profile in less. not working
!alias pbcopy='nc localhost 2224'
I really need some help to understand this.
aliases are not commands.
Your shell is likely not loading them.
And if it is loading them they aren't available in non-interactive shells by default so they still won't work without you explicitly turning aliases on.
Either create that as a shell function or as a shell script in your $PATH.
It is also almost certainly the case that each !cmd invocation is started in a new shell so you cannot carry assignments, variables, functions, etc. from one to the next.

How to run a script with Git bash with custom bashrc?

I am trying to get a bash script to run in git bash while specifying a different .bashrc than the one in my home directory (or none at all) however it is proving an impossible task.
To my understanding this should work:
"C:\Program Files (x86)\Git\bin\sh.exe " --rcfile .bashrc --login -i C:/Scripts/myscript.sh
However no matter what I try either the --rcfile file flag will be completely ignored or the script will get parse errors because it is not parsed by bash.
The following are my findings:
--login flag is needed to get the script to be parsed by bash rather than windows command prompt
--rcfile and also --norc are completely ignored if flags --login is used
I have tried every possible combination I think of, including calling the script within my .bashrc file, swapping the flags around, using the -c flag to run the script command and swapping my .bashrc files around to try using the --norc flag instead.
Is this just a result of shitty bash implementation for windows or am I doing something wrong?
Any help on the matter is appreciated.
You can try sourcing your .bashrc inside the script myscript.sh.
source .bashrc
Or
. .bashrc
As far as I can tell, the -i flag is overridden by the fact that you provide a script for bash to run. Your shell isn't actually interactive, so --rcfile is ignored. The only way I can tell to both run a script and source an additional file is to use a non-interactive login shell; however, in that case, you are restricted to using .bash_profile, .bash_login, or .profile, whichever is found first:
bash --login myscript.sh
There is no --loginfile to override the choice of file sourced prior to myscript.sh.
UPDATE: I forgot about BASH_ENV.
export BASH_ENV=.bashrc
bash myscript.sh
I do not know how you would go about adding BASH_ENV to your environment in Git bash.

ubuntu bash scripting: configure file missing?

in "Bash Guide for Beginners", it's said:
Bash is the GNU shell, compatible with the Bourne shell and incorporating many useful features from other shells. When the shell is started, it reads its configuration files. The most important are:
/etc/profile
~/.bash_profile
~/.bashrc
however, in my ubuntu 11.10,
- there's no "~/.bash_profile": file explorer does not show it, and "ls -l ~/.bash_profile" says "No Such file or directory"
- there are "/etc/profile" and "~/.bashrc", but they don't show up in file explorer, only "ls -l /etc/profile" and "ls -l /.bashrc" shows the result.
is there something missing during my installation?
No, it's fine if those files aren't there, they'll just be ignored. To get a complete list of what's loaded and in what order, run man bash and check the section on INVOCATION (use "/" and type in INVOCATION to search)
Edit: saving #athos a man bash call ;)
When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file
/etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes com‐
mands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.
When a login shell exits, bash reads and executes commands from the file ~/.bash_logout, if it exists.
When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This
may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of /etc/bash.bashrc and
~/.bashrc.
Here I discuss, how to set JAVA_HOME variable and the PATH variable to your Java installation.
First using the terminal open the .bashrc which is at your home.
gedit ~/.bashrc
Now add the following to the end of the file.
JAVA_HOME=/usr/lib/jvm/java
export JAVA_HOME
PATH=$PATH:$JAVA_HOME/bin
export PATH
NOTE: If /usr/lib/jvm/java does not match the actual JAVA_HOME path in your environment, then set the actual JAVA_HOME, where you have installed Java in your machine.
Now run,
source ~/.bashrc
Then, try running the following commands and check whether your getting the appropriate responses:
echo $JAVA_HOME
/usr/lib/jvm/java
echo $PATH
:/usr/lib/jvm/java/bin
If it not work try after restarting
It also reads /etc/bashrc, which is probably present on your system.
I'm pretty sure that you also have ~/.profile (that one it reads as well) or ~/.bashrc.
If those files are missing, feel free to create them and fill with whatever you need.

Resources