====== 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\] $ '