Bash script: only echo line to ~/.bash_profile once if the line doesn't yet exist
Something like this should do it:
LINE_TO_ADD=". ~/.git-completion.bash"check_if_line_exists(){ # grep wont care if one or both files dont exist. grep -qsFx "$LINE_TO_ADD" ~/.profile ~/.bash_profile}add_line_to_profile(){ profile=~/.profile [ -w "$profile" ] || profile=~/.bash_profile printf "%s\n" "$LINE_TO_ADD" >> "$profile"}check_if_line_exists || add_line_to_profile
A couple of notes:
- I've used the
.
command instead ofsource
assource
is a bashism, but.profile
may be used by non-bash shells. The commandsource ...
is an error in.profile
- I've used
printf
instead ofecho
because it's more portable and wont screw up backslash-escaped characters as bash'secho
would. - Try to be a little more robust to non-obvious failures. In this case make sure .profile exists and is writable before trying to write to it.
- I use
grep -Fx
to search for the string.-F
means fixed strings, so no special characters in the search string needs to be escaped, and-x
means match the whole line only. The-qs
is common grep syntax for just checking the existence of a string and not to show it. - This is proof of concept. I didn't actually run this. My bad, but it's Sunday morning and I want to go out and play.
if [[ ! -s "$HOME/.bash_profile" && -s "$HOME/.profile" ]] ; then profile_file="$HOME/.profile"else profile_file="$HOME/.bash_profile"fiif ! grep -q 'git-completion.bash' "${profile_file}" ; then echo "Editing ${profile_file} to load ~/.git-completioin.bash on Terminal launch" echo "source \"$HOME/.git-completion.bash\"" >> "${profile_file}"fi
How about:
grep -q '^source ~/\.git-completion\.bash$' ~/.bash_profile || echo "source ~/.git-completion.bash" >> ~/.bash_profile
or in a more explicit (and readable) form:
if ! grep -q '^source ~/\.git-completion\.bash$' ~/.bash_profile; then echo "Updating" ~/.bash_profile echo "source ~/.git-completion.bash" >> ~/.bash_profilefi
EDIT:
You should probably add an additional newline before your one-liner, just in case ~/.bash_profile
does not end in one:
if ! grep -q '^source ~/\.git-completion\.bash$' ~/.bash_profile; then echo "Updating" ~/.bash_profile echo >> ~/.bash_profile echo "source ~/.git-completion.bash" >> ~/.bash_profilefi
EDIT 2:
This is a bit easier to modify and slightly more portable:
LINE='source ~/.git-completion.bash'if ! grep -Fx "$LINE" ~/.bash_profile >/dev/null 2>/dev/null; then echo "Updating" ~/.bash_profile echo >> ~/.bash_profile echo "$LINE" >> ~/.bash_profilefi
The -F
and -x
options are specified by POSIX and were suggested in several other answers and comments.