Bash: trucs et astuces
Révision datée du 8 mars 2018 à 08:09 par Toine (discussion | contributions) (→Grouper des cpommandes)
Sommaire
Fonctions utiles
Conversions
# conversion netmask => cidr
# ex: mask2cidr 255.255.128.0 --> 17
# suppose qu'il n'y a plus de "255." après un octet non-255
mask2cidr ()
{
local x=${1##*255.}
set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) ${x%%.*}
x=${1%%$3*}
echo $(( $2 + (${#x}/4) ))
}
# conversion cidr => netmask
# ex: cidr2mask 17 --> 255.255.128.0
cidr2mask ()
{
set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
[ $1 -gt 1 ] && shift $1 || shift
echo ${1-0}.${2-0}.${3-0}.${4-0}
}
manipuler des chaines de caractères
split chaine de caracteres:
1)IFS: OIFS=$IFS string="ABCDE-123456" IFS=- # use "local IFS=-" inside the function set $string echo $1 # >>> ABCDE echo $2 # >>> 123456 IFS=$OIFS # restituer le séparateur originel
2) récupérer le début ou la fin (ici separateur = ' ' ) line="myhost 192.168.1.145 abcdefg 123456"
# enlever le dernier champ
$ echo ${line% *}
myhost 192.168.1.145 abcdefg
# conserver le premier champ
$ echo ${line%% *}
myhost
# enlever le premier champ
$ echo ${line#* }
192.168.1.145 abcdefg 123456
# conserver le dernier champ
$ echo ${line##* }
123456
3) affecter les différents termes d'une ligne (cf IFS) à un tableau
line="myhost 192.168.1.145 is a good host"
$ termes=($line)
$ echo ${termes[0]}
myhost
$ echo ${termes[4]}
good
substring
Par exemple:
$ date=2017-01-12
$ echo ${date:5:2}
résultat: "01"
récupérer le resultat d'une commande dans un tableau, ligne à ligne
1) IFS:
$ IFS=$'\r\n'
$ aa=($(grep blabla /pathtofile))
$ echo ${aa[0]}
ici ma premiere ligne.
manipuler le tableau:
for str in "${aa[@]}";do echo $str;done;
2) read: il faut passer par un fichier intermédiaire $ grep blabla /pathtofile > /tmp/out $ while read str; do echo $str;done < /tmp/out
manipuler des variables
# variable avec valeur par defaut
if [ ${var:=n} = "y" ]; then ...
=> affecte 'n' par défaut à $var.
manipuler les lignes d'un fichier: exemple conversion d'un dossier mp3 => wav
# chercher lister les fichiers mp3
find . -name "*.mp3" > /tmp/lst
# lire la liste dans un tableau (1 enregistrement par ligne)
IFS=$'\n' read -d -r -a files < /tmp/lst
while [ $i -lt ${#files[@]} ]; do
fout=` echo ${files[$i]} | sed "s/.mp3/.wav/"`;
lame --decode "${files[$i]}" "../wav/$fout";
let i=i+1;
done
Modifier quelques comportements avec shopt
SSH et les alias
Les alias ne sont développés qu'avec les shells interactifs sauf si l'option expand_aliases du shell est activée par la commande shopt. Pour utiliser des alias distants en SSH, ajouter dans .bashrc de l'utilisateur distant:
if [ -z "$PS1" ]; then shopt -s expand_aliases fi
avec cdable_vars interpréter les variables pour la commande 'cd'
Si cette option est active, un argument de la commande interne cd qui n'est pas un répertoire est supposé être un nom de variable dont la valeur est le répertoire visé. Exemple:
$ shopt -s cdable_vars $ vms=/home/VMimages $ cd vms /home/VMimages
avec nocaseglob ignorer la casse pour développer les noms de fichiers
Si cette option est active, bash traite les noms de fichiers sans différences minuscules/majuscules lors du développement des noms de fichiers
$ shopt -s nocaseglob $ ls cis* CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.4.0-oval.xml CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.4.0-xccdf.xml
Comportement / syntaxe bash
Grouper des commandes
- avec () les commandes placées dans la liste entre parenthèses sont exécutées dans un sous-shell. Il n'y a pas persistence dans le shell courant des variables manipulées dans ces commandes.
- avec {} les commandes placées entre accolades sont exécutées dans le contexte de shell courant. Le point virgule séparant les commandes est obligatoire sur la dernière, ainsi que les espaces autour de début et fin de bloc. D'éventuelles redirections peuvent être appliquées au bloc de commandes. Par exemple, lire un fichier dans une variable, et éviter les messages d'erreur:
{ var=$(<"$file"); } 2>/dev/null;