Exile on Keyboard St. - Blog sur Linux et Debian

Aller au contenu | Aller au menu | Aller à la recherche

mardi 15 août 2017

Utilisation des alias Bash en mode interactif ou non

Avec Bash, les alias sont définis dans le fichier .bashrc ou plus proprement dans le fichier .bash_aliases qui normalement est chargé depuis .bashrc comme suit:

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

Si j'ai défini:

alias ll='ls -l

Alias en mode interactif

La commande ll donnera le résultat suivant:

user@machine:~$ ll
total 60
drwxr-xr-x 2 user user  4096 juil. 23 17:03 bin
drwxr-xr-x 2 user user  4096 août   3 21:41 Bureau
drwxr-xr-x 6 user user  4096 juil.  9 18:00 Documents
drwxr-xr-x 2 user user  4096 avril 29 14:20 Enregistrements
drwxr-xr-x 4 user user  4096 juin  14 07:39 Images
drwxr-xr-x 2 user user  4096 nov.   9  2016 Modèles
drwxr-xr-x 2 user user  4096 nov.  23  2016 Musique
drwxr-xr-x 9 user user  4096 juin  13 08:51 Programs
drwxr-xr-x 2 user user  4096 nov.   9  2016 Public
drwxr-xr-x 8 user user  4096 juin   4 07:25 Sources
drwxr-xr-x 6 user user 12288 août   2 07:59 Téléchargements
drwxr-xr-x 7 user user  4096 juin   5 06:31 Vidéos
drwxr-xr-x 9 user user  4096 juin  30 19:32 VirtualBox VMs

Expansion des alias

C'est normal me direz-vous. En fait, l'alias ll qui a été défini est utilisable parce que je suis dans un Shell interactif et que par défaut Bash autorise l'expansion des alias dans un Shell interactif.

On peut s'en convaincre en désactivant cette option:

user@machine:~$ shopt -u expand_aliases
user@machine:~$ ll
bash: ll : commande introuvable
user@machine:~$ alias
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -l'
alias ls='ls --color=auto'
alias rm='rm -i'

Les alias sont définis, ils existent mais ne sont pas utilisables pour autant !

Alias en mode non interactif

En mode non interactif, c'est à dire dans un script Shell lançé sans l'option -i, les choses sont différentes.

Première différence, le script .bash_aliases n'est pas chargé puisque .bashrc ne l'est pas. Ah bon ?

Il suffit de regarder le début du fichier .bashrc pour s'en convaincre:

user@machine:~$ more .bashrc 
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

Vos alias habituels ne seront donc pas connus dans les scripts.

C'est en fait assez heureux si l'on considère les alias couramment définis sur les commandes rm et cp avec une demande de confirmation: dans un script mieux vaut ne pas avoir à répondre à des questions !

Deuxième différence, l'expansion des alias n'est pas activée par défaut dans un Shell non interactif.

Considérons le script suivant:

#!/bin/bash

alias ll='ls -l'
alias
ll
user@machine:~$ alias.sh
alias ll='ls -l'
/home/user/alias.sh: ligne 5: ll : commande introuvable

L'alias défini dans le script lui même n'est pas utilisable !!!

En revanche si j'ajoute en début de script la ligne suivante:

shopt -s expand_aliases

mon alias est connu depuis le script. On pensera donc à ajouter cette commande, avant ou après la définition des alias, dans les scripts les utilisant.

Et pour afficher toutes les options actives de Bash:

shopt -s

vendredi 7 avril 2017

Bien utiliser les tableaux en bash

Le bash, Bourne Again Shell, offre une possibilité absente du Bourne Shell, à savoir la possibilité de déclarer facilement des tableaux.

On s'intéressera ici aux tableaux indexés uniquement.

Pour déclarer un tableau, rien de plus simple:

#!/bin/bash

colours=(black blue green white red yellow)

Maintenant pour afficher tous les éléments en une fois:

echo "colours_elements=${colours[@]}"

colours_elements=black blue green white red yellow

Pour afficher la troisième couleur, située à l'indice 2:

echo "green=${colours[2]}"
green=green

Le nombre d'élements du tableau:

echo "colours_count=${#colours[@]}"
colours_count=6

Pour boucler sur chaque valeur:

for colour in ${colours[@]}; do
    ...
done

Et pour afficher la troisième couleur en partant de la fin du tableau:

echo "${colours[-3]}"
white

Enfin bash permet aussi de lire un fichier dans un tableau avec la built-in mapfile.

dimanche 24 juillet 2016

Définir un valeur par défaut pour la builtin read de Bash

La builtin read de bash permet à l'utilisateur de saisir des informations depuis un script Shell.

Par exemple:

read value

On peut aussi afficher un prompt précisant ce que l'utilisateur doit entrer au clavier:

read -p "Enter the input file path: " file_path

Mais il est souvent également nécessaire de définir une valeur par défaut de telle sorte que si celle-ci convient à l'utilisateur il n'a qu'à appuyer sur Entrée:

read -p "Enter the folder path: " -e -i /tmp folder_path

qui affiche:

Enter the folder path: /tmp

Cela se fait avec le flag -i de la builtin read qui nécessite également le flag -e (pour utiliser l'interface readline).

La documentation complète des builtin de bash se trouve ici: https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html.

On peut aussi consulter le Linux Documentation Project.

dimanche 20 décembre 2015

Quelle valeur pour vos codes retour en Shell ?

On a vu précédemment que les fonctions du Shell Linux ne permettent pas de retourner facilement une valeur non numérique.

Mais dans le cas le plus courant où une fonction Shell doit retourner une valeur booléenne, que doit-on retourner ? 1 pour true ou 0 ?

Imaginons la fonction suivante dont on a très souvent besoin en Shell:

is_root_v1() {
    if [ "$(id -u)" -eq "0" ]; then
        echo "$(id -u) is root"
        return 1
    fi

    echo "$(id -u) is not root"
    return 0
}

A priori cette fonction semble correcte. Pourtant, si on l’appelle comme suit depuis un utilisateur non root:

if is_root_v1; then
    echo "We are connected as root !"
else
    echo "We are not connected as root !"
fi

On obtient le résultat suivant:

1000 is not root
We are connected as root !

L'erreur n'est pas à chercher dans le code de la fonction elle même, si le résultat de id -u est 0, c'est bien qu'on est connecté en tant que root. Cela dit, le code retour retourné par la fonction is_root_v1 n'est pas le bon.

En effet, dans un if en Shell le bloc de code then est exécuté si la condition vaut 0 et non 1 contrairement à la première idée qu'on pourrait se faire !!!

Il faut donc inverser les codes retour de notre fonction comme suit:

is_root_v2() {
    if [ "$(id -u)" -eq "0" ]; then
        echo "$(id -u) is root"
        return 0
    fi

    echo "$(id -u) is not root"
    return 1
}

Maintenant, j'obtiens un résultat cohérent:

1000 is not root
We are not connected as root !

Conclusion: en Shell true vaut 0 et false vaut 1.

On peut le vérifier avec les commandes suivantes:

true; echo $?

qui affiche 0.

Et:

false; echo $?

qui affiche 1

- page 1 de 2