Скрипт Bash: только выводите строку в ~ / .bash_profile только один раз, если строка еще не существует - PullRequest
3 голосов
/ 18 декабря 2010

Я написал скрипт gash-install для bash . К концу я делаю:

echo "Edit ~/.bash_profile to load ~/.git-completioin.bash on Terminal launch"
echo "source ~/.git-completion.bash" >> ~/.bash_profile

Проблема в том, что если вы запускаете скрипт более одного раза, вы в конечном итоге добавляете эту строку несколько раз в ~ / .bash_profile. Как использовать bash-скриптинг с grep или sed (или другим вариантом, который вы можете порекомендовать), чтобы добавить строку, только если она еще не существует в файле. Кроме того, я хочу добавить строку в ~/.profile, если этот файл существует, а ~/.bash_profile не существует, в противном случае просто добавьте его в ~/.bash_profile.

Ответы [ 4 ]

11 голосов
/ 19 декабря 2010

Что-то вроде этого должно сделать это:

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

Пара заметок:

  • Я использовал команду . вместо source, поскольку source - это bashism, но .profile может использоваться не-bash-оболочками. Команда source ... является ошибкой в ​​.profile
  • Я использовал printf вместо echo, потому что он более переносим и не испортит символы с обратной косой чертой, как в echo bash.
  • Постарайтесь быть немного более устойчивым к неочевидным сбоям. В этом случае убедитесь, что .profile существует и доступен для записи , прежде чем пытаться писать в него.
  • Я использую grep -Fx для поиска строки. -F означает фиксированные строки, поэтому нет необходимости экранировать специальные символы в строке поиска, а -x означает, что соответствует только всей строке. -qs - это общий синтаксис grep для проверки наличия строки, а не для ее отображения.
  • Это доказательство концепции. Я на самом деле не запускал это. Плохо, но сейчас воскресное утро, и я хочу пойти поиграть.
6 голосов
/ 18 декабря 2010
if [[ ! -s "$HOME/.bash_profile" && -s "$HOME/.profile" ]] ; then
  profile_file="$HOME/.profile"
else
  profile_file="$HOME/.bash_profile"
fi

if ! 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
2 голосов
/ 18 декабря 2010

Как насчет:

grep -q '^source ~/\.git-completion\.bash$' ~/.bash_profile || echo "source ~/.git-completion.bash" >> ~/.bash_profile

или в более явной (и читаемой) форме:

if ! grep -q '^source ~/\.git-completion\.bash$' ~/.bash_profile; then
    echo "Updating" ~/.bash_profile

    echo "source ~/.git-completion.bash" >> ~/.bash_profile
fi

РЕДАКТИРОВАТЬ:

Возможно, вам следует добавить дополнительную новую строкуперед вашей строкой, на всякий случай ~/.bash_profile не заканчивается на один:

if ! grep -q '^source ~/\.git-completion\.bash$' ~/.bash_profile; then
    echo "Updating" ~/.bash_profile

    echo >> ~/.bash_profile   
    echo "source ~/.git-completion.bash" >> ~/.bash_profile
fi

РЕДАКТИРОВАТЬ 2:

Это немного проще изменить и немного более переносимо:

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_profile
fi

Опции -F и -x определены POSIX и были предложены в нескольких других ответах и ​​комментариях.

1 голос
/ 18 декабря 2010
# Decide which profile to add to
PROFILE=~/.bash_profile
if ! [ -e "$PROFILE" ] && [ -e ~/.profile ]; then
    PROFILE=~/.profile
fi

# Add to profile if it doesn't appear to be there already. Err on the side of
# not adding it, in case user has made edits to their profile.
if ! grep -s 'git-completion\.bash' "$PROFILE"; then
    echo "Editing $PROFILE to load ~/.git-completion.bash on Terminal launch"
    echo "source ~/.git-completion.bash" >> "$PROFILE"
fi
...