Une Configuration Bash
Table des matières
Shell interactif
Si le shell n'est pas interactif, on ne configure rien. Tester la présence du prompt est l'une des deux méthodes officielles pour savoir ça.
if [ -z "${PS1}" ] then return fi
Prompts
On utilise tput
pour obtenir quelques séquences de contrôle du terminal, pour gérer le gras et le souligné.
u_on=$(tput smul) u_off=$(tput rmul) bold=$(tput bold) normal=$(tput sgr0)
Étrangement, il n'existe pas de tput rmbold
, et pour sortir de l'affichage en gras, il faut faire une remise à zéro de tous les styles avec tput sgr0
. La page de manuel de tput
indique tput smso
et tput rmso
pour contrôler l'affichage en gras, mais il semblerait que cela agisse plutôt sur l'affichage en vidéo inversée.
Il existe des raccourcis pour les éléments usuels à mettre dans son prompt, comme \u
pour l'utilisateur, \h
pour le nom de la machine (jusqu'au premier point), ou \w
pour le répertoire courrant (avec ${HOME}
abrégé en ~
). Mais on peut être plus créatif et ajouter d'autres informations, comme le namespace réseau dans lequel s'exécute le shell, ou des informations sur le status Git quand on est dans un dépôt (avec git-prompt.sh).
ns=$(ip netns identify) ns=${ns:+⬗${u_on}${ns}${u_off}} gp() { #Empty Git prompt return } if [ -e ${HOME}/.git-prompt.sh ] then export GIT_PS1_SHOWDIRTYSTATE=1 . ${HOME}/.git-prompt.sh gp() { ps=$(__git_ps1 '%s') if [ -n "${ps}" ] then echo "⬗${u_on}${ps}${u_off}" fi } fi
On peut configurer un prompt classique et efficace, sur deux lignes, vu il y a longtemps dans Unix Power Tools (augmenté du namespace et de Git). Sauf si Bash est lancé dans Emacs ! Car dans ce cas, un prompt plus simple fonctionne mieux.
if [ "${EMACS}" != "t" ] then export PS1='\n${bold}\u${normal}@${u_on}\h${u_off}${ns}$(gp): \w\n> ' else export PS1='\n\u@\h:\w > ' fi
Ce qui, dans un terminal Xfce, donne selon le contexte, un prompt court
Ou un prompt un peu plus long, avec namespace réseau et informations Git
Environnement général
Une valeur raisonnable pour avoir de la couleur dans le terminal
export TERM="xterm-256color"
Quand on développe, on veut des core !
ulimit -c unlimited
Retire les permissions pour group et other. Les répertoires sont créés en 755 et les fichiers en 644.
umask 022
La touche TAB complète en ignorant la casse
bind "set completion-ignore-case on"
Affiche les différentes propositions pour compléter, plutôt qu'une alerte
bind "set show-all-if-ambiguous on"
Met à jour les variables LINES
et COLUMNS
après chaque commande
shopt -s checkwinsize
Si Bash n'est pas lancé depuis Emacs, on invite ce dernier dans le shell
- Comportement d'Emacs pour readline (en principe par défaut)
- L'éditeur par défaut est Emacs en mode texte
if [ "${EMACS}" != "t" ] then set -o emacs export EDITOR="emacs -nw" fi
Si besoin d'un proxy HTTP
export http_proxy="proxy.blablabla.fr:80"
Lorsqu'il démarre, le shell tronque son fichier d'historique pour ne garder que les 2000 dernières commandes
HISTFILESIZE=2000
Lorsqu'il termine, le shell ajoute ses 1000 dernières commandes au fichier d'historique (ce dernier n'est pas écrasé).
HISTSIZE=1000 shopt -s histappend
Ajouts au PATH
Sauvegarde et restaure le PATH
système afin de pouvoir charger ce fichier plusieurs fois sans que les modifications apportées ne soient cumulatives. (Elles sont cumulatives quand même en cas de nouveau shell car SYS_PATH n'est pas exporté.)
if [ -z "${SYS_PATH}" ] then SYS_PATH="${PATH}" else PATH="${SYS_PATH}" fi
Prend tous les répertoires ~/local/*/bin
. Utilise une substitution de processus pour ne pas lancer un sous shell et perdre les modifications faites à PATH
(ce qui serait le cas avec un simple pipe).
if [ -d ${HOME}/local ] then while read -d '' bin do PATH="${bin}:${PATH}" done < <(find -L ${HOME}/local \ -mindepth 2 -maxdepth 2 -type d -iname bin -print0) fi
Le reste est sans subtilité. On ajoute quelques répertoires usuels, s'ils sont présents.
if [ -d ${HOME}/local/bin ] then export PATH="${HOME}/local/bin:${PATH}" fi if [ -d ${HOME}/bin ] then export PATH="${HOME}/bin:${PATH}" fi
On construit également un CDPATH
succinct (car pratique mais vite piégeux !)
export CDPATH="${HOME}" if [ -d ${HOME}/Bitbucket ] then export CDPATH=${HOME}/Bitbucket:${CDPATH} fi
Alias et fonctions
Pour mémoire, un espace à la fin d'un alias permet au terme suivant sur la ligne de commande de bénéficier du remplacement des alias. Cependant, les alias sont remplacés immédiatement, avant la lecture de leurs arguments. Il faut donc utiliser une fonction pour que les variables comme ${@}
soient évaluées correctement.
alias grep="grep --color=auto " alias h="history 100 " alias lf="ls -FA " alias ll="ls -lA "
On utilise emacsclient
depuis le terminal pour éditer les fichiers directement dans Emacs en mode graphique
if which emacsclient > /dev/null then alias ec="emacsclient --alternate-editor=emacs -n " fi
view
lance Emacs en mode texte, et ouvre en lecture seule les fichiers passés en argument
view() { emacs -nw --eval "(find-file-read-only \"${@}\")"; }
ediff
réalise dans Emacs (en mode graphique) une comparaison des deux fichiers passés en argument
ediff() { ec --eval "(ediff-files \"${1}\" \"${2}\")"; }
work
lance un terminal Xfce et Emacs cote à cote, en plein écran
work() { xfce4-terminal --geometry=134x64+0-10 \ --default-working-directory="${HOME}/Bureau" \ --title=Bureau \ --tab --working-directory="${HOME}/Bitbucket" \ --title=Bitbucket \ > /dev/null 2>&1 & disown # Pourquoi ce changement 116x66-6+0 -> 103x56 ? emacs --geometry=103x56 > /dev/null 2>&1 & disown }
old
, org
, bu
sont trois alias qui copient ou renomment rapidement une liste de fichiers. Par exemple
org /etc/fstab
Copie l'original du fichier /etc/fstab
vers /etc/fstab.org
. L'alias bu
fonctionne de même (avec l'extension bu
) et correspond au comportement par défaut de la fonction cpmv
appelée en sous-main. En revanche
old ~/.emacs ~/.bashrc
Renomme les deux fichiers de configuration vers old.emacs
et old.bashrc
. Avec ces trois alias, les fichiers cachés commençant par .
deviennent apparents.
cpmv() { for f in "${@}" ; do g=$(echo ${f} | sed -r "{ s:/$::g s:(^[^.]*)(\.?)(.*):\1.${CPMV_EXT:-bu}\2\3:g s:^\.?::g }") cmd="${CPMV_CMD:-cp -R} '${f}' '${g}'" echo ${cmd} eval ${cmd} done } alias org="CPMV_EXT=org CPMV_CMD='cp -R' cpmv " alias old="CPMV_EXT=old CPMV_CMD=mv cpmv " alias bu="cpmv "