Ah le Bash ! Ce vrai et beau langage qui continue son exécution même après qu'une erreur s'est produite.
Dans leur grande sagesse, les développeurs ont eu la bonne idée d'y associer un mode de débuggage, qui permet d'afficher la valeur des variables.
Quand on en a marre de débugger un script à coup de echo
toutes les deux lignes, cela s'avère pratique.
Pour l'activer :
1) On peut lancer tout le script en mode débug :
bash -x monScript.sh
2) On peut également intégrer l'option directement au niveau du shebang :
#!/usr/bin/env bash -x
3) On peut enfin ne placer qu'une partie du script en mode débug. Il suffit d'activer le mode avant le code suspect, et de le désactiver ensuite :
#!/usr/bin/env
# Le code qui ne pose pas de problème
...
# Activation du mode debug
set -x
# Le code foireux
...
# Désactivation du mode debug
set +x
# Code exécuté après
Il y a quelques autres options, mais en gros c'est l'idée.
Pour connaître le path d'un script à l'intérieur de ce même script, il faut utiliser :
PATH=${BASH_SOURCE[0]}
Au lieu de :
PATH=$0
En effet, la première méthode retourne le path du script courant même s'il est sourcé (ie lancé comme ceci : ./script.sh).
Pour télécharger le jdk d'oracle depuis leur saleté de site quand on n'a que le shell de disponible.
Je remet le script ici:
#!/bin/bash
# You must accept the Oracle Binary Code License
# http://www.oracle.com/technetwork/java/javase/terms/license/index.html
# usage: get_jdk.sh <jdk_version> <ext>
# jdk_version: 8(default) or 9
# ext: rpm or tar.gz
jdk_version=${1:-8}
ext=${2:-rpm}
readonly url="http://www.oracle.com"
readonly jdk_download_url1="$url/technetwork/java/javase/downloads/index.html"
readonly jdk_download_url2=$(
curl -s $jdk_download_url1 | \
egrep -o "\/technetwork\/java/\javase\/downloads\/jdk${jdk_version}-downloads-.+?\.html" | \
head -1 | \
cut -d '"' -f 1
)
[[ -z "$jdk_download_url2" ]] && echo "Could not get jdk download url - $jdk_download_url1" >> /dev/stderr
readonly jdk_download_url3="${url}${jdk_download_url2}"
readonly jdk_download_url4=$(
curl -s $jdk_download_url3 | \
egrep -o "http\:\/\/download.oracle\.com\/otn-pub\/java\/jdk\/[8-9](http://u[0-9]+|\+).*\/jdk-${jdk_version}.*(-|_)linux-(x64|x64_bin).$ext"
)
for dl_url in ${jdk_download_url4[@]}; do
wget --no-cookies \
--no-check-certificate \
--header "Cookie: oraclelicense=accept-securebackup-cookie" \
-N $dl_url
done
Pour récupérer le n-ème argument en bash:
#!/bin/bash
n=3
echo "${!n}"
Résultat:
bash script.sh voiture camion "tati danielle" raclette "pommes de terre" exponentielle logarithme
tati danielle
Et pour récupérer les m premiers arguments à partir du n-ème (compris):
#!/bin/bash
n=4
m=2
echo "${@:$n:$m}
Résultat:
bash script.sh voiture camion "tati danielle" raclette "pommes de terre" exponentielle logarithme
raclette pommes de terre
La variable d'environnement LANG sous Linux, contient la valeur liée aux paramètres locaux (langue, clavier, ...).
Elle vaut en général quelquechose comme ça:
fr_FR.utf8
es_EC.utf8
en_US.utf8
etc
Mais parfois, on voit cette variable LANG changer de valeur. En particulier, lors d'une compilation en langage C.
On voit alors:
LANG=C
Mais cela n'a (presque) rien a voir avec le fait que c'est le langage C qui est en jeu.
La "locale" C est une convention POSIX qui permet d'anticiper les sorties de certains outils tels que grep. Cette locale C permet en outre d'augmenter les performances de ces mêmes outils, en n'utilisant pas l'UTF8.
Enfin, la langue de cette locale est l'anglais. Eh oui.
Du coup au lieu de faire ça:
$ echo $LANG
$ fr_FR.utf8
$ LANG=C
$ echo oui | commande
On fait ça:
$ echo $LANG
$ fr_FR.utf8
$ LANG=C
$ echo yes | commande
Dans un script shell bash, pour une utilisation de yum, faire ainsi:
paquets_a_installer="mercurial zip gcc nano"
sudo yum install -y $paquets_a_installer
Le point important est qu'il NE FAUT PAS entourer la variable $paquets_a_installer avec des guillemets, lors de l'appel à yum. Sinon yum s'écrase au sol comme un gros caca des familles: il considère que les différents paquets contenus dans la variable n'en forment en réalité qu'un seul.
Pour les avoir rencontrées plusieurs fois récemment, les commandes "pushd" et "popd" sous linux peuvent faire des adeptes (ou pas).
Pour faire court, ces deux commandes, en lien avec la commande "dirs", permettent de mémoriser une suite de répertoires sous la forme d'une pile.
On peut alors naviguer entre ces répertoires numérotés (cf "dirs -v"), comme on utiliserait des alias classiques.
La navigation se fait par exemple ainsi: "cd ~3" pour entrer dans le 4eme répertoire de la pile.
Cela peut être intéressant pour naviguer dans un shell. Mais dans un script je préfère encore créer des variables.