Trucs libres

CV Diaspora
en

dimanche 13 novembre 2011

Script d'import de fichier CSV dans MySQL

Voila le petit script sh que j’ai fait pour faire ça. Il existe la commande MySQL LOAD DATA INFILE, mais cette commande ne crée pas la structure de la table.

#!/bin/sh

MYSQL_ARGS="--defaults-file=/etc/mysql/debian.cnf"
DB="mbctest"
DELIM=";"

CSV="$1"
TABLE="$2"

[ "$CSV" = "" -o "$TABLE" = "" ] && echo "Syntax: $0 csvfile tablename" && exit 1

FIELDS=$(head -1 "$CSV" | sed -e 's/'$DELIM'/` varchar(255),\n`/g' -e 's/\r//g')
FIELDS='`'"$FIELDS"'` varchar(255)'

#echo "$FIELDS" && exit

mysql $MYSQL_ARGS $DB -e "
DROP TABLE IF EXISTS $TABLE;
CREATE TABLE $TABLE ($FIELDS);

LOAD DATA INFILE '$(pwd)/$CSV' INTO TABLE $TABLE
FIELDS TERMINATED BY '$DELIM'
IGNORE 1 LINES
;
"

http://dev.mysql.com/doc/refman/5.1/en/load-data.html

(Voir le commentaire "Posted by John Swapceinski on September 5 2011 5:33am")

vendredi 22 octobre 2010

Une solution au problème umask : inotify pour forcer les droits

Trouver une bonne solution au problème du partage des fichiers entre utilisateurs Linux est un cauchemar.

Si elle convient il y a la solution de l’UID unique. Tous les clients accèdent aux fichiers avec le même UID utilisateur. Seulement on ne sais pas qui fait quoi. Et les utilisateurs ne peuvent pas gérer finement leurs droits.

Problème : le umask par défaut est TOUJOURS 0022, ce qui fait que tout fichier créé aura les droits rw– r–– r––. Seul le propriétaire peut écrire et personne d’autre. Pour partager les fichier, un groupe doit aussi pouvoir écrire.

On peut changer ce umask. Pour la ligne de commande, ça se passe dans les fichiers .bashrc ou .profile, ou dans /etc/profile pour tous les utilisateurs. Pour un partage SFTP, on s’en sort avec un bricolage. Pour le serveur Apache, on s’en sort avec le fichier /etc/apache2/envvars sous Debian.

Si le partage de fichier se fait via un seul service, c’est simple de changer le umask, sinon, c’est compliqué. Et même en changeant tous les umask de tous les services, tout n’est pas parfait : par exemple, Nautilus via SFTP n’en fait qu’à sa tête. Certains clients posent le fichiers et font un chmod derrière : l’enfer. Il y a aussi la puissance des ACL POSIX qui permettent de forcer les droits. Mais là encore, certains clients vous poserons problème.

Enfin, on ne souhaite pas forcément que tous les fichiers soient posés avec l’écriture pour le groupe. On peut souhaiter une meilleure granularité.

D’expérience, j’ai abandonné l’idée du correctif à la source pour me tourner vers un bricolage agissant APRÈS la création du fichier. La solution la plus simple est bien sûr la tâche cron, qui toutes les X minutes fait un chmod -R g+w sur un dossier. Déjà la solution n’est pas immédiate car désynchronisée de la création de fichiers, et elle rajoute une (très) petite charge supplémentaire à votre système.

Je propose une solution à base d’inotify, qui force les droits dès qu’un fichier est créé :

aptitude install inotify-tools

Et la commande magique :

inotifywait -mrq -e CREATE --format %w%f /tmp/mytest/ | while read FILE; do chmod g=u "$FILE"; done

MAJ 2010-10-30 Pour gérer les espaces en fin de fichiers, et les antislashs :

inotifywait -mrq -e CREATE --format %w%f /tmp/mytest/ | while IFS= read -r FILE; do chmod g=u "$FILE"; done

Merci à vitoreiji (commentaires)

La commande inotifywait écoute les événements du dossier /tmp/mytest. Dès qu’un fichier est créé, il est affiché sur la sortie standard. Chaque ligne-fichier est ensuite lue par la boucle while et les droits sont changés. Le g=u donne au groupe les mêmes droits que l’utilisateur (avec g+w, si l’utilisateur pose un fichier rw– ––– –––, les droits deviendraient rw– –w– –––).

Vous pouvez maintenant tester la création/copie de fichiers/dossiers. Même un mkdir -p a/b/c/d/e doit fonctionner.

Pour terminer, on ajoutera tout cela dans un script de démarrage :

vi /usr/local/bin/inotifywait.sh && chmod +x /usr/local/bin/inotifywait.sh
#!/bin/sh
# Take the directory name as argument

inotifywait -mrq -e CREATE --format %w%f "$1" | while read FILE
do
	chmod g=u "$FILE"
done
vi /etc/init.d/inotifywait.sh && chmod +x /etc/init.d/inotifywait.sh
#! /bin/sh

case "$1" in
  start|"")

	rm -f /tmp/inotifywait.log
	/usr/local/bin/inotifywait.sh /path/to/dir/ >/tmp/inotifywait.log 2>&1 &
	
	;;
  restart|reload|force-reload)
	echo "Error: argument '$1' not supported" >&2
	exit 3
	;;
  stop)
	# killall inotifywait ???
	;;
  *)
	echo "Usage: inotifywait.sh [start|stop]" >&2
	exit 3
	;;
esac

:

(sous Debian)

update-rc.d inotifywait.sh defaults

Note : un inconvénient : il y a une limite sur le nombre de fichier surveillés, voir l’option -r dans man inotifywait.

Et enfin la touche finale qui est utile pour que les fichiers créés conservent le groupe du dossier parent : le bit setgid au groupe pour tous les dossiers.

find /path/to/dir -type d -exec chmod g+s {} \;

Liens :

jeudi 10 décembre 2009

[SSH] Changement de répertoire à la connexion

Problème :

Je souhaite créer un alias serveur-www qui me connecte au serveur en SSH et m’amène automatiquement dans le dossier /var/www/.

Voici :

ssh -t serveur 'cd /var/www && $SHELL'

Et pour l’alias qu’on pourra ensuite mettre dans son ~/.bashrc :

alias serveur-www="ssh -t serveur 'cd /var/www && $SHELL'"
serveur-www # pour tester

Références :

jeudi 20 août 2009

Avec quelle adresse IP je sors ?

Pour savoir avec quelle adresse IP on sort sur Internet, on peux aller voir un site du genre http://www.whatismyip.com

En mode texte sans navigateur Web, c’est un peu plus compliqué. On pourra donc utiliser la commande suivante :

wget --user-agent="Mozilla/5.0" -O - http://www.whatismyip.com 2>/dev/null | grep -o "Your IP Address Is: [0-9.]*"

Il faut se faire passer pour un vrai navigateur sinon le site nous refuse.

MAJ 14/01/2010

Pour trouver son adresse IP externe, une méthode encore plus élégante :

dig +short myip.opendns.com @resolver1.opendns.com

MAJ 19/03/2010

D’ailleurs ça marche même plus ma méthode. Préférez donc :

http://dev.petitchevalroux.net/linux/connaitre-son-adresse-externe-linux.305.html

MAJ 06/05/2010

Ou encore mieux !

curl icanhazip.com

http://www.commandlinefu.com/commands/view/2966/return-external-ip

jeudi 2 juillet 2009

Colorer la sortie d'une commande

Voici comment colorer simplement la syntaxe d’une sortie de commande avec vim :

Colorer un diff :

diff -u /tmp/1 /tmp/2 | vim -R -

Colorer un fichier un fichier quelconque (moins d’intérêt, car on peut simplement ouvrir le fichier avec vim)

cat script.sh | vim -R -

dimanche 24 mai 2009

Terminer tous les enfants à la mort du parent

Dans un script Bash, voici la solution la plus simple que j’ai trouvée pour faire en sorte que tous les processus enfants soient tués en même temps que le parent :

# kill every children on exit
trap "kill -- -$$" EXIT

La commande kill -- -PID permet de tuer l’ensemble du groupe de processus identifié par PID. Sachant que dans notre cas, l’ID du groupe de processus est le même que l’ID du processus parent.

Il y aurait aussi peut-être la solution de programmer, dans l’enfant, la commande exit dès que ce dernier reçoit le signal que son parent a changé.

mardi 10 mars 2009

Faire taire le terminal

Assez d’entendre les bips incessants lorsque vous utilisez la complétion dans votre terminal ?

Ajouter la ligne suivante au fichier ~/.bashrc

# desactiver le son de cloche
xset -b

mercredi 4 mars 2009

Augmenter l'historique des commandes bash

Par défault la taille de l’historique bash sous Debian semble être à 500.

Placer la ligne suivante dans son ~/.bashrc :

export HISTFILESIZE=5000

dimanche 4 janvier 2009

Passer une chaîne en majuscule en Shell

Voici comment passer une chaîne en majuscule en ligne de commande :

echo toto | tr '[a-z]' '[A-Z]'

La commande tr est très utile pour effectuer tout remplacement de caractère.

mardi 29 juillet 2008

Des variables variables dans Bash

Dans certains langages, il est possible de faire référence à une variable dont le nom est contenu dans une autre variable.

Ainsi, en PHP :

$toto = 8;
$nomvar = 'toto';
echo $$nomvar;

Affichera 8.

C’est aussi possible en Bash de la manière suivante :

toto=8
nomvar='toto'
echo ${!nomvar}

Source : http://www.seocam.net/how-tos/how-t...

jeudi 19 juin 2008

Commande screen

La commande screen est très pratique pour lancer des scripts lorsqu’on est connecté en SSH, pour que si une coupure de courant ou un problème survient côté client, le shell client ne soit pas tué ainsi que le script.

Pour lancer un script :

$ screen

Pour le détacher, il faut faire Ctrl+A, puis D.

Enfin, pour récupérer un screen :

$ screen -r