Aller au contenu | Aller au menu | Aller à la recherche

Another Home Page Blog

lundi, septembre 2 2013

obtenir facilement les propriétés d'un fichier avec stat

Généralement, quand on cherche à obtenir les propriétés d'un fichier, on utilise la commande ls, avec l'argument -l, ce qui donne un résultat proche de ceci :

nils@orgrimmar:~$ ls -l /dev/null 
crw-rw-rw- 1 root root 1, 3 août  4 11:21 /dev/null

C'est bien gentil, mais si on ne souhaite avoir comme information que le propriétaire d'un fichier, ça fait beaucoup de choses à filtrer. Filtrer la sortie de ls avec awk n'est pas le truc le plus méchant, mais je trouve que c'est comme utiliser un fusil à pompe pour se débarrasser d'une mouche. On est dans le monde UNIX, là où il y a des programmes qui ne font qu'une seule tâche, mais qui la font bien.

Et l'outil qui fait cela se nomme tout simplement stat, et est disponible sur de nombreux systèmes. Sous RHEL/CentOS, il est inclus dans le paquet coreutils, et il est installé avec le système de base dans NetBSD. Là où c'est par contre un peu moins drôle, c'est que l'implémentation Linux diffère de l'implémentation BSD.

Exemple, sous Linux :

nils@orgrimmar:~$ stat -c %U /dev/null 
root

Et ensuite sous NetBSD :

nils@dev:~$ stat -c %U /dev/null 
stat: unknown option -- c
usage: stat [-FlLnqrsx] [-f format] [-t timefmt] [file ...]

Allez, on recommence avec les bonnes options :

nils@dev:~$ stat -f %Su /dev/null 
root

Ici, j'ai cherché à afficher le nom de l'utilisateur propriétaire du fichier, mais d'autres propriétés sont disponibles, comme le nom du groupe, les UID et GID propriétaires, les droits, la taille, les dates de création et de modification, le nom du fichier... D'ailleurs, lancé sans autre argument que le nom du fichier, stat propose bon nombre d'informations.

lundi, août 26 2013

freeshell : votre accès terminal UNIX sur internet

Je me suis dit que ça serait sympa de vous faire découvrir l'association SDF (pour Super Dimension Fortress) et son projet freeshell : un accès en mode terminal sur une machine UNIX (NetBSD pour être exact). Cet accès, dans certaines conditions, est gratuit. C'est assez chouette, ça existe depuis très longtemps et permet d'apprendre les rudiments d'UNIX sans forcément installer en physique ou en virtuel ce type d'environnement. L'association fait cela à but éducatif et culturel, et est reconnue "non-profit" (oui, c'est une association américaine).

Pour accéder à freeshell, et créer un compte, il suffit de se munir d'un client SSH et de se connecter de la façon suivante :

ssh new@sdf.org

il existe d'autres moyens, qui reposent généralement sur SSH ou telnet, sur la page d'inscription au service.

J'ai indiqué plus haut que sous certaines conditions, ce service est gratuit : il y a en fait différent niveaux de services, selon ce que vous êtes prêts à payer. Une fois le compte et l'accès créé, vous disposez de certains outils, comme :

  • mutt, pop3, imap, icq, twitter, bsflite (aim), irc (sur le réseau SDF) ;
  • games, mud, lynx, gopher, TOPS-20 ;
  • hébergement HTTP statique de type http://yourlogin.sdf.org (d'autres domaines sont possibles) ;
  • traceroute, ping, whois, dig et d'autres.

mais tout ça est dans un shell limité. Si vous consentez à payer une petite somme (historiquement 1 Dollar US), un accès shell "classique" (comprendre : bash, ksh, tcsh, rc ou zsh) vous est alors ouvert, avec bien plus de possibilités, comme le webmail, FTP, SFTP (en entrée, pas en sortie), ou un accès à plus d'outils. Pourquoi le shell limité et pourquoi la somme ? Pour éviter le spam d'une part, et d'autre part car le traitement peut se faire par courrier papier, il suffit d'envoyer un billet de 1 Dollar (ou de 5 Euros) à l'adresse indiquée dans la page d'explication.

Encore plus d'outils et de possibilités sont offertes à qui est prêt à mettre un peu plus la main au portefeuille, et certains services sont facturés au mois, comme par exemple un accès VPN. Le tout est hébergé aux USA, et il existe aussi une version européenne, hébergée en Allemagne : SDFEU. Rien que pour l'accès shell, traceroute, dig, whois et autres lynx, c'est assez pratique je trouve, d'avoir un point "de sortie" ailleurs que dans son pays d'origine. Cela permet par exemple de tester des filtrages (géolocalisation ?). C'est aussi, à mon sens, un moyen de disposer d'un hébergement web (statique) peu coûteux et à taille plus humaine, et à finalité moins commerciale.

lundi, octobre 1 2012

Nombre d'occurrences dans un fichier - remix

Je détaillais dans un billet écrit il y a déjà un sacré bout de temps comment obtenir une sorte de top 10 des adresses IP effectuant le plus de requêtes dans un fichier de log Apache. J'ai décidé de revenir dessus, et de faire quelques déclinaisons de ce one-liner selon les recherches. Attention si vous voulez copier-coller ces exemples, ils ont été réalisés sous NetBSD, et la commande sort n'a pas les mêmes options. Grosso modo pour le moment, j'ai vu que là où on écrit sort -g sous GNU/Linux, il faut écrire sort -n sous NetBSD. J'ai aussi décidé de me limiter à un top 5 dans l'affichage, afin d'éviter un billet trop long.

Revenons donc d'abord sur le one-liner de base, les IP qui font le plus de requêtes, avec à gauche, l'adresse IP, et à droite le nombre de hits :

root@dev:/var/log/httpd# awk '{frequencies[$1]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' < ./access.log | sort -nr -k 2,2 | head -5
81.X.Y.Z    6414
208.F.B.I 1578
178.K.G.B  1301
67.D.S.T  1179
77.C.I.A     1157

Ensuite, effectuons pareil mais sur les URLs visitées, toujours avec le nombre de hits à droite :

root@dev:/var/log/httpd# awk '{frequencies[$7]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' < ./access.log | sort -nr -k 2,2 | head -5
/post/2008/05/17/installation-de-phpmyadmin-sur-CentOS-5        7787
/post/2008/05/24/Installation-de-mod_gnutls-sur-CentOS-5        4010
/post/2008/06/20/Utilisateurs-virtuels-sous-CentOS-5-avec-base-de-donnees-MySQL 1910
/post/2007/11/28/Installation-et-configuration-dun-serveur-dedie-OpenArena-071  1284
/post/2009/11/09/Utilisation-transparente-d-une-passerelle-SSH  1266

Comme il ne s'agit que de modifier le numéro du champ, on peut aussi voir les codes de retour HTTP les plus obtenus :

root@dev:/var/log/httpd# awk '{frequencies[$9]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' < ./access.log | sort -nr -k 2,2 | head -5
200     57019
304     6156
404     1797
500     114
403     20

On peut ensuite aller chercher avec grep les pages causant des erreurs 500 ou 404.

Toujours avec la même facilité (un simple numéro de champ à modifier), on peut afficher les referers qui amènent le plus de hits :

root@dev:/var/log/httpd# awk '{frequencies[$11]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' < ./access.log | sort -nr -k 2,2 | head -5
"-"     44306
"http://blog.anotherhomepage.org/post/2008/05/17/installation-de-phpmyadmin-sur-CentOS-5"       3443
"http://blog.anotherhomepage.org/post/2008/06/20/Utilisateurs-virtuels-sous-CentOS-5-avec-base-de-donnees-MySQL"        686
"http://blog.anotherhomepage.org/post/2009/11/09/Utilisation-transparente-d-une-passerelle-SSH" 552
"http://www.google.fr/search?q=phpmyadmin+centos&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:fr:official&client=firefox-a"   401

On remarque que beaucoup n'ont pas de referer, mais il est probable que ce soient des hits sur le flux RSS. On remarque aussi que j'ai beaucoup de referers de mon propre site, il me suffit de les filtrer si je ne veux pas les afficher. Afin de rendre le traitement plus rapide, je décide de mettre la commande grep en premier dans mon traitement :

root@dev:/var/log/httpd# grep -v "blog.anotherhomepage.org" access.log | awk '{frequencies[$11]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' | sort -nr -k 2,2 | head -5
"-"     44306
"http://www.google.fr/search?q=phpmyadmin+centos&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:fr:official&client=firefox-a"   401
"http://www.google.fr/search?q=centos+phpmyadmin&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:fr:official&client=firefox-a"   166
"http://forum.hardware.fr/hfr/OSAlternatifs/Installation/resolu-centos-phpmyadmin-sujet_70143_1.htm"    121
"http://www.google.fr/" 77

Reprenons notre affichage des URLs les plus visitées, mais cette fois prenons en compte les méthodes (GET, HEAD, POST) et la version du protocole HTTP :

root@dev:/var/log/httpd# awk -F "\"" '{frequencies[$2]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' < ./access.log | sort -nr -k 4| head -5
GET /post/2008/05/17/installation-de-phpmyadmin-sur-CentOS-5 HTTP/1.1   4266
GET /post/2008/05/17/installation-de-phpmyadmin-sur-CentOS-5 HTTP/1.0   3521
GET /post/2008/05/24/Installation-de-mod_gnutls-sur-CentOS-5 HTTP/1.1   2181
GET /post/2008/05/24/Installation-de-mod_gnutls-sur-CentOS-5 HTTP/1.0   1829
GET /post/2008/06/20/Utilisateurs-virtuels-sous-CentOS-5-avec-base-de-donnees-MySQL HTTP/1.0    1193

On note ici l'utilisation de l'option "-F" de awk pour changer le motif du séparateur de champ, ce qui me permet d'avoir des champs avec espace.

Enfin, dernier exemple, trions maintenant les User-Agents :

root@dev:/var/log/httpd# awk -F "\"" '{frequencies[$6]++;} END {for (field in frequencies) printf "%d\t%s\n" , frequencies[field], field;}' < ./access.log | sort -nr | head -5
10539   Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) VoilaBot BETA 1.2 (support.voilabot@orange-ftgroup.com)
6493    Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; SPV M700; OpVer 19.123.2.733) OrangeBot-Mobile 2008.0 (mobilesearch.support@orange-ftgroup.com)
4188    Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)
3269    msnbot/2.0b (+http://search.msn.com/msnbot.htm)
3017    Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

J'ai décidé cette fois-ci d'afficher le nombre d'occurrences à gauche, car le nombre de champs (séparés par un espace) n'est plus fixe dans le cas des User-Agents. Mais au moment d'écrire cette phrase, j'ai de nouveau parcouru la page de manuel de sort et j'ai pu voir qu'il est possible de spécifier le séparateur de champ (option -t). J'ai utilisé le caractère $ pour séparer le nombre d'occurrences du libellé du User-Agent, suivi de 'tr' pour le remplacer par une tabulation :

awk -F "\"" '{frequencies[$6]++;} END {for (field in frequencies) printf "%s$%d\n" , field , frequencies[field];}' < ./access.log | sort -nr -t$ -k 2,2| tr $ "\t" | head -5
Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) VoilaBot BETA 1.2 (support.voilabot@orange-ftgroup.com)  10539
Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; SPV M700; OpVer 19.123.2.733) OrangeBot-Mobile 2008.0 (mobilesearch.support@orange-ftgroup.com)        6493
Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp) 4188
msnbot/2.0b (+http://search.msn.com/msnbot.htm) 3269
Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)        3017

Le choix du caractère de séparateur de champ est discutable, mais il ne change pas qu'après réflexion, l'affichage de la commande précédente me semble plus lisible. Et je pense qu'afficher le nombre d'occurences en permier sera plus lisible dans d'autres cas, comme le referer ou l'URL.

lundi, décembre 5 2011

Couleurs dans le terminal

Pour beaucoup de gens, la vue d'un terminal, en général en texte blanc sur fond noir (mais aussi en noir sur fond blanc ou beige sur certaines distributions), peut s'avérer très peu attrayante. En ce qui me concerne je me suis accommodé et j'ai fini par apprécier le terminal, grâce à quelques modifications cosmétiques apportant de la couleur. Je trouve ainsi mon environnement beaucoup plus lisible.

Le prompt

Dans bash (et probablement dans d'autres shells), il est possible de modifier l'apparence du prompt via la variable d'environnement PS1. Regardons quelle est la valeur de PS1 sur un système CentOS (les simples quotes visent à montrer qu'il y a un espace à la fin) :

[root@orgrimmar ~]# echo "PS1 vaut: '$PS1'"
PS1 vaut: '[\u@\h \W]\$ '

Il est possible d'en modifier l'apparence avec de nombreux paramètres, tels que la couleur, certaines informations. Par exemple, j'ai choisi d'appliquer la personnalisation suivante sur tous mes environnements bash :

nils@arreat:~$ echo "PS1 vaut: '$PS1'"
PS1 vaut: '\[\]\u\[\]@\[\]\h\[\]:\w\[\]\$\[\] '

Ce qui est gênant, c'est que si ma variable d'environnement possède des couleurs, leurs codes ne sont pas affichés mais directement interprétés. En réalité, ma variable PS1 vaut :

# récupartion depuis mon bashrc :
PS1=$'\[\E[01;32m\]\u\[\E[0m\]@\[\E[01;36m\]\h\[\E[0m\]:\w\[\E[01;32m\]\$\[\E[0m\] '

Le nom d'utilisateur et le signe "$" sont verts, tandis que le nom d'hôte est bleu. J'ai réalisé une variante pour l'utilisateur root où le vert est remplacé par du rouge.

Pour essayer, rien de plus simple : il suffit d'exporter la variable d'environnement PS1 avec une nouvelle valeur :

[root@orgrimmar ~]# echo "PS1 vaut: '$PS1'"
PS1 vaut: '[\u@\h \W]\$ '
[root@orgrimmar ~]# PS1=$'\[\E[01;32m\]\u\[\E[0m\]@\[\E[01;36m\]\h\[\E[0m\]:\w\[\E[01;32m\]\$\[\E[0m\] '
root@orgrimmar:~# echo "PS1 vaut: '$PS1'"
PS1 vaut: '\[\]\u\[\]@\[\]\h\[\]:\w\[\]\$\[\] '

Il est possible d'aller plus loin, comme de remplacer \h par \H pour obtenir le nom complet de la machine, d'insérer la date, d'afficher le prompt en gras... Vous trouverez chez Nixcraft les différents codes pour démarrer et stopper une couleur, ainsi que pour la mise en gras.

Si vos expérimentations amènent un résultat peu plaisant, deux possibilités : la première consiste à appliquer de nouveau l'ancienne valeur PS1, si vous avez copié son contenu ailleurs, ou d'aller le chercher par exemple dans /etc/bashrc ; la deuxième consiste tout simplement à fermer puis relancer votre terminal.

Une fois que votre nouveau prompt vous plaît, vous voulez rendre le changement définitif. Il est possible d'éditer son fichier .bashrc, .bash_profile ou .profile pour cela. Si vous souhaitez que ce changement soit effectif pour tous les utilisateurs, il est possible de modifier directement /etc/profile ou /etc/bashrc, mais je ne vous le recommande pas : il est possible de mal éditer le fichier et de supprimer accidentellement des commandes utiles, et donc de mettre en vrac son système.

Pour CentOS/RHEL/Fedora, j'ai pris l'habitude de créer un fichier nommé /etc/profile.d/prompt.sh : en effet, le fichier /etc/profile de ces distributions charge tous les .sh situés dans /etc/profile.d. Il devient donc aisé d'ajouter ou de retirer des personnalisations shell comme des alias, le prompt, et d'autres variables d'environnement qui affecteront tous les utilisateurs.

Pour NetBSD, j'ai choisi de créer un fichier /usr/pkg/etc/bashrc contenant ces personnalisations, et d'ajouter le contenu suivant dans /etc/profile (qui, par défaut, ne contient que des commentaires) :

if [ "${BASH_no}" != "no" ]; then
                 [ -r /usr/pkg/etc/bashrc ] && . /usr/pkg/etc/bashrc
fi

De la couleur dans ls

Selon votre système, cette option peut ne pas être disponible : cela fonctionne avec CentOS 4 et 5, mais pas avec NetBSD. Il s'agit tout simplement d'utiliser l'option --color, qui peut être complétée, par exemple --color=auto ou --color=tty. D'où viennent ces couleurs ? De la variable d'environnement LS_COLORS. On peut donc modifier cette variable pour afficher les couleurs différemment, et consulter la page de manuel de dircolors pour plus de détails.

Grep

La commande grep possède une option --color, parfois activée par défaut dans un alias sur certaines distributions. Elle colore en rouge la chaîne de caractères recherchée, que ce soit sous CentOS ou NetBSD.

Pages de manuel en couleur

most permet de visualiser un texte, comme more ou less. A la différence de ces deux derniers, most affiche les pages de manuel en couleur. Pour cela, vous pouvez utiliser la commande suivante :

PAGER=most man <votrecommande>

Pour que ce soit définitif, exportez la variable d'environnement PAGER=most. Attention toutefois, vérifiez que vous n'avez pas un PAGER=more qui traîne quelque part. Concernant la disponibilité du package, on peut le trouver dans pkgsrc ainsi que dans RPMForge.

Colorer ses fichiers de log

Un outil très pratique pour avoir des fichiers de log en couleurs est ccze. Il m'arrive de l'utiliser de la manière suivante :

tail -f /chemin/vers/mon/log/apache | ccze

Je peux aussi m'en servir sur un fichier qui n'est pas mis à jour en direct, en duo avec less :

ccze -A < monfichierdelog | less -R

Ce petit bijou connaît de nombreux formats de fichiers de log, et les rend du coup plus agréables à lire. C'est disponible dans pkgsrc et dans EPEL

Un top en couleur ?

Htop est une version améliorée de top qui, en plus d'afficher la couleur, affiche les taux d'occupation processeur et mémoire d'une manière un peu graphique. A noter cependant que cet outil est d'abord développé pour Linux, et qu'il faut, sous NetBSD, monter /proc avec l'option linux (celle-ci est cependant différente de la couche de compatibilité binaire linux). Htop est disponible dans pkgsrc et dans EPEL

Coloration syntaxique avec VIm

Vous trouvez vi trop morne et déprimant ? Installez VIm et activez la coloration syntaxique ! Souvent, seul vi est installé. Côté pkgsrc, le package se nomme vim et a pour dépendance vim-share. Côté Red Hat, on installera vim-enhanced (dispo dans les dépôts de base). Une fois ceci fait, ajoutez dans votre répertoire home un fichier .vimrc contenant au moins :

syn on
set nu

Ensuite, éditez un script shell, par exemple. Vous verrez la couleur et les numéros de ligne. Pour ceux qui comme moi on un fond noir ou sombre, on ajoutera la directive suivante à son .vimrc :

set bg=dark

La coloration syntaxique s'adaptera ainsi au fond de votre terminal.

Et voilà ! C'est Noël sur votre shell :-)

lundi, novembre 28 2011

Lancement de GNU Screen en arrière-plan

Les entrailles de GNU Screen (que j'abrègerai en screen par la suite) sont parfois difficiles à comprendre. L'histoire commence ainsi : je possède une machine NetBSD, un peu bruyante, que j'allume le matin au lever et que j'éteins le soir au coucher. J'utilise screen sur cette machine, et j'aimerais, par grosse fénéantise, que ce dernier se lance au démarrage de ma machine, en mode détaché. De la sorte, il ne me reste qu'à lancer un bon vieux screen -r lorsque que je m'y connecte et mon comportement ne change pas d'autres machines allumées 24h/24 : je me connecte, je screen -r et je suis prêt.

Jusque-là rien de bien particulier : un petit tour dans la page de manuel m'apprend que cela est déjà possible :

screen -d -m

Cette commande permet de faire en sorte qu'il démarre en mode détaché, et que c'est justement fait pour un éventuel script de démarrage. En bref, la paix dans le monde, mes amis :-)

Je me précipite donc sur ${EDITOR} et entame l'écriture épique d'un script shell qui va lancer screen en mode détaché sous l'identité de l'utilisateur que je suis, avec le fichier .screenrc qui convient. Le script fonctionne, le script fonctionne au démarrage de la machine (c'est mieux, hein ?), toujours la paix dans le monde, avec les oiseaux qui chantent, nous sommes dans un rêve :-)

Donc, plein d'illusions, je lance la commande screen -r . Et là, c'est le drame : le prompt de mon shell (bash) n'est pas coloré, et n'affiche pas le répertoire courant. Après avoir demandé conseil à mon moteur de recherche favori, je me rend compte que dans ce cas, screen a eu la bonne idée de remplacer la variable d'environnement PS1 (qui définit le prompt) par une valeur autre. D'où vient-elle ? Je ne le savais pas encore. J'ai essayé de redéfinir cette variable dans mon fichier de configuration .screenrc, sans succès. En désespoir de cause, je tente un unset PS1. Victoire ! J'ai mon prompt personnalisé ! je suis joie, bonheur, les oiseaux chantent, la paix dans le monde, tout ça tout ça...

Jusqu'à ce que j'édite un fichier texte. Et là, c'est le drame (à nouveau) : mon éditeur de texte, VIm, dispose d'une fonction de coloration syntaxique que j'active par défaut. C'est trèèèès pratique. J'active aussi la numérotation des lignes. Mais là, pas de couleur. Il s'agit pourtant d'un type de fichier connu. Je tente ma chance avec d'autres programmes disposant d'un affichage coloré, sans succès non plus. Après quelques bidouillages, je me rend compte qu'en changeant la variable d'environnement TERM de screen à xterm-color, j'obtiens à nouveau la couleur. En désespoir de cause j'ajoute export TERM=xterm-color au fichier /usr/pkg/etc/bashrc (ce qui m'évite de copier-coller un .bashrc dans le $HOME de mon utilisateur et de root), je relance le script et là : couleur :-)

Avec le recul de l'écriture de ce billet, je me suis rendu compte que lorsque j'utilise screen -d -m, ce dernier charge mon fichier .profile (qui charge .shrc). Ces deux fichiers m'ont posé problème dans le passé : par exemple .profile contient deux exports qui entrent conflit avec mon bashrc, export EDITOR=vi et export PAGER=more (j'utilise vim et most à la place). J'ai aussi remarqué la ligne suivante dans le fichier .shrc :

export PS1="$(whoami)@$(hostname -s)$ "

Tiens, c'est marrant, c'est exactement le prompt que j'avais lors de mon premier problème... ;-)

Bref, ma solution n'est peut-être pas la plus élégante, mais au moins ça fonctionne. Mais comme on me l'a fait remarquer il y a presque deux mois, sur les systèmes Unix : There Is More Than One Way To Do It (Il y a plus d'une façon de le faire).

- page 1 de 3