====== Bash ======
Un site qu'il est bien pratique http://www.shellunix.com/commandes.html
Un autre bien détaillé sur le bash http://aral.iut-rodez.fr/fr/sanchis/enseignement/bash/index.html
La bible en anglais du GNU Bash => http://wiki.bash-hackers.org/start
Le guide du débutant, ici l'introduction au if => http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html
Se replacer dans le répertoire du script automatiquement
#!/bin/bash
cd `dirname $0`
* ''$1'' est le 1er argument passé au script, ''$2'' le 2ème etc.. A partir de 10, on note ''${10}''
* ''$0'' Contient le nom du script tel qu'il a été invoqué
* ''$*'' L'ensembles des paramètres sous la forme d'un seul argument
* ''$@'' L'ensemble des arguments, un argument par paramètre
* ''$#'' Le nombre de paramètres passés au script
* ''$?'' Le code retour de la dernière commande
* ''$$'' Le PID su shell qui exécute le script
* ''$!'' Le PID du dernier processus lancé en arrière-plan
* ''$RANDOM'' Une valeur numeric au hasard
* ''$SECONDS'' Valeur numéric s'incrémentant toutes les secondes, utile pour chronométrer un script
===== Bang (!) commands =====
Re-run all or part of a previous command.\\
Event Designators. An event designator is a reference to a command line entry in the history list. Unless the reference is absolute, events are relative to the current position in the history list.
* ''!!'' Run the last command again
* ''!n'' Refer to command line n.
* ''!-n'' Refer to the current command minus n.
* ''!foo'' Run the most recent command that starts with 'foo' (e.g. !ls)
* ''!foo:p'' Print out the command that !foo would run also add it to the command history
* ''!$'' Run the last word of the previous command (same as Alt + .)
* ''!$:p'' Print out the word that !$ would substitute
* ''!*'' Run the previous command except for the last word
* ''!*:p'' Print out the previous command except for the last word
* ''^foo^bar'' Run the previous command replacing foo with bar
* ''!#'' The entire command line typed so far.
===== Variable =====
toto=lol
echo $toto
echo ${toto}
cpt=1
echo $((cpt++))
echo $((cpt+15))
Tableau associatif ( http://www.artificialworlds.net/blog/2012/10/17/bash-associative-array-examples/ )
$ declare -A MYMAP # Create an associative array
$ MYMAP[foo]=bar # Put a value into an associative array
$ echo ${MYMAP[foo]} # Get a value out of an associative array
bar
$ echo MYMAP[foo] # WRONG
MYMAP[foo]
$ echo $MYMAP[foo] # WRONG
[foo]
$ K=baz
$ MYMAP[$K]=quux # Use a variable as key to put a value into an associative array
$ echo ${MYMAP[$K]} # Use a variable as key to extract a value from an associative array
quux
$ echo ${MYMAP[baz]} # Obviously the value is accessible via the literal key
quux
$ declare -A MYMAP=( [foo a]=bar [baz b]=quux )
$ echo "${!MYMAP[@]}" # Print all keys - quoted, but quotes removed by echo
foo a baz b
$ # Looping through keys and values in an associative array
$ for K in "${!MYMAP[@]}"; do echo $K --- ${MYMAP[$K]}; done
foo a --- bar
baz b --- quux
$ # Loop through all values in an associative array
$ for V in "${MYMAP[@]}"; do echo $V; done
bar
quux
$ echo ${#MYMAP[@]} # Number of keys in an associative array
2
Faire une liste simple
list=(
aaa
bbb
ccc
ddd
)
$ echo $list
aaa
$ echo ${list[@]}
aaa bbb ccc ddd
$ echo ${list[1]}
bbb
$ for i in ${list[@]}; do echo $i; done
aaa
bbb
ccc
ddd
===== Manipuler du texte =====
-- source http://tldp.org/LDP/abs/html/string-manipulation.html
==== Taille d'un texte ====
stringZ=abcABC123ABCabc
echo ${#stringZ} # 15
echo `expr length $stringZ` # 15
echo `expr "$stringZ" : '.*'` # 15
==== Position d'un texte dans un texte ====
stringZ=abcABC123ABCabc
# 123456 ...
echo `expr index "$stringZ" C12` # 6
# C position.
echo `expr index "$stringZ" 1c` # 3
# 'c' (in #3 position) matches before '1'.
==== Extraite une partie du texte ====
stringZ=abcABC123ABCabc
# 0123456789.....
# 0-based indexing.
echo ${stringZ:0} # abcABC123ABCabc
echo ${stringZ:1} # bcABC123ABCabc
echo ${stringZ:7} # 23ABCabc
echo ${stringZ:7:3} # 23A
# Three characters of substring.
# Is it possible to index from the right end of the string?
echo ${stringZ:-4} # abcABC123ABCabc
# Defaults to full string, as in ${parameter:-default}.
# However . . .
echo ${stringZ:(-4)} # Cabc
echo ${stringZ: -4} # Cabc
# Now, it works.
# Parentheses or added space "escape" the position parameter.
# Thank you, Dan Jacobson, for pointing this out.
==== Remplacer du texte dans un texte ====
stringZ=abcABC123ABCabc
echo ${stringZ/abc/xyz} # xyzABC123ABCabc
# Replaces first match of 'abc' with 'xyz'.
echo ${stringZ//abc/xyz} # xyzABC123ABCxyz
# Replaces all matches of 'abc' with # 'xyz'.
echo ---------------
echo "$stringZ" # abcABC123ABCabc
echo ---------------
# The string itself is not altered!
# Can the match and replacement strings be parameterized?
match=abc
repl=000
echo ${stringZ/$match/$repl} # 000ABC123ABCabc
# ^ ^ ^^^
echo ${stringZ//$match/$repl} # 000ABC123ABC000
# Yes! ^ ^ ^^^ ^^^
echo
# What happens if no $replacement string is supplied?
echo ${stringZ/abc} # ABC123ABCabc
echo ${stringZ//abc} # ABC123ABC
# A simple deletion takes place.
echo ${stringZ/#abc/XYZ} # XYZABC123ABCabc
# Replaces front-end match of 'abc' with 'XYZ'.
echo ${stringZ/%abc/XYZ} # abcABC123ABCXYZ
# Replaces back-end match of 'abc' with 'XYZ'.
===== Lire un fichier =====
#!/bin/bash
# Usage: $0 < FILENAME
while read line # Boucle sur chaque ligne du fichier
do
echo "$line" # Affiche la ligne en cours
len=${#line} # taille de la ligne
done
ou
#!/bin/bash
while read line # Boucle sur chaque ligne du fichier
do
echo "$line" # Affiche la ligne en cours
done < /home/user/mon_fichier
Traiter un fichier csv
#!/bin/bash
while IFS=';' read champ1 champ2 champ3 # déclarez autant de champ séparé par un ;
do
echo "$champ1 $champ2 $champ3" # Affiche les champs
done < /home/user/mon_fichier.csv
===== Test d'exécution d'une commande =====
La 1ère façon la plus simple est d'utiliser ''&&'' et ''||''
command && echo "tout est ok" || echo "la commande a échoué"
Dans des cas plus complexe, vous pouvez créer une fonction dans un fichier **mesfonctions** que vous pouvez inclure facilement dans d'autres scripts avec la commande
. /cheminde/mesfonctions
ou
source /chemeinde/mesfonctions
run() {
# Vous pouvez lancer ici une pre-command
# on exécute la commande passée en paramètre
$@
if [ $? -ne 0 ]
then
#si le code retour est différent de zéro, cela signifie que la commande a échoué
echo "Big problème !!!"
return 1
else
#sinon tout est ok
echo "Good !"
return 0
fi
}
===== Exemple de condition =====
Voila un petit bout de bash pour tester l’existence d’un repertoire ou d’un fichier
#!/bin/bash
dir="/home/hio/test"
if [ -d "$dir" ]; then
echo "$dir existe !"
fi
et en rajoutant un else ^^
#!/bin/bash
dir="/home/hio/test"
if [ -d "$dir" ]; then
echo "$dir existe !"
else
echo "$dir n'existe pas!"
fi
et en inversant le test on rajoute juste un « ! » devant le « -d »
#!/bin/bash
dir="/home/hio/test"
if [ ! -d "$dir" ]; then
echo "$dir n'existe pas!"
else
echo "$dir existe !"
fi
Voila, c’est pas tres compliqué ^^ et pour tester l’existence d’un fichier, on remplace juste le « -d » par un « -f »
On peut aussi écrire
if test -f $1
then
file $1
else
echo " le fichier n'existe pas "
fi
La commande test permet pas mal de possibilité ( voir man test )
Le fait de mettre -e à la place de -d ou -f est plus pratique car ca test tout sans distinction.
if [ -e index.html ]; then echo OK; fi
Autre facon encore plus courte de faire la même chose
[[e_index.html]] && echo OK
Pour tester le contenu d'une string
VAR="hello"
if [ -n "$VAR" ]; then
echo "VAR is not empty"
fi
VAR=""
if [ -z "$VAR" ]; then
echo "VAR is empty"
fi
Tester le contenu d'une chaine avec du regex
Tester une date yyyymmdd de facon très simple
[[ $date =~ ^[0-9]{8}$ ]] && echo "yes"
ou plus complet
[[ $date =~ ^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$ ]] && echo "yes"
# |^^^^^^^^ ^^^^^^ ^^^^^^ ^^^^^^ ^^^^^^^^^^ ^^^^^^ |
# | | ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ |
# | | | | |
# | | \ | |
# | --year-- --month-- --day-- |
# | either 01...09 either 01..09 end of line
# start of line or 10,11,12 or 10..29
# or 30, 31
That is, you can define a regex in Bash matching the format you want. This way you can do:
[[ $date =~ ^regex$ ]] && echo "matched" || echo "did not match"
where commands after && are executed if the test is successful, and commands after || are executed if the test is unsuccessful.
Note this is based on the solution by Aleks-Daniel Jakimenko in User input date format verification in bash.
In other shells you can use grep. If your shell is POSIX compliant, do
(echo "$date" | grep -Eq ^regex$) && echo "matched" || echo "did not match"
In fish, which is not POSIX-compliant, you can do
echo "$date" | grep -Eq "^regex\$"; and echo "matched"; or echo "did not match"
===== Boucle =====
==== for ====
for VARIABLE in 1 2 3 4 5 .. N
do
command1
command2
commandN
done
Séquence
for i in {1..5}
do
echo "Welcome $i times"
done
Affiche les nombres impaires
for i in {1..11..2}
do
echo "Welcome $i times"
done
plus d'exemple => http://www.cyberciti.biz/faq/bash-for-loop/
Ecriture sur une ligne de commande
for i in {1..5}; do COMMAND-HERE; done
for X in /dev/sd*; do echo $X; smartctl -a $X | grep overall; done
~# for X in {a..z}; do smartctl -a /dev/sd$X | grep overall; done
SMART overall-health self-assessment test result: PASSED
SMART overall-health self-assessment test result: PASSED
SMART overall-health self-assessment test result: PASSED
SMART overall-health self-assessment test result: PASSED
...
===== Suppression d'un grand nombre de fichiers =====
Lorsqu'il y a un grand nombre de fichiers à supprimer, la commande **rm** ne suffit plus.
Voici 3 facons différentes d'effectuer cette suppression.
On liste les fichiers que l'on veut supprimer avec **ls** et avec **xargs** on les envoie en argument un par un à **rm**
ls * | xargs rm
NOTE : le **ls * ** ne fonctionne pas quand on a trop de fichier..., essayer plutot ceci si vous voulez par exemple effacer tous les fichiers qui contient le mot **toto**
ls | grep toto | xargs rm -f
Si vous souhaitez effacer tous les fichiers du répertoire courant, ceci fonctionnera
ls | xargs rm -f
A la place de **ls** on peut aussi utiliser **find**
find . -type f -name \* | xargs rm
Ou utiliser **find** sans **xargs**
find . -name "*" -exec rm {} \;
Pour savoir combien de fichiers vont être effacés
find . -name "*" | wc -l
Garder les 5 fichiers les plus récents et supprimer le reste
ls -c *.txt | tail -n +5 | xargs rm
===== Taille de plusieurs répertoires =====
Permet d'afficher la taille des répertoires du répertoire courant.
du -h --max-depth=1
Affiche la taille des répertoires
du -hcs *
Affiche la taille des répertoires en ignorant les autres disques (sans compter les /mnt, /media..) et trie du plus petit au plus grand.
du -xhcs --max-depth=1 | sort -h
Compter le nombre de fichier récursivement sans compter les répertoires
ls -Rp repertoire | grep -v -e ^$ -e / | wc -l
Compter le nombre de répertoire
ls -dR repertoire/* | wc -l
Un petit programme nommé **ncdu** dispo dans les dépots permet d'afficher sous forme graphique la taille des répertoires et de naviguer à l'intérieur
===== Faire un prompt =====
Ce script pose une question à l'utilisateur et la repose tant qu'une réponse valide n'a pas été donnée.
PS3='> ' # le prompt
LISTE=("[y] yes" "[n] no") # liste de choix disponibles
select CHOIX in "${LISTE[@]}" ; do
case $REPLY in
yes|y)
echo ok
break
;;
no|n)
echo ko
break
;;
*) echo "invalid option $REPLY";;
esac
done
Demander de saisir un texte
echo Hello, who am I talking to?
read varname
echo It\'s nice to meet you $varname
===== echo =====
Ne pas revenir à la ligne
[user@pc]# echo -n blabla
blabla[user@pc]#
Autoriser les sequences avec des backslash
echo -e blabla\\nbla
blabla
bla
\\ backslash
\a alert (BEL)
\b backspace
\c produce no further output
\e escape
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\0NNN byte with octal value NNN (1 to 3 digits)
\xHH byte with hexadecimal value HH (1 to 2 digits)
Dans le cas d'une variable avec retour chariot, echo converti les retours chariots par un espace. Il est possible de faire autrement. Voici un exemple
[root@pc:~]# free
total used free shared buffers cached
Mem: 236736 185120 51616 0 80084 16968
-/+ buffers/cache: 88068 148668
Swap: 102396 96 102300
[root@pc:~]# toto=`free`
[root@pc:~]# echo $toto
total used free shared buffers cached Mem: 236736 185240 51496 0 80092 16968 -/+ buffers/cache: 88180 148556 Swap: 102396 96 102300
[root@pc:~]# echo "$toto"
total used free shared buffers cached
Mem: 236736 185240 51496 0 80092 16968
-/+ buffers/cache: 88180 148556
Swap: 102396 96 102300
===== Ecrire en couleur =====
!/bin/sh
VERT="\\033[1;32m"
NORMAL="\\033[0;39m"
ROUGE="\\033[1;31m"
ROSE="\\033[1;35m"
BLEU="\\033[1;34m"
BLANC="\\033[0;02m"
BLANCLAIR="\\033[1;08m"
JAUNE="\\033[1;33m"
CYAN="\\033[1;36m"
echo ""
echo -e "$VERT" " ------------------ ""$ROUGE""Y o u W i l l B e C o l o r e d ""$VERT"" ------------ " "$NORMAL"
echo " | Color bash script | "
echo -e " | written by""$VERT" "selim,b." "$CYAN""(s.bouras@free.fr) " "$NORMAL" " | "
echo -e " | This script is""$BLEU"" free Licence""$NORMAL"" | "
echo -e "$VERT" " -------------------------------------------------------------------- " "$NORMAL"
echo -e " $BLEU" " Ok!!..Dear ... Your bash is colored .. Have Fun!!.."
En php exécuté en mode console, vous pouvez aussi écrire en couleur avec un
echo "\033[47m \033[1;34m texte en bleu sur fond gris clair \033[0m \n";
Contrairement au bash, il faut mettre un seul backslash et utiliser des guillemets.
Code couleur du texte
black = \033[0;30m
dark_gray = \033[1;30m
blue = \033[0;34m
light_blue = \033[1;34m
green = \033[0;32m
light_green = \033[1;32m
cyan = \033[0;36m
light_cyan = \033[1;36m
red = \033[0;31m
light_red = \033[1;31m
purple = \033[0;35m
light_purple = \033[1;35m
brown = \033[0;33m
yellow = \033[1;33m
light_gray = \033[0;37m
white = \033[1;37m
Code couleur du fond
black = \033[40m
red = \033[41m
green = \033[42m
yellow = \033[43m
blue = \033[44m
magenta = \033[45m
cyan = \033[46m
light_gray = \033[47m
Toujours réinitialiser la fin de la phrase par
\033[0m
===== Modifier le contenu d'un fichier avec sed =====
Il peut être utile d'utiliser **sed** pour modifier une valeur dans un fichier de configuration en tapant juste une ligne de commande.
[[linux:sed|Autre page sur sed]]
Dans mon cas, je voulais modifier une variable dans tous mes fichiers *awstats et donc au lieu d'ouvrir un à un mes fichiers de conf, j'ai juste eu à lancer la commande sed ;)
Exemple pour modifier la variable **Categories** dans un fichier
sed -i 's/^Categories=.*/Categories=toto/' FILENAME
option -i de sed : écrire dans le fichier
commande 's/A/B/' : remplacer A par B avec pour A :
^Categories=.* : n'importe quelle ligne commençant (le ^) par Categories= et suivi par un nombre quelconque (*) de n'importe quel caractère (.)
Une variante qui fait la même chose que sed mais en utilisant **grep** et **echo**
grep '^Categories=' FILENAME || { echo; echo 'Categories=toto'; } >>FILENAME
grep '^Categories=' FILENAME : cherche une ligne commençant par Categories= dans FILENAME
si la commande échoue elle retourne un code d'erreur 1 et ce qui est après || est exécuté :
{ echo; echo 'Categories=toto'; } >>FILENAME : saute une ligne et ajoute (>>) 'Categories=toto' à FILENAME, ce qui aurait pu aussi être écrit :
echo -e "\nCategories=toto" >>FILENAME
l'option -e autorise les caractères spéciaux tels que \n (newline)
edit: et juste pour le fun (et le chipotage) il ne sert à rien de lancer la substitution si le motif Categories= est absent (dans le cas où on fait le grep) donc :
if grep -q '^Categories=' FILENAME; then
sed -i 's/^Categories=.*/Categories=toto/' FILENAME
else
echo -e "\nCategories=toto" >>FILENAME
fi
grep -q pour ne pas avoir de sortie, juste le code de retour 0 (trouvé) ou 1 (absent)
===== trap, wait, sleep =====
''trap'' sert à exécuter une commande lorsqu'un signal est envoyé au script en cours
''wait'' sert à attendre la fin d'une commande qui aura été lancé en tache de fond
''sleep'' sert à faire une pause suivant un nombre de seconde définit
Le petit script suivant est une démonstration de wait, trap et sleep.\\
Le but est de lancer 3 commandes en parallèle et de vérifier l'état d'avancement en parallèle puis de récupérer le code de retour à la fin.
- Au commencement, on exécute trois ''wget'' en tache de fond dont le 3ème est volontairement erroné
- Je reviendrai sur trap plus tard
- On fait une boucle while avec un test sur le rendu de la commande ''jobs'' qui ne renvoi rien quand il n'y a plus rien qui tourne en tache de fond. Donc, tant que les commandes précédentes lancées en tache de fond ne sont pas fini, on continu d'exécuter tout ce qui se trouve dans la boucle while
- Dans la boucle, je fais une pause d'une seconde et j'affiche ensuite la taille du fichier que nous sommes en train de télécharger pour chaque tache qui tourne.
- Lorsque toutes les taches ont fini de tourner, je récupère le code d'erreur avec ''wait'' et on affiche le résultat.
#!/bin/bash
wget -q http://proof.ovh.net/files/10Mio.dat -O 10Mio.dat &
PID1=$!
wget -q http://proof.ovh.net/files/1Mio.dat -O 1Mio.dat &
PID2=$!
# plusieurs commandes passées en tache de fond
(
echo blabla
wget -q http://proof.ovh.net/files/1Mio.dat -O 1Mio.dat
) &
PID3=$!
trap 'kill $PID1 $PID2; exit 0' 1 2 3 15
while [ -n "`jobs`" ]
do
jobs
if [ -d /proc/$PID1 ]
then
sleep 1
echo Process $PID1
du 10Mio.dat | cut -f1
fi
if [ -d /proc/$PID2 ]
then
sleep 1
echo Process $PID2
du 1Mio.dat | cut -f1
fi
done
wait $PID1
exit1=$?
wait $PID2
exit2=$?
wait $PID3
exit3=$?
echo "Process $PID1 : Code de retour $exit1"
echo "Process $PID2 : Code de retour $exit2"
echo "Process $PID3 : Code de retour $exit3"
A quoi sert le trap ?
Lorsque je lance mon script et que je ne veux pas attendre la fin du téléchargement, je quitte en faisant un Ctrl+C. Le problème est que le wget continu de tourner en tache de fond et si je lance 10 fois mon script et que je fais 10 fois Ctrl+C je me retrouve avec 10 wget qui tournent en tache de fond.
trap va me permettre de lancer une commande lorsque je fais un Ctrl+C ou un kill (mais pas un kill -9). Ici j'ai mis la commande ''kill $!''. Souvenez-vous que ''$!'' correspond au pid de la commande lancé précédemment. Il ne faut pas oublier ''exit 0'' sinon vous ne sortirez jamais du script avec votre Ctrl+C, vous serez obliger d'utiliser ''kill -9''
===== lien symbolique nommé selon la date de répertoire =====
Dans le cas d'un backup avec rsnapshot ou on a des dossiers de type daily.0, daily.1, daily.2 etc.. je voulais des noms de répertoire plus parlant comme par exemple la date de création du répertoire.
for f in /media/hdd/backup/daily.* ; do ln -s $f `ls -ld --time-style=+%Y-%m-%d $f | awk '{print $6}'`; done
On obtient :
lrwxrwxrwx 1 root root 29 janv. 29 00:15 2014-01-16 -> /media/hdd/backup/daily.12
lrwxrwxrwx 1 root root 29 janv. 29 00:15 2014-01-17 -> /media/hdd/backup/daily.11
lrwxrwxrwx 1 root root 29 janv. 29 00:15 2014-01-18 -> /media/hdd/backup/daily.10
lrwxrwxrwx 1 root root 28 janv. 29 00:15 2014-01-19 -> /media/hdd/backup/daily.9
lrwxrwxrwx 1 root root 28 janv. 29 00:15 2014-01-20 -> /media/hdd/backup/daily.8
lrwxrwxrwx 1 root root 28 janv. 29 00:15 2014-01-21 -> /media/hdd/backup/daily.7
lrwxrwxrwx 1 root root 28 janv. 29 00:15 2014-01-22 -> /media/hdd/backup/daily.6
lrwxrwxrwx 1 root root 28 janv. 29 00:15 2014-01-23 -> /media/hdd/backup/daily.5
lrwxrwxrwx 1 root root 28 janv. 29 00:15 2014-01-24 -> /media/hdd/backup/daily.4
lrwxrwxrwx 1 root root 28 janv. 29 00:15 2014-01-25 -> /media/hdd/backup/daily.3
lrwxrwxrwx 1 root root 28 janv. 29 00:15 2014-01-26 -> /media/hdd/backup/daily.2
lrwxrwxrwx 1 root root 28 janv. 29 00:15 2014-01-27 -> /media/hdd/backup/daily.1
lrwxrwxrwx 1 root root 28 janv. 29 00:15 2014-01-28 -> /media/hdd/backup/daily.0
Il n'y a plus qu'a faire pointer votre partage samba sur ce répertoire de lien symbolique ;)
===== Renommer / changer l'extension de plusieurs fichiers =====
Pour changer l'extension de tous les fichiers .css en .less
rename 's/\.css$/\.less/' *.css
===== Couper un gros fichier en petit morceau =====
# split --help
Utilisation : split [OPTION]... [INPUT [PREFIX]]
Affiche sur la sortie des morceaux de INPUT de taille fixe selon PREFIXaa,
PREFIXab, ... ; par défaut la taille est de 1000 lignes et le préfixe par
défaut est « x ».
Sans INPUT ou quand INPUT est -, la lecture se fait sur l'entrée standard.
Les arguments obligatoires pour les options longues le sont aussi pour les
options courtes.
-a, --suffix-length=N utilise les suffixes de longueur N (par défaut 2)
-b, --bytes=BYTES écrit BYTES octets par fichier de sortie
-C, --line-bytes=SIZE écrit au plus SIZE octets par ligne par fichier de
sortie
-d, --numeric-suffixes utilise des suffixes numériques et non alphabétiques
-l, --lines=NUMBER écrit NUMBER lignes par fichier de sortie
--verbose affiche un diagnostic juste avant chaque ouverture de
fichier de sortie
--help affiche l'aide et quitte
--version affiche des informations de version et quitte
SIZE peut être (ou un entier optionnellement suivi par) l'une des valeurs
suivantes : kB 1000, K 1024, MB 1000*1000, M 1024*1024 et ainsi de suite pour
G, T, P, E, Z et Y.
Pour découper un gros **messages.log** en plusieurs petits fichier nommé **messages.split.00, messages.split.01...**
split -d -b 500MB messages.log messages.split.
===== Redimensionner des images =====
On a un répertoire plein d'image HD et on voudrait un répertoire **miniature** avec les images redimensionnées. Et bien sur, on ne veut pas recréer les miniatures qui existe déjà sauf si c'est voulu.
En 1er lieu, installez le paquet **imagemagick** qui contient tout un tas d'outils de création, conversion d'images ( http://www.imagemagick.org/script/command-line-tools.php )
Si vous voulez tout convertir en une fois
mogrify -resize 200 -quality 75 -interlace Plane -strip -path /home/user/photo/miniature /home/user/photo/*.jpg
Sinon voici le script
#!/bin/bash
path_src='/home/user/photo'
path_dest='/home/user/photo/miniature'
cd $path_src
for file in *.jpg;
do
if [ ! -f $path_dest/$file -o "$1" == "overwrite" ]; then
convert -resize 200 -quality 75 -interlace Plane -strip $file $path_dest/$file
fi
done
Ici on fait une boucle sur les fichiers avec un filtre sur les extensions jpg. Ensuite on teste si le fichier n'existe pas dans la destination OU si l'argument passé au script est "overwrite" alors on exécute la commande "convert"
* ''-resize 200'' permet de réduire l'image sur une largeur de 200px en gardant la proportionnalité de l'image
* ''-quality 75'' joue sur la compression de l'image et donc sa qualité. 0 renvoie une petite taille mais une image pourri, 100 renvoie une belle image mais d'une taille conséquente
* ''-interlace Plane'' est le mode progressif du format jpeg qui permet sur les sites web d'afficher une 1er image en mode dégradé avant d'avoir fini son chargement complet
* ''-strip'' permet de supprimer les informations inutiles de l'image
===== Manipuler les process =====
source : http://monkeypatch.me/blog/move-a-running-process-to-a-new-screen-shell.html
Récupérer un process lancé sur un autre terminal avec la commande **reptyr**
En bref
* [Ctrl]+[C] : arrête le processus courant, càd que ça le kill...
* [Ctrl]+[Z] : mets en arrière plan le processus courant, et rend la main (on se retrouve sous un shell)
* bg : continue l’exécution en tache de fonds d'un programme qui s'est mangé un [Ctrl]+[Z] dans la gueule...
* fg : continue l’exécution en avant plan (on perd le prompt shell) d'un programme qui s'est fait [Ctrl]+[Z]er...
* jobs : liste les processus qui sont en arrière plan
===== Date de fichier =====
La commande **touch** permet de changer la date de modification d'un fichier
# touch toto.txt
# stat toto.txt
File: « toto.txt »
Size: 0 Blocks: 0 IO Block: 4096 fichier vide
Device: fd00h/64768d Inode: 130793 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2016-07-04 08:47:38.715578195 +0000
Modify: 2016-07-04 08:47:38.715578195 +0000
Change: 2016-07-04 08:47:38.715578195 +0000
# touch -d "2015-01-01 00:00" toto.txt
# stat toto.txt
File: « toto.txt »
Size: 0 Blocks: 0 IO Block: 4096 fichier vide
Device: fd00h/64768d Inode: 130793 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2015-01-01 00:00:00.000000000 +0000
Modify: 2015-01-01 00:00:00.000000000 +0000
Change: 2016-07-04 08:48:40.464863103 +0000
On peut aussi utiliser la notation suivante
# touch -d "-1 day" toto.txt
===== rbash (restrited bash) =====
A creuser pour les accès restreint en ssh https://en.wikipedia.org/wiki/Restricted_shell
===== vérifier si le script tourne encore =====
Pour voir si le script **abc.sh** tourne encore, on peut utiliser le code suivant
if pidof -x "abc.sh" >/dev/null; then
echo "Process already running"
fi
Alternatively, have your script create a PID file when it executes. It's then a simple exercise of checking for the presence of the PID file to determine if the process is already running.
#!/bin/bash
# abc.sh
mypidfile=/var/run/abc.sh.pid
# Could add check for existence of mypidfile here if interlock is
# needed in the shell script itself.
# Ensure PID file is removed on program exit.
trap "rm -f -- '$mypidfile'" EXIT
# Create a file with current PID to indicate that process is running.
echo $$ > "$mypidfile"
...
Update: The question has now changed to check from the script itself. In this case, we would expect to always see at least one abc.sh running. If there is more than one abc.sh, then we know that process is still running. I'd still suggest use of the pidof command which would return 2 PIDs if the process was already running. You could use grep to filter out the current PID, loop in the shell or even revert to just counting PIDs with wc to detect multiple processes.
Here's an example:
#!/bin/bash
for pid in $(pidof -x abc.sh); do
if [ $pid != $$ ]; then
echo "[$(date)] : abc.sh : Process is already running with PID $pid"
exit 1
fi
done
Optimisation, comme on sait que le nom du script est le notre, on peut écrire
for pid in $(pidof -x $0); do
if [ $pid != $$ ]; then
echo "[$(date)] : $0 : Process is already running with PID $pid"
exit 1
fi
done
Très utile quand on lance un script toutes les minutes pour éviter de se retrouver avec 500 process qui tournent en même dans le cas ou la réponse du script dépasserait la minute
===== ls et le globbing (ou filtrage avancé) =====
bash$ ls -l
total 2
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 a.1
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1
-rw-rw-r-- 1 bozo bozo 466 Aug 6 17:48 t2.sh
-rw-rw-r-- 1 bozo bozo 758 Jul 30 09:02 test1.txt
bash$ ls -l t?.sh
-rw-rw-r-- 1 bozo bozo 466 Aug 6 17:48 t2.sh
bash$ ls -l [ab]*
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 a.1
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1
bash$ ls -l [a-c]*
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 a.1
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1
bash$ ls -l [^ab]*
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1
-rw-rw-r-- 1 bozo bozo 466 Aug 6 17:48 t2.sh
-rw-rw-r-- 1 bozo bozo 758 Jul 30 09:02 test1.txt
bash$ ls -l {b*,c*,*est*}
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1
-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1
-rw-rw-r-- 1 bozo bozo 758 Jul 30 09:02 test1.txt
source: http://tldp.org/LDP/abs/html/globbingref.html
===== Problème d'affichage sur la ligne du prompt =====
Avec certain prompt fantaisiste, il peut y avoir des problème d'affichage notamment quand on remonte dans l'historique des commandes, ça peut vite devenir illisible.
D'où l'importance d'entourer vos codes couleurs dans la variable PS1 par \[ et \]
Si vous appelez une fonction dans la variable PS1, il faudra entourer le code couleur par \001 et \002
(voir le code dans le chapitre suivant)
source: http://mywiki.wooledge.org/BashFAQ/053
Mots clés pour recherche sur le web: Line wrapping issues in Bash
===== Afficher le status de la dernière commande dans le prompt =====
Ajoutez dans votre .bashrc ce petit bout de code
get_exit_status(){
es=$?
if [ $es -eq 0 ]
then
echo -e '\001\033[0;32m\002✔\001\033[0;0m\002'
else
echo -e '\001\033[0;31m\002✘ '$es'\001\033[0;0m\002'
fi
}
PS1='$(get_exit_status) \[\033[1;34m\]\u:\[\033[0;36m\]\W\[\033[0;0m\] $ '