Bash : meuh ?


23 mai 2011

Comment se comprend la commande suivante ?

echo "hello world world hello world" | awk '{$1=$1}1' OFS=":"

Sachant qu'elle produit la sortie :

hello:world:world:hello:world

On l'aura compris, ce qui me dérange, c'est ce qui est entre accolades...

Admin : l'appel rsync le plus fréquent


21 mai 2011

La plupart des rsync que je fais sont semblables à celui qui suit, récursif, il compresse, quand il peut, les données, il ne modifie pas les droits de ce qu'il transfère et il exécute réellement le transfert seulement quand c'est nécessaire (avec une vérification par checksum), le tout avec une transmission des données par SSH. En plus elle se retient facilement :

rsync -carzv --progress --skip-compress='bz2/gz/mp3/jpg/7z/png/rar/zip' --rsh="ssh" SourceDir/ user@hostname:DestDir/

Bash : des choses que je ne savais pas...


19 mai 2011

On en découvre tous les jours sur Bash, surtout si on l'a appris en fonction de ses besoins et pas globalement.

Ainsi, on va rediriger la sortie d'un find vers une boucle while et utiliser des pseudos-classes :

#!/bin/bash
# This bash script will locate and replace spaces in the filenames
DIR="."
# Controlling a loop with bash read command by redirecting STDOUT as a STDIN to while loop
# find will not truncate filenames containing spaces
find $DIR -type f | while read file; do
    # using POSIX class [:space:] to find space in the filename
    if [[ "$file" = *[[:space:]]* ]]; then
        # substitute space with "_" character and consequently rename the file
        mv "$file" `echo $file | tr ' ' '_'`
    fi;
done

Le mot-clé select existe en Bash :

select word in "linux" "bash" "scripting" "tutorial" 
do
  echo "The word you have selected is: $word"
  break     # Break, otherwise endless loop
done

Les expensions ANSI-C :

# as a example we have used \n as a new line, \x40 is hex value for @
# and \56 is octal value for .
echo $'web: www.linuxconfig.org\nemail: web\x40linuxconfig\56org'

Les redirections...

X>&Y : redirige le flux de X vers le flux Y
X> : redirige le flux X (par défaut stdout ou 1) vers un fichier
On peut combiner les redirections précédentes, par exemple : > file 2>&1
Les deux indicateurs de redirections sont équivalents : >& et &>, tous les deux redirigent stdout et stderr vers un fichier
< : remplace stdin avec le contenu d'un fichier
<X : remplace le flux X avec le contenu d'un fichier

Si on utilise ces opérations de redirections avec la commande "exec" on exécute la redirection pour toute la durée du processus courant ou jusqu'à une modification de cette redirection et plus seulement dans le contexte d'une commande donnée. Donner des exemples.

# Link filedescriptor 10 with stdin
# stdin replaced with a file
Exemple : exec 10<&0; exec < Fichier
Son opposé (pour restaurer) : exec 0<&10 10<&-

On va utiliser 'exec < Fichier' pour pouvoir, par exemple, faire un 'while read Line' et énumérer toutes les lignes du fichier Fichier.

Question : est-ce que 'cat Fichier | command' est équivalent à 'command < Fichier' ?

Les expressions et leurs calculs
let Var=Expression : permet le calcul de Expression et le placement de son résultat dans Var
On peut "expandre" (calculer le résultat d'une expression) avec $((Expression)) ou $[ Expression ]
On peut écrire Base#Valeur pour déclarer la base dans laquelle s'exprime la valeur

Admin : redirections 301 massives


16 mai 2011

Pour planter le décor : un site a été modifié en quelques années et GWT indique à l'administrateur que des liens venant de l'extérieur aboutissent à des erreurs 404. Rien de grave ? Si, car il s'agit d'un site marchand et son référencement va s'en ressentir mais en plus il y en a plusieurs milliers !

Bien sûr, l'administrateur habitué va tout de suite penser à une solution basée sur ModRewrite d'Apache pour générer des redirections HTTP 301 (permanentes) et il aura raison :) Voici la chose :

	RewriteEngine   On
	RewriteLogLevel 0
	RewriteMap      VieillesPages404        txt:../../../../home/www/LeSite/www/oldies.404.txt
	RewriteMap      lowercase       int:tolower
	RewriteCond     ${lowercase:%{REQUEST_URI}|NONE}        ^(.+)$
	RewriteCond     ${VieillesPages404:$1}  >""
	RewriteRule     ^(.*)$          ${VieillesPages404:$1|$1}       [R=301,L]

J'ai ajouté ce code dans l'hôte virtuel parce qu'un .htaccess n'autorise pas la directive RewriteMap.

Au final, j'ai plusieurs milliers de redirections gérées sans aucune pénalité pour le serveur, un référencement de nouveau satisfaisant et une liste d'adresse qui peut évoluer au fil du temps puisqu'il ne s'agit que d'un fichier texte !

Attention : le fichier texte, oldies.404.txt, est composée de lignes contenant deux champs avec le premier précédé d'un '/' alors que le second n'en possède pas.

Source : http://www.jeremytunnell.com/posts/mod_rewrite-attempting-to-bend-rewritemap-rewritecond-and-rewriterule-to-my-will

Reste à faire : tester httxt2dbm pour qu'Apache utilise une base de données optimisée à base de hash pour repérer plus rapidement les URL à rediriger. N'en ayant pas eu besoin je ne l'ai pas fait.

Les différents JOINs du standard SQL démystifiés


15 mai 2009

Introduction

Les jointures SQL, représentées par la clause JOIN, sont une façon standardisée de combiner les éléments de deux ou plusieurs tables en leur demandant de suivre une condition. Ces jointures, ces combinaisons, peuvent parfois s'appliquer sur la même table plusieurs fois (par exemple pour les classements sportifs). Grossièrement, il existe deux types de jointures : les internes, représentées par la clause INNER JOIN, et les externes, par OUTER JOIN.

Ces notes sont tirées du chapitre 9 de SQL Bible, A. Kriegel & B. Trukhnov, Wiley 2003 et ne représentent certainement pas un tutorial mais un pense-bête personnel.

Les jointures internes

Les clauses INNER JOIN combinent donc deux tables, ou plus, et renvoient les lignes pour lesquelles la condition de jointure se vérifie, à l'exclusion de toutes les autres.

...FROM <table1>
    [INNER | NATURAL | CROSS] JOIN <table2>
    [ON <condition> | USING <col_name>, ...]...
Syntaxe d'un INNER JOIN

Les jointures internes naturelles et libres

L'option NATURAL est appliquée quand les tables à joindre possède des noms de colonnes en commun et que l'on veut que la jointure les suivent. L'intérêt est que la requête est simple à écrire (mais pas forcément à comprendre) mais ceci impose que les colonnes liées aient les même noms.

Si NATURAL ne peut pas être utilisé (par exemple si les colonnes liées n'ont pas le même nom ou si on ne veut pas qu'elles soient TOUTES concernées par la jointure), on va utiliser les options INNER (le plus souvent) ou CROSS (dans des cas rares).

Ces deux options s'utilisent avec des conditions de jointures : les clauses USING et ON. USING est suivi d'une série de noms de colonnes qui doivent être les mêmes dans les deux tables, cette clause permettant de réaliser une jointure interne comme NATURAL mais sur un sous-ensemble de colonnes communes. La clause ON quand à elle permet de spécifier une série de conditions comme WHERE peut le faire, on est donc cette fois totalement libre de définir la jointure. Par contre la requête se complexifie d'autant (on n'a rien sans rien).

NATURAL : toutes les colonnes de même noms
INNER/CROSS avec USING : les colonnes de même noms que l'on choisit
INNER/CROSS avec ON : jointure que l'on peut définir librement
simplicité d'écriture vs liberté de jointure

Donc pour résumer : on utilisera soit NATURAL sans conditions de jointures, soit INNER/CROSS avec des conditions de jointures.

Le CROSS JOIN

Un CROSS JOIN est le produit cartésien des tenseurs en algèbre : pour chacune des lignes de la table A on associe toutes les lignes de la table B.

On peut se servir de ce type de jointure pour l'élaboration de données de test car on a immédiatement un grand nombre d'éléments après son application.

Les jointures externes

OUTER JOIN : les jointures externes car les INNER JOIN ignorent par définition les colonnes contenant des NULLs dans une seule des deux tables et que ces lignes peuvent tout de même nous intéresser. Une jointure externe renvoie TOUTES les entrées de la table A (à la clause WHERE près évidemment) et celles de la table B qui leur correspondent SI elles existent.

...FROM <table1>
((LEFT | RIGHT | FULL) [OUTER] | UNION) JOIN <table2>
[ON <condition>] | [USING <col_name>, ...], ...
Syntaxe d'une jointure externe

Les jointures externes gauche et droite

Les jointures externes complètes

Un FULL OUTER JOIN renverra la combinaison des deux A LEFT OUTER JOIN B et A RIGHT OUTER JOIN B.

Les UNION JOINs

Les UNION JOINs représentent l'intersection des deux JOINs suivants : (A FULL OUTER JOIN B) et (A INNER JOIN B) On extrait donc les lignes jointées qui correspondent entre les deux tables ou celles qui ont un NULL parmi les champs considérés, on extrait d'autre part les lignes dont les éléments correspondent entre les deux tables et on prend l'intersection de ces deux résultats. On obtient donc toutes les lignes jointées qui ont un NULL dans une des deux tables.

Ex : on doit donc pouvoir avoir les matches non joués de toutes les équipes.

Les jointures à l'ancienne, i.e. sans JOIN explicites mais avec une clause WHERE

On peut effectivement facilement trouver une correspondance entre les INNER JOINs et la "l'ancienne notation" qui n'utilise que la clause WHERE. Mais qu'en est-il des OUTER JOINs, ça a l'air bien plus compliqué de trouver une équivalence de ce type ? Ceci sans utiliser les notations batardes d'Oracle ou MS...

/* Ex : les matches de foot joués par une équipe. Un INNER JOIN ne renverra pas les matches non joués, i.e. ceux qui ont NULL dans les scores. Ex : on peut prendre comme exemple les matches de foot que j'ai déjà fait pour expliquer les LEFT et RIGHT OUTER JOINs. On aura tous les matches d'une équipe, joués ou pas. Pour les FULL OUTER JOINs >On peut peut-être séparer la notion de score à domicile et à l'extérieur pour illustrer les LEFT, RIGHT et FULL OUTER JOINs ! */ //OUTER JOINs simplification : http://dev.mysql.com/doc/refman/5.1/en/outer-join-simplification.html //LEFT and RIGHT JOINs optimization : http://dev.mysql.com/doc/refman/5.1/en/left-join-optimization.html //JOINs syntax : http://dev.mysql.com/doc/refman/5.1/en/join.html
Accueil1 2 3 4 5 6 7 8