.:Bordel-de-Nerd:.

Configurer son terminal Bash

closeCet article a été publié il y a 2 ans 10 mois 4 jours, il est donc possible qu’il ne soit plus à jour. Les informations proposées sont donc peut-être expirées.

Bash  (Bourne-Again shell) est le shell par défaut sous Linux, pour en profiter pleinement il est indispensable de le configurer.
Les fichiers de configuration de Bash sont les suivants :

Scripts exécutés lors de la connexion :

Commun à tous les utilisateurs

  • /etc/profile

Spécifiques à chaque utilisateur

  • .bash_profile
  • .bash_login
  • .profile

Script exécuté lors de la déconnexion :

  • .bash_logout

Pour plus de simplicité nous allons utiliser le fichier ~/.bashrc qui est utilisé pour chaque utilisateur  par les shells interactifs autres que les shells de connexion.

Pour gagner en productivité Bash offre la complétion automatique.

Pour en profiter il est nécessaire d’évaluer des fonctions préétablies dans le fichier /etc/bash_completion.

if [ -f /etc/bash_completion ]; then
	    . /etc/bash_completion
fi

On ajoute aussi la complétion pour les noms d’hôte ssh

if [ -f ~/.ssh/known_hosts ]; then
  SSH_COMPLETE=( $(cat ~/.ssh/known_hosts | \
  cut -f 1 -d ' ' | \
  sed -e s/,.*//g | \
  uniq | \
  egrep -v [0123456789]) )
  complete -o default -W "${SSH_COMPLETE[*]}" ssh
fi

Et enfin pour que la complétion fonctionne aussi avec sudo on ajoute

complete -cf sudo

Notre shell est maintenant capable de compléter nos commandes à l’aide de la touche [TAB] mais aussi de parcourir l’historique des commandes déjà saisies à l’aide du raccourci [Ctrl]-r.

Pour une meilleure ergonomie et afin d’améliorer encore votre productivité, je ne peux que vous inciter à installer kingbash (cf article sur cet outil)

pour l’installer

wget http://www.projet-libre.org/files/KingBash-last && chmod +x KingBash-last && sudo mv KingBash-last /usr/bin/kingbash

Puis ajoutez à votre ~/.bashrc les fonctions ci-dessous afin de remplacer les raccourcis [Tab] et [Ctrl]-r pour qu’ils utilisent kingbash

# Auto Completion dans le style Ncurse avec la touche [TAB] 
function kingbash.fn() {
  echo -n "KingBash> $READLINE_LINE"
  OUTPUT=`/usr/bin/kingbash "$(compgen -ab -A function)"`
  READLINE_POINT=`echo "$OUTPUT" | tail -n 1`
  READLINE_LINE=`echo "$OUTPUT" | head -n -1`
  echo -ne "\r\e[2K"; }
bind -x '"\t":kingbash.fn'
 
# Historique pour KingBash avec la touche [Ctrl]+r
function kingbash.hs() {
  echo -n "KingBash> $READLINE_LINE"
  history -a
  OUTPUT=`/usr/bin/kingbash -r <(tac ~/.bash_history)`                                                                                                        
  READLINE_POINT=`echo "$OUTPUT" | tail -n 1`                                                                                                                 
  READLINE_LINE=`echo "$OUTPUT" | head -n -1`                                                                                                                 
  echo -ne "\r\e[2K"; }                                                                                                                                       
bind -x '"\x12":kingbash.hs'

On en profite pour configurer la façon dont bash gère notre historique

export HISTSIZE=10000 # taille de l'historique 
export HISTFILESIZE=${HISTSIZE}
export HISTIGNORE="ls:cd:[bf]g:exit" # ignorer les lignes w/ ls, cd, ...
export HISTCONTROL="ignoreboth" # ignorer les doublons et les commandes qui commencent par un espace

Maintenant que notre shell est capable d’utiliser la complétion automatique nous allons le configurer un peu plus en profondeur à l’aide de la commande shopt qui depuis la version 2.0 de bash permet d’en modifier le comportement.

shopt -s cdspell # Pour que bash corrige automatiquement les fautes de frappes ex: cd ~/fiml sera remplacé par cd ~/film
shopt -s checkwinsize # Pour que bash vérifie la taille de la fenêtre après chaque commande
shopt -s cmdhist # Pour que bash sauve dans l'historique les commandes qui prennent plusieurs lignes sur une seule ligne.
shopt -s dotglob # Pour que bash montre les fichiers qui commencent par un .
shopt -s expand_aliases # # Pour que bash montre la commande complete au lieu de l'alias
shopt -s extglob # Pour que bash, interprète les expressions génériques
shopt -s histappend # Pour que bash ajoute au lieu d'écraser dans l'histo
shopt -s hostcomplete # Pour que bash tente de résoudre le nom pour les ip suivis d'un @
shopt -s nocaseglob # Pour que bash ne soit pas sensible a la casse

A ce stade notre shell commence à devenir un peu plus convivial.
Afin de le rendre encore plus attractif nous allons définir des variables pour les couleurs et redéfinir la variable $PS1 qui correspond au prompt à utiliser (cf article sur les prompt)

D’abord les couleurs

txtrst='\e[0m'    # Text Reset
txtbluj="\[\e[01;34m\]" # Bleu prompt
txtarobasc="\[\e[05;33m\]" # Orange clignote prompt
txtarobas="\[\e[02;33m\]" # Orange prompt
txtvertj="\[\e[01;32m\]" # Vert fluo prompt
txtjaunj="\[\e[01;33m\]" # Jaune prompt
txtbleucj="\[\033[1;36m\]" # Bleu clair prompt
txtheure="\[\e[02;36m\]" # turquoise, heure prompt
txtgrisj="\[\e[30;1m\]" # gris prompt

La version du prompt que je propose ici vérifie d’abord la longueur du répertoire courant et si elle dépasse 1/3 de la longueur du terminal on raccourci le nom du répertoire (fonction truncate_pwd) ensuite on regarde si vous utilisez un screen et si c’est le cas on défini un prompt spécifique qui affiche le numéro du screen utilisé.
Enfin on vérifie si l’utilisateur est root et si c’est le cas on met en place un prompt spécifique avec le @ qui clignote.

voici le code complet pour ce prompt à ajouter à notre ./bashrc

# Prompt perso, modification de la variable $PS1
# USER@MACHINE:DOSSIER (nb fichiers Taille Mb) [HH:mm:ss] #N°Commande
# (nb jobs)-(screen num) :-) 
function truncate_pwd # Fonction pour remplacer PWD par {...} si > 1/3 de l'écran
{
  newPWD="${PWD/#$HOME/~}"
  local pwdmaxlen=$((${COLUMNS:-20}/3))
  if [ ${#newPWD} -gt $pwdmaxlen ]
  then
     newPWD=" {...} ${newPWD: -$pwdmaxlen}"
  fi  
  nbFiles=$(ls -1 | wc -l | sed 's: ::g')
  sizeFiles=$(ls -lah | grep -m 1 total | sed 's/total //')
}
 
PROMPT_COMMAND=truncate_pwd # Executé avant chaque commande
 
ROOT_UID=0
# Vérifier si on est dans un screen
if [ -n "${STY#*.}" ]; then
    export PS1="\n${txtbluj}\u${txtrst}${txtarobasc}@${txtrst}${txtvertj}\h${txtrst}:${txtjaunj} \${newPWD} ${txtrst}(${txtbleucj}\${nbFiles} fichiers ${txtjaunj}\${sizeFiles}b${txtrst}) ${txtrst}${txtbleucj}[\t]${txtgrisj} #\#\n${txtgrisj}(jobs:${txtbluj}\j${txtgrisj}) - (screen:${txtbluj}$WINDOW${txtgrisj})\`if [ i\$? -eq 0 ]; then echo '${txtvertj} :-)'; else echo '${bldred} :-(' ; fi\`${txtrst}\n$"
else
  if [ "$UID" -eq "$ROOT_UID" ]  # Si root le @ clignote,
  then
	  export PS1="\n${txtbluj}\u${txtrst}${txtarobasc}@${txtrst}${txtvertj}\h${txtrst}:${txtjaunj} \${newPWD} ${txtrst}(${txtbleucj}\${nbFiles} fichiers ${txtjaunj}\${sizeFiles}b${txtrst}) ${txtrst}${txtbleucj}[\t]${txtgrisj} #\#\n${txtgrisj}(jobs:${txtbluj}\j${txtgrisj})\`if [ \$? = "0" ]; then echo '${txtvertj} :-)'; else echo '${bldred} :-(' ; fi\`${txtrst}\n$"
  else
	  export PS1="\n${txtbluj}\u${txtrst}${txtarobas}@${txtrst}${txtvertj}\h${txtrst}:${txtjaunj} \${newPWD} ${txtrst}(${txtbleucj}\${nbFiles} fichiers ${txtjaunj}\${sizeFiles}b${txtrst}) ${txtrst}${txtbleucj}[\t]${txtgrisj} #\#\n${txtgrisj}(jobs:${txtbluj}\j${txtgrisj})\`if [ \$? = "0" ]; then echo '${txtvertj} :-)'; else echo '${bldred} :-(' ; fi\`${txtrst}\n$"
  fi
fi

On peut aussi redéfinir la variable $PS2 pour remplacer le symbole > pour les commandes sur plusieurs lignes

export PS2="continue-> " # Pour les longues commandes remplace >

Et enfin voici un aperçu de ce « magnifique » prompt

prompt

Maintenant que nous avons un prompt en couleur il serait intéressant donner aussi de la couleur aux commandes de base.
Pour ce faire nous allons installer deux outils, le premier grc http://kassiopeia.juls.savba.sk/~garabik/software/grc.html s’installe grace à votre gestionnaire de paquets

Debian/Ubuntu

sudo apt-get install grc

Arch

yaourt -S grc

Pour coloriser la sortie de la commande MaCommande on utilise la syntaxe

grc --color=auto MaCommande

Pour ne pas avoir à faire précéder chaque commande à coloriser par grc nous allons ajouter des alias dans notre fichier ~/.bashrc

if which grc &>/dev/null; then
    alias .cl='grc -es --colour=auto'
    alias configure='.cl ./configure'
    alias diff='.cl diff'
    alias make='.cl make'
    alias gcc='.cl gcc'
    alias g++='.cl g++'
    alias ld='.cl ld'
    alias netstat='.cl netstat'
    alias ping='.cl ping -c 10'
    alias traceroute='.cl traceroute'
fi

C’est tout pour grc, on passe maintenant à l’installation du deuxième outil, j’ai nommé cope : https://github.com/trapd00r/cope.
Pour cope ça ne va pas être aussi simple que pour grc car sauf si vous êtes sous arch (yaourt -S cope-git) vous allez devoir compiler le logiciel manuellement.

Voici les commandes nécessaires à la compilation de cope

git clone https://github.com/trapd00r/cope.git
cd cope
perl Makefile.PL
make
sudo make install

Une fois installé saisissez la commande suivante

perl cope_path.pl

Cette commande nous donne un repertoire qu’il faudra ajouter à notre variable $PATH

exemple sous Arch (attention le chemin est différent sous Ubuntu)

export PATH=/usr/share/perl5/vendor_perl/auto/share/dist/Cope:$PATH

A ce stade notre configuration de bash est terminée mais il existe (comme vous avez pu le voir pour grc) deux commandes très utiles pour personnaliser bash, il s’agit des alias et des fonctions.

Au lieu de taper ls -l nous allons définir un alias

alias ls="ls -l"

Ainsi il suffira de saisir la commande ls pour réaliser un ls -l.

Voici une liste des alias que j’utilise avec un commentaire pour les expliquer

alias ls='ls --group-directories-first --time-style=+"%d.%m.%Y %H:%M" --color=auto -F' # ls par default (dossier en 1er + mise en forme de l'heure)
alias lsfp='ls | sed s#^#$(pwd)/#' # ls avec full PATH
alias ll='ls -l --group-directories-first --time-style=+"%d.%m.%Y %H:%M" --color=auto -F' # ls détaille
alias la='ls -la --group-directories-first --time-style=+"%d.%m.%Y %H:%M" --color=auto -F' # ls aussi les fichiers cachés .*
alias lsofnames="lsof | awk '!/^\$/ && /\// { print \$9 }' | sort -u" # noms des fichiers ouverts
alias grep='grep --color=tty -d skip'
alias cp="cp -i"  # Confirmer avant d'écraser un fichier existant
alias df='df -h'  # Tailles lisibles par l'homme
alias free='free -m'  # voir la taille en MB
alias vp='vim PKGBUILD' # spécifique Arch
alias vs='vim SPLITBUILD' # spécifique Arch
alias ports="lsof -i -n -P" # Voir les process qui utilisent une connection internet
alias estab="ss -p | grep STA" # Voir seulement les sockets établis 
alias netstat80="netstat -plan|grep :80|awk {'print $5'}|cut -d: -f 1|sort|uniq -c|sort -nk 1" # nombre de connections sur le port 80 du serveur par IP    
alias openports="netstat -nape --inet" # Voir les ports ouverts
alias netpid="netstat -tlnp" # Voir le port qui écoute avec le PID du process associé
alias appson="netstat -lantp | grep -i stab | awk -F/ '{print $2}' | sort | uniq" # Voir une liste des noms de process qui utilisent une connection
alias rscp='rsync -aP --no-whole-file --inplace' # rsync cp // a(garder permissions) P(progress bar)
alias rsmv='rscp --remove-source-files' # rsync mv avec progressbar
alias calc='python -ic "from math import *; from random import *"' # Une calculatrice en python
alias servethis="python -m SimpleHTTPServer 8000" # Serveur python sur le port 8000
if type -P htop >/dev/null; then
  alias top='htop' # toujours utiliser htop si installé
fi
alias reload_bash="source ~/.bashrc" # recharger le ~/.bashrc
alias ncmpc='ncmpc -c' # Ncurse mpc en couleur
alias psp='ps u -C' # ps sur un seul process
if type -P vim >/dev/null; then
  alias vi=vim # toujours utiliser vim au lieu de vi si installe
fi
bind '"\C-l"':"\"clear\r\"" # Ctrl+l vide le terminal

Sous ubuntu il doit manquer certain logiciels pour ces alias

sudo apt-get install vim htop ncmpc

Après les alias nous allons définir des fonctions pour les opération complexe

la fonction myip retourne l’IP externe.

# myip - Obtenir IP publique
# usage: myip
myip(){ wget -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//';}

Ces 3 fonctions permettent de créer des archives facilement.

# Créer une archive pour un repertoire donne.
mktar() { tar cvf  "${1%%/}.tar"     "${1%%/}/"; }
mktgz() { tar cvzf "${1%%/}.tar.gz"  "${1%%/}/"; }
mktbz() { tar cvjf "${1%%/}.tar.bz2" "${1%%/}/"; }

La fonction ex permet d’extraire facilement tout type d’archive.

# ex - Extraire une archive
# usage: ex <fichier>
ex ()
{
  if [ -f $1 ] ; then
    case $1 in
      *.tar.bz2)   tar xjvf $1   ;;
      *.tar.gz)    tar xzvf $1   ;;
      *.bz2)       bunzip2 $1   ;;
      *.rar)       unrar x $1     ;;
      *.gz)        gunzip $1    ;;
      *.tar)       tar xvf $1    ;;
      *.tbz2)      tar xjvf $1   ;;
      *.tgz)       tar xzvf $1   ;;
      *.zip)       unzip $1     ;;
      *.Z)         uncompress $1;;
      *.7z)        7z x $1      ;;
      *)           echo -e "${bldred}'$1' ne peut pas etre decompresse avec ex()" ;;
    esac
  else
    echo -e "\n${bldred}'$1' n'est pas un fichier valide"
  fi
}

La fonction clock affiche une horloge simple

# clock - Affiche une horloge simple
# usage: clock
clock() { while true;do clear;echo -e "\e[30;1m===========\e[0m\e[01;33m";date +"%r";echo -e "\e[0m\e[30;1m===========\e[0m";sleep 1;done; }

Les fonctions define et definef retournent la définition d’un mot via google en français ou anglais.

# definef - Definition francaise d'un mot a l'aide de google
# usage: definef <mot>
definef(){ local y="$@";curl -sA"Opera" "http://www.google.fr/search?q=define:${y// /+}"|grep -Po '(?<=<li>)[^<]+'|nl|perl -MHTML::Entities -pe 'decode_entities($_)' 2>/dev/null;}
 
# define - Definition Anglaise d'un mot a l'aide de google
# usage: definef <word>
define(){ local y="$@";curl -sA"Opera" "http://www.google.com/search?q=define:${y// /+}"|grep -Po '(?<=<li>)[^<]+'|nl|perl -MHTML::Entities -pe 'decode_entities($_)' 2>/dev/null;}

la fonction resetperm permet de rétablir les permissions par défaut.

# resetperm - restaurer les permissions des repertoires et fichiers avec leurs valeurs "normales" (644/755)
# usage: resetperm <dossier>
resetperm()
{
  chmod -R u=rwX,go=rX "$@"
  chown -R ${USER}:users "$@"
}

Cette fonction converti l’affichage des permissions en octal (ex : 777).

# XXX - mise en forme des permissions symbolic en octal (644)
# usage : ls -l | XXX
XXX() { sed -e 's/--x/1/g' -e 's/-w-/2/g' -e 's/-wx/3/g' -e 's/r--/4/g'  -e 's/r-x/5/g' -e 's/rw-/6/g' -e 's/rwx/7/g' -e 's/---/0/g' ; }

La fonction changeEncoding regarde l’encodage d’un fichier, s’il est codé en UTF-8 on le converti en ISO-8859-1 et vice-versa (exemple : fichier .srt de sous-titres)

# Convertir l'encodage d'un fichier iso2utf8/utf82iso
# usage : changeEncoding <fichier>
changeEncoding()
{
  if [ -f "$1" ] ; then
    case "`file -bi "$1"`" in
      *iso-8859-1)   iconv --from-code=ISO-8859-1 --to-code=UTF-8 "$1" > "$1".utf-8 && echo -e "\n${bldgrn}Nouveau fichier : "$1".utf-8"  ;;
      *utf-8)   iconv --from-code=UTF-8 --to-code=ISO-8859-1 "$1" > "$1".iso-8859-1 && echo -e "\n${bldgrn}Nouveau fichier : "$1".iso-8859-1" ;;
      *us-ascii)   echo -e "\n${bldylw}Encodage US-ASCII pas besoin de convertir"   ;;
      *)           echo -e "\n${bldred}L'encodage de '$1' ne peut pas etre converti avec changeEncoding(`file -bi "$1"`)" ;;
    esac
  else
    echo -e "\n${bldred}'$1' n'est pas un fichier valide"
  fi
}

La fonction dtc affiche une quote au hasard depuis danstonchat.org.

# Afficher une quote depuis danstonchat.com
# usage: dtc
dtc()
{ 
  url=http://danstonchat.com/random.html?toto=`date +%N` 
  lynx --dump --display_charset=utf8 $url 2>&1 \
    | awk '$1~"#" && $0!~"RSS" { getline; while ($1!~"#") { print $0; getline;}; exit}'
}

La fonction wdl permet de télécharger un site pour une consultation offline.

# télecharger un site complet avec Wget
# Les pages seront mise en html (E), les liens seront transformés (k) et c'est récursif (r) sur 5 niveaux maxi (l5)
# Usage wdl <URL>
# tip : utiliser servethis pour servir les pages télechargées
wdl(){ wget -r -l5 -k -E ${1} && cd $_;}

Cette fonction permet de prendre une capture d’écran (sudo apt-get install scrot).

# Prendre une capture d'écran
# Usage: screenshot [delai en sc] [qualite]
screenshot() {
    if ! which scrot &>/dev/null; then
        echo "${FUNCNAME[0]}(): Vous devez d'abord installer 'scrot'."
        return 1
    fi
 
    local delay=1
    local quality=95
 
    [ "$1" ] && delay="$1"
    [ "$2" ] && quality="$2"
 
    scrot -q $quality -d $delay "$HOME/screenshot_`date +'%F_%Hh%M'`.jpg"
}

Cette fonction transforme une image (depuis une URL) en ascci html (sudo apt-get install jp2a).

# Transforme une image (depuis une URL) en ascci html
# servethis pour voir sur le port 8000 ou mongoose http://code.google.com/p/mongoose/
# usage : toascii <URL>
toascii() { convert $1 jpg:- | jp2a - --color --fill --background=light --html > $HOME/ascii_`date +'%F_%Hh%M'`.html;}

Cette fonction construit une galerie html avec tout les fichiers contenu dans un répertoire.

# Construire une galerie html avec toutes les photo d'un dossier
# usage : galerie
galerie() 
{
  echo -e "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1- \
transitional.dtd\">\n<HTML>\n<head>\n<title>Galerie photo du `date +'%F_%Hh%M'`</title>\n\n<style type=\"text/css\">\nhtml \
, body {\n\tmargin: 0px;\n\tpadding: 0px;\n\tborder: 0px;\n}\n#main {\n\tmargin: 5px 20px;\n}\ndiv.left {\n\tfloat: left;\n\tmargin \
-right: 300px;\n\twidth: 400px;\n\tmargin-bottom: 10px;\n}\ndiv.left p {\n\ttext-align: center;\n}\nimg {\n\tborder: 0px none;\n}\ndiv. \
center {\n\twidth: 600px;\n}\n.clear {\n  clear : both;\n}\n</style>\n</head>\n\n<body>\n<div id=\"main\">\n  <h1>Galerie photo du \
 `date +'%F_%Hh%M'`</h1>\n" > galerie_`date +'%F'`.html;
  for i in *.{jpg,jpeg,png,gif,JPG,JPEG,PNG,GIF};
   do echo -e "\t<div class="left">\n\t\t<a href="http://www.bordel-de-nerd.net/2010/08/configurer-son-terminal-bash/"><img src="http://www.bordel-de-nerd.net/2010/08/configurer-son-terminal-bash/" width="300" height="300" border="0" /></a><br />\n\t\t<p>$i</p>\n\t</div>\n";
  done >> galerie_`date +'%F'`.html
  echo -e "</div>\n</body>\n</html>" >> galerie_`date +'%F'`.html
  echo -e "\n${bldgrn}La galerie galerie_`date +'%F'`.html contient les photos du dossier `pwd`."
}

Pour changer l’extension d’un lot de fichiers.

# chext - modifier l'extension 
# usage : chext new_ext *.old_ext
function chext(){
  local fname
  local new_ext="$1"
  shift
  IFS=$'\n'
  for fname in $@
  do
    mv "$fname" "${fname%.*}.$new_ext"
  done
}

Cette fonction liste un répertoire et affiche un résumé avec le nombre de fichiers par type.

# cbt - Count by Type - affiche le nombre de fichiers par type
# usage : cbt
cbt() { find ${*-.} -type f -print0 | xargs -0 file | awk -F, '{print $1}' | awk '{$1=NULL;print $0}' | sort | uniq -c | sort -nr ;}

Pour renommer en majuscule ou minuscule des fichiers.

# Renomme en minuscules
# usage tolowercase <*.txt>
toLowercase() { for i in "$@"; do mv -f "$i" "`echo $i| tr [A-Z] [a-z]`" &>/dev/null; done }
 
# Renomme en majuscules
# usage toupercase <*.txt>
toUpercase() { for i in "$@"; do mv -f "$i" "`echo $i| tr [a-z] [A-Z]`" &>/dev/null; done }

Pour remplacer les espaces par des underscore dans les noms de fichiers.

# remplacer les espaces par des _
# usage underscorespace <*.txt>
underscorespace() { for i in "$@"; do mv "$i" "`echo $i| tr ' ' '_'`" &>/dev/null; done }

Pour obtenir des statistiques sur le temps de réponse d’une URL.

# tempsrep - temps de réponse pour un URL
# usage : tempsrep <URL> (TTFB:time to first bit)
tempsrep() { curl -o /dev/null -w "Connect: %{time_connect} TTFB: %{time_starttransfer} Total time: %{time_total} \n" $1; }

Savoir quelle serveur web est utilisé par un site.

# getserver - Determine le serveur utilisé par un site 
# usage : getserver <URL> 
getserver() { curl -I $1  2>&1 | grep Server;}

Pour contrôler plus facilement les services.

# start, stop, restart, reload - Controler les services
# usage: start nom_du_daemon
start() { for arg in $*; do sudo /etc/init.d/$arg start; done }
stop() { for arg in $*; do sudo /etc/init.d/$arg stop; done }
restart() { for arg in $*; do sudo /etc/init.d/$arg restart; done }
reload() { for arg in $*; do sudo /etc/init.d/$arg reload; done }

Obtenir une liste des fonctions existantes (un peu comme la commande alias).

# Affiche une liste des fonctions comme alias le fait pour les alias
fonctions()
{
  echo -e "\n${txtpur}FONCTIONS
----------------------------------------------------------------------${txtrst}"
  echo -e "${txtcyn}myip : ${txtrst}affiche l'adresse ip"
  echo -e "${txtcyn}mktar() <dossier> :${txtrst} creer une archive tar du dossier"
  echo -e "${txtcyn}mktgz() <dossier> :${txtrst} creer une archive tar.gz du dossier"
  echo -e "${txtcyn}mktbz() <dossier> :${txtrst} creer une archive tar.bz2 du dossier"
  echo -e "${txtcyn}ex <fichier> :${txtrst} extraire un fichier"
  echo -e "${txtcyn}clock :${txtrst} Affiche une horloge simple"
  echo -e "${txtcyn}definef <mot> :${txtrst} Definition francaise d'un mot a l'aide de google"
  echo -e "${txtcyn}define <word> :${txtrst} Definition anglaise d'un mot a l'aide de google"
  echo -e "${txtcyn}resetperm <dossier> :${txtrst} restaurer les permissions des repertoires et fichiers avec leurs valeurs normales (644/755)"
  echo -e "${txtcyn}ls -l | XXX :${txtrst} XXX - mise en forme des permissions symbolic en octal (644)"
  echo -e "${txtcyn}changeEncoding <fichier>:${txtrst} Convertir l'encodage d'un fichier iso2utf8/utf82iso"
  echo -e "${txtcyn}dtc :${txtrst} affiche une quote depuis danstonchat.com"
  echo -e "${txtcyn}wdl <URL> :${txtrst} telecharger un site complet avec Wget"
  echo -e "${txtcyn}toascii <URL> :${txtrst} Transforme une image (depuis une URL) en ascci html"
  echo -e "${txtcyn}screenshot [delai en sc] [qualite] :${txtrst} prendre une capture d'ecran"
  echo -e "${txtcyn}toascii <URL> :${txtrst} tranforme une image en ascii html"
  echo -e "${txtcyn}galerie :${txtrst} Construire une gallerie html avec toutes les photo d'un dossier"
  echo -e "${txtcyn}chext new_ext *.old_ext :${txtrst} modifier l'extension" 
  echo -e "${txtcyn}cbt (Count by Type) :${txtrst} affiche le nombre de fichiers par type" 
  echo -e "${txtcyn}toLowercase <*.txt> :${txtrst} renommer en minuscules" 
  echo -e "${txtcyn}toUpercase <*.txt> :${txtrst} renommer en majuscules" 
  echo -e "${txtcyn}underscorespace <*.txt>:${txtrst} remplacer les espaces par des _"
  echo -e "${txtcyn}tempsrep <URL> :${txtrst} temps de reponse pour un URL" 
  echo -e "${txtcyn}getserver <URL> :${txtrst} Determine le serveur utilise par un site"
  echo -e "${txtcyn}start() stop() restart() reload() <daemon> :${txtrst} Controler les services"
}

Obtenir une aide sur l’utilisation de bash.

function bashtips {
echo -e "
${txtpur}REPERTOIRES
----------------------------------------------------------------------${txtrst}
${txtcyn}~-          ${txtrst}repertoire precedent
${txtcyn}pushd tmp   ${txtrst}Push tmp && cd tmp
${txtcyn}popd        ${txtrst}Pop && cd
${txtcyn}save foo    ${txtrst}bookmark le dossier courant dans foo
${txtcyn}show        ${txtrst}voir une liste des bookmarks
 
${txtpur}HISTORIQUE
----------------------------------------------------------------------${txtrst}
${txtcyn}!!        ${txtrst}Derniere commande
${txtcyn}!!:p      ${txtrst}Apercu sans execution de la derniere commande
${txtcyn}!?foo     ${txtrst}Derniere commande contenant \`foo'
${txtcyn}^foo^bar^ ${txtrst}Derniere commande contenant \`foo', mais substitue avec \`bar'
${txtcyn}!!:0      ${txtrst}Derniere commande mot
${txtcyn}!!:^      ${txtrst}1er argument de la derniere commande
${txtcyn}!\$        ${txtrst}Dernier argument de la derniere commande
${txtcyn}!!:*      ${txtrst}Tout les arguments de la derniere commande
${txtcyn}!!:x-y    ${txtrst}Arguments x a y de la derniere commande
${txtcyn}[Ctrl]-s  ${txtrst}Rechercher en avant dans l'historique
${txtcyn}[Ctrl]-r  ${txtrst}Rechercher en arriere dans l'historique
 
${txtpur}EDITION DE LIGNE
----------------------------------------------------------------------${txtrst}
${txtcyn}[Ctrl]-a     ${txtrst}aller au debut de la ligne
${txtcyn}[Ctrl]-e     ${txtrst}aller a la fin de la ligne
${txtcyn}[ Alt]-d     ${txtrst}efface jusqu'a la fin d'un mot
${txtcyn}[Ctrl]-w     ${txtrst}efface jusqu'au debut d'un mot
${txtcyn}[Ctrl]-k     ${txtrst}efface jusqu'a la fin de la ligne
${txtcyn}[Ctrl]-u     ${txtrst}efface jusqu'au debut de la ligne
${txtcyn}[Ctrl]-y     ${txtrst}coller le contenu du buffer
${txtcyn}[Ctrl]-r     ${txtrst}revert all modifications to current line
${txtcyn}[Ctrl]-]     ${txtrst}chercher en avant dans la ligne
${txtcyn}[ Alt]-
  ${txtcyn}[Ctrl]-]   ${txtrst}chercher en arriere dans la ligne
${txtcyn}[Ctrl]-t     ${txtrst}switch lettre
${txtcyn}[ Alt]-t     ${txtrst}switch mot
${txtcyn}[ Alt]-u     ${txtrst}mot en Majuscule
${txtcyn}[ Alt]-l     ${txtrst}Mot en Minuscule
${txtcyn}[ Alt]-c     ${txtrst}1ere lettre du mot en Majuscule
 
${txtpur}COMPLETION
----------------------------------------------------------------------${txtrst}
${txtcyn}[ Alt].      ${txtrst}faire defiler les arguments de la derniere commande
${txtcyn}[ Alt]-/     ${txtrst}completer le nom de fichier
${txtcyn}[ Alt]-~     ${txtrst}completer le nom d'utilisateur
${txtcyn}[ Alt]-@     ${txtrst}completer le nom d'host
${txtcyn}[ Alt]-\$     ${txtrst}completer le nom de variable
${txtcyn}[ Alt]-!     ${txtrst}completer le nom d'une commande
${txtcyn}[ Alt]-^     ${txtrst}completer l'historique"
 
}

Voila pour un début, libre à vous d’ajouter de nouvelles fonctions ou de nouveaux alias à votre fichier.

Enfin pour terminier cet article et récompenser les courageux qui ont réussi à ne pas abandonner avant la fin voici une implémentation en bash du système des marque-pages.

############################################################################################################################################################
#			ALIAS POUR LES BOOKMARKS EN BASH
############################################################################################################################################################
# show pour voir la liste des bookmarks existants // save foo sauvergarde le dossier courant dans le bookmark foo // cd foo pour y revenir
############################################################################################################################################################
if [ ! -f ~/.dirs ]; then  # si ~/.dirs n'existe pas, le créer
	touch ~/.dirs
fi
 
alias show='cat -n ~/.dirs | sed "s/^\([^.]*\)\=\(.*\)/-\1 --> \2/g"'
save (){ command sed "/!$/d" ~/.dirs > ~/.dirs1; \mv ~/.dirs1 ~/.dirs; echo "$@"=\"`pwd`\" >> ~/.dirs; source ~/.dirs ;}
source ~/.dirs  # Initialisation de la fonction 'save': source le fichier .sdirs
shopt -s cdable_vars # utilisé pour la fonction bookmarks pour que bash n'ai pas besoin de $ pour sourcer le fichier .dirs

Si vous essayez cette fonction vous ne pourrez plus vous en passer.
Si par exemple vous vous déplacez dans un répertoire avec un chemin « à rallonge »

cd /mon/repertoire/avec/un/chemin/impossible/a/se/rappeller/

Pour enregister un marque page sur ce repertoire il vous suffit de faire

save dossierperso

Et enfin pour vous y rendre à nouveau et voir la liste des marque-pages créés

show
    -   1 dossierperso --> "/mon/repertoire/avec/un/chemin/impossible/a/se/rappeller/"
cd dossierperso

Pour les impatients voici le fichier .bashrc au complet et commenté

http://www.bordel-de-nerd.net/wp-content/plugins/downloads-manager/img/icons/default.gif télécharger: bashrc (243B)
ajouté: 14/08/2010
clics: 1064
description: Fichier de configuration pour bash à copier dans votre home (~/.bashrc)

Pour en profiter pleinement veuillez installer cope/grc (voir plus haut) pour les couleurs des commandes et kingbash pour faciliter la navigation.
Ainsi que les outils utilisés dans certaines fonctions.

sudo apt-get install jp2a grc vim wget htop

N’hésitez pas à laisser un commentaire si vous avez une fonction intéressante qui n’est pas listée ci-dessus et pourquoi pas non plus revenir sur les articles de ce blog qui traitent du sujet de la ligne de commande.
http://www.bordel-de-nerd.net/tag/command-line/

24 Responses to Configurer son terminal Bash

  1. Pingback: Tweets that mention Configurer son terminal Bash | .: bordel-de-nerd :. -- Topsy.com

  2. pierre

    Hi, this how-to is very nicely build.
    Thanks for your advice, I’ll take a look closer asap!
    thanks again for this great job, well done!
    Salut

  3. philippe

    Salut, désolé pour le déterrage, mais je viens de tomber sur ce fabuleux article.

    J’ai essayé la fonction truncate_pwd, très utile sur un netbook, mais elle ne marche pas. Est ce qu’il faut la mettre à un endroit précis du bashrc? Ou est ce qu’il faut faire quelque chose en plus pour qu’elle marche?

  4. Bonjour Philippe,

    Pour que ça fonctionne il faut juste écrire la fonction (peu importe l’endroit)

    function truncate_pwd
    {
      newPWD="${PWD/#$HOME/~}"
      local pwdmaxlen=$((${COLUMNS:-20}/3))
      if [ ${#newPWD} -gt $pwdmaxlen ]
      then
        newPWD=" {...} ${newPWD: -$pwdmaxlen}"
      fi
    }

    Puis ensuite l’utiliser pour redéfinir la variable d’environnement PROMPT_COMMAND de cette façon

    PROMPT_COMMAND=truncate_pwd

    Enfin pour finir et c’est ça que je n’ai pas dans l’article, dans la variable $PS1 il faut remplacer ‘w’ ( qui correspond au chemin courant) par ${newPWD}

    Ce qui nous donne le code suivant pour $PS1 (je met à jour sur l’article merci)

    # Vérifier si on est dans un screen
    if [ -n "${STY#*.}" ]; then
        export PS1="n${txtbluj}u${txtrst}${txtarobasc}@${txtrst}${txtvertj}h${txtrst}:${txtjaunj} ${newPWD} ${txtrst}(${txtbleucj}$(ls -1 | wc -l | sed 's: ::g') fichiers ${txtjaunj}$(ls -lah | grep -m 1 total | sed 's/total //')b${txtrst}) ${txtrst}${txtbleucj}[t]${txtgrisj} ##n${txtgrisj}(jobs:${txtbluj}j${txtgrisj}) - (screen:${txtbluj}$WINDOW${txtgrisj})`if [ $? -eq 0 ]; then echo '${txtvertj} :-)'; else echo '${bldred} :-(' ; fi`${txtrst}n$"
    else
      if [ "$UID" -eq "$ROOT_UID" ]  # Si root le @ clignote,
      then
    	  export PS1="n${txtbluj}u${txtrst}${txtarobasc}@${txtrst}${txtvertj}h${txtrst}:${txtjaunj} ${newPWD} ${txtrst}(${txtbleucj}$(ls -1 | wc -l | sed 's: ::g') fichiers ${txtjaunj}$(ls -lah | grep -m 1 total | sed 's/total //')b${txtrst}) ${txtrst}${txtbleucj}[t]${txtgrisj} ##n${txtgrisj}(jobs:${txtbluj}j${txtgrisj})`if [ $? = "0" ]; then echo '${txtvertj} :-)'; else echo '${bldred} :-(' ; fi`${txtrst}n$"
      else
    	  export PS1="n${txtbluj}u${txtrst}${txtarobas}@${txtrst}${txtvertj}h${txtrst}:${txtjaunj} ${newPWD} ${txtrst}(${txtbleucj}$(ls -1 | wc -l | sed 's: ::g') fichiers ${txtjaunj}$(ls -lah | grep -m 1 total | sed 's/total //')b${txtrst}) ${txtrst}${txtbleucj}[t]${txtgrisj} ##n${txtgrisj}(jobs:${txtbluj}j${txtgrisj})`if [ $? = "0" ]; then echo '${txtvertj} :-)'; else echo '${bldred} :-(' ; fi`${txtrst}n$"
      fi
    fi
  5. désolé pour le déterrage …

    merci pour les révisions ca faisait un moment que je ne m’étais pas remis à cela ! Ca tombe pile poil puisque je dois m’y remettre !

    nota : ca me rappelle l’époque pendant laquelle j’étais au CNAM (certif admin rés et sys) ! souvenirs souvenirs …

    @ bientot

    seb

  6. Pas de problème pour le « déterrage », au contraire même.
    Je profite donc de ton message sur cet article pour donner le PROMPT que j’utilise actuellement, c’est sensiblement le même mais il n’utilise plus la fonction truncate_pwd et la variable $PROMPT_COMMAND.

    A la place il utilise les fonctionnalités de substitution de bash pour définir le répertoire courant depuis la variable $PWD:

    ${PWD//????????????????????????????*/...${PWD:${#PWD}-25}}

    J’ai aussi remplacé # ( numéro de la commande) par ! (son numéro dans l’historique).

    Voici donc le prompt complet
    (dans l’exemple ci-dessous les antislashs ne passent pas, je les ai remplacés par §)

    ROOT_UID=0   # Root a l'identifiant $UID 0.
    if [ -n "${STY#*.}" ]; then
        export PS1="§n${txtbluj}§u${txtrst}${txtarobasc}@${txtrst}${txtvertj}§h${txtrst}:${txtjaunj}${PWD/????????????????????????????*/...${PWD:${#PWD}-25}} ${txtrst}(${txtbleucj}§$( ls -1 | wc -l | sed 's: ::g' ) fichiers ${txtjaunj}§$( ls -lah | grep -m 1 total | sed 's/total //' )b${txtrst}) ${txtrst}${txtbleucj}[t]${txtgrisj} #§!§n${txtgrisj}(jobs:${txtbluj}§j${txtgrisj}) - (screen:${txtbluj}$WINDOW${txtgrisj}$( if [ §$? -eq 0 ]; then echo '${txtvertj} :-)'; else echo '${bldred} :-(' ; fi )${txtrst}§n$"
    else
      if [ "$UID" -eq "$ROOT_UID" ]  # Si root le @ clignote,
      then
              export PS1="§n${txtbluj}§u${txtrst}${txtarobasc}@${txtrst}${txtvertj}§h${txtrst}:${txtjaunj}${PWD/????????????????????????????*/...${PWD:${#PWD}-25}} ${txtrst}(${txtbleucj}§$(ls -1 | wc -l | sed 's: ::g') fichiers ${txtjaunj}§$( ls -lah | grep -m 1 total | sed 's/total //' )b${txtrst}) ${txtrst}${txtbleucj}[t]${txtgrisj} #§!§n${txtgrisj}(jobs:${txtbluj}§j${txtgrisj}$( if [ §$? = '0' ]; then echo '${txtvertj} :-)'; else echo '${bldred} :-(' ; fi )${txtrst}§n$"
      else
              export PS1="§n${txtbluj}§u${txtrst}${txtarobas}@${txtrst}${txtvertj}§h${txtrst}:${txtjaunj}${PWD/????????????????????????????*/...${PWD:${#PWD}-25}} ${txtrst}(${txtbleucj}§$( ls -1 | wc -l | sed 's: ::g' ) fichiers ${txtjaunj}§$( ls -lah | grep -m 1 total | sed 's/total //' )b${txtrst}) ${txtrst}${txtbleucj}[t]${txtgrisj} #§!§n${txtgrisj}(jobs:${txtbluj}§j${txtgrisj}$( if [ §$? = '0' ]; then echo '${txtvertj} :-)'; else echo '${bldred} :-(' ; fi )${txtrst}§n$"
      fi
    fi
  7. n3o, je viens de tester sous ubuntu et ça passe sans erreur :

    git clone https://github.com/trapd00r/cope.git
    cd cope
    perl Makefile.PL
    make
    sudo make install

    Ensuite la commande :

    perl cope_path.pl

    me donne

    /usr/local/share/perl/5.10.1/auto/share/dist/Cope

    Du coup il ne reste plus qu’à modifier la variable $PATH

    export PATH=/usr/local/share/perl/5.10.1/auto/share/dist/Cope:$PATH

    Et pour que ça soit définitif on ajoute ça dans le fichier .bashrc dans le home :

    echo 'export PATH=/usr/local/share/perl/5.10.1/auto/share/dist/Cope:$PATH' >> ~/.bashrc

    Et on recharge :

    source ~/.bashrc

    Si ça ne passe pas pour toi il faudrait au moins connaître l’erreur obtenue pour avoir un idée de la raison !

  8. n3o

    Merci jerome mais j’ai des erreurs lors de la compilation

    Can’t locate File/ShareDir.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.10.1 /usr/local/share/perl/5.10.1 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at cope_path.pl line 4.
    BEGIN failed–compilation aborted at cope_path.pl line 4.

    cela lors du perl cope path

    alors j’ai relancer et j’ai

    Error opening ‘MYMETA.json’ for writing: Permission non accordée
    — cannot continue

    [ERROR] Unable to create a new distribution object for ‘File::ShareDir’ — cannot continue

    lors de make ensuite lors de sudo make install

    [ERROR] File ‘/home/n3o-chacha/.cpanplus/5.10.1/build/Class-Inspector-1.27/Makefile’ is not readable or does not exist

    Key ‘file’ (/home/n3o-chacha/.cpanplus/5.10.1/build/Class-Inspector-1.27/Makefile) is of invalid type for ‘CPANPLUS::Dist::MM::_find_prereqs’ provided by CPANPLUS::Dist::MM::prepare at /usr/share/perl/5.10/CPANPLUS/Module.pm line 815
    [ERROR] Unable to scan ‘/home/n3o-chacha/.cpanplus/5.10.1/build/Class-Inspector-1.27/Makefile’ for prereqs

    [ERROR] Unable to create a new distribution object for ‘Class::Inspector’ — cannot continue

    [ERROR] Failed to install ‘Class::Inspector’ as prerequisite for ‘File::ShareDir’

    [ERROR] Unable to satisfy prerequisites for ‘File::ShareDir’ — aborting install

    [ERROR] Unable to create a new distribution object for ‘File::ShareDir’ — cannot continue

    Key ‘ok’ () is of invalid type for ‘CPANPLUS::Backend::RV::new’ provided by CPANPLUS::Backend::__ANON__ at /usr/share/perl/5.10/CPANPLUS/Backend.pm line 398
    *** File::ShareDir installation cancelled.

  9. Jerska

    Merci pour cet article ultra précis !
    Comme n30 j’ai eu quelques galères pour cope, mais évidemment c’était un problème de dépendances de perl non installées.
    J’ai enfin un shell digne de ce nom ! (Je suis sous fedora)

    Juste une chose, les fichiers ne se mettent évidemment pas à jour à chaque cd comme le (ls -1 | wc -l | sed ‘s: ::g’) n’est appelé que dans la génération du PS1 et n’affiche donc que les infos du /home.

    Personnellement je l’ai rajouté dans le truncate, même si d’un coup le nom de la fonction perd un peu de son sens. ^^

    Enfin voilà, merci encore. :D

  10. Jerska

    Ha tiens, juste une petite question !

    Est-ce qu’il y aurait moyen de truncate en tronquant au début du nom d’un dossier ?


    #Exemple, plutot que d'afficher
    "...er/Documents/blabla"

    #qu'il affiche soit
    ".../user/Documents/blabla"
    #soit
    ".../Documents/blabla"

    J’imagine qu’il y a moyen avec un grep, mais étant peu habitué aux commandes du prompt, je saurais pas le sortir. :/

  11. Jerska

    Désolé pour le triple post, mais j’ai réussi ! :D

    Pour ceux que ça intéresserait :

    function truncate_pwd
    {
      nbFiles=$(ls -1 | wc -l | sed 's: ::g')
      sizeFiles=$(ls -lah | grep -m 1 total | sed 's/total //')
     
      newPWD="${PWD/#$HOME/~}"
      local pwdmaxlen=$((${COLUMNS:-20}/3))
      if [ ${#newPWD} -gt $pwdmaxlen ]
      then
        newPWD=$(echo -e "${newPWD: -$pwdmaxlen}" | sed 's/([^/]*)/(.*)/.../2//')
      fi
    }

    Y’a juste la ligne dans le if qui change, tout le reste pareil.
    J’ai eu du mal avec le sed j’dois avouer, mais ça m’a appris à utiliser les regex !

    Par ailleurs, pour ceux qui ont u mon premier message et qui voudrait que ça s’actualise, nbFiles et sizeFiles sont deux variables qui servent à ça. Appelez-les dans PS1 avec ${nbFiles} et ${sizeFiles} en remplacement des commandes.

    Bonne journée et merci encore pour cet article. :)

  12. Jerska

    Rah les backslashs sont partis, php fail ! :p (Quadruple post, sry)

    newPWD=$(echo -e « ${newPWD: -$pwdmaxlen} » | sed ‘s/&([^&/]*&)&/&(.*&)/&.&.&.&/&2&//’ )

    Remplacer les & par des backslashs.

  13. @Jerska
    Merci pour ta contribution, j’ai mis à jour l’article.
    PI j’ai édité ton premier message pour ajouter les backslashs (mais ça ne semble pas passer dans les commentaires).

    Sinon pour éviter les « echo » et « pipe » avec ton sed tu peux utiliser un « here string » en bash ‘< <<', ce qui donne :

    sed 's/([^/]*)/(.*)/.../2//'  ${newPWD: -$pwdmaxlen} <<<$newPWD
  14. Jerska

    Ha d’accord, ben merci bien, d’un coup ça rend tout ça un peu plus clair. :p

    Tant que j’y suis, je me suis rendu compte d’un truc récemment, le total affiché par ls -lh est pas égal à la somme des tailles des fichiers.
    Si quelqu’un sait pourquoi ça m’intéresserait vraiment.

  15. Je pense que le total de ls -lh n’est pas égal à la somme des tailles des fichiers car il ajoute 4kB pour chaque sous répertoire.

    Tu peux utiliser find pour ne prendre en compte que les fichiers, exemple :

    find REPERTOIRE -maxdepth 1 -type f -printf %k"n" | awk '{  sum += $1 } END { print sum/1024 }'
  16. SmallFItz

    Merveilleux. Oo
    Direct dans les bookmarks !
    Je saurai quoi faire cet été.
    Un immense merci à toi !
    J’ai appris / vais apprendre plein de choses. =)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Get Adobe Flash player