Snippets by user Nicolas Perriault
Supprimer les espaces des noms de fichier
Pour supprimer tous les espaces des noms de fichier récursivement :
$ find . -type f -regex ".*\ .*" \
-exec bash -c 'echo "$1";mv "$1" "${1// /-}"' '{}' '{}' \;
(via maboite.org)
Vérifier l'empreinte md5 d'une image ISO
Avec md5sum :
$ md5sum feisty-desktop-i386.iso
Comparer l'empreinte de l'image ISO avec celle du CD gravé :
Trouver le périphérique à vérifier :
$ cat /etc/fstab | grep cdrom
Vérification :
$ md5sum /dev/hdb
Mirrorer un répertoire d'une machine à une autre via SSH
Pour synchroniser un répertoire d'une machine A vers une machine B en passant par SSH (avec preservation des droits) :
$ rsync -avz -e ssh someuser@server1.example.com:/var/www/ /var/www/
Utile également pour migrer une machine vers une autre.
Trouver le nombre de slots mémoires disponibles/occupés sous Linux
Sous linux :
$ dmidecode | grep -i "size"
Ce qui renvoie un truc du genre :
Size: 512 MB Size: 512 MB Size: No Module Installed Size: No Module Installed Size: No Module Installed Size: No Module Installed
Donc là on a 6 slots occupés par deux barrettes de 512Mo.
Hello World !
Hi all, this is just a test :
<?php abstract class HelloWorld { static public function sayIt() { echo 'Hello World !'; } } HelloWorld::sayIt(); ?>
Effacer les fichiers trop volumineux
Find est un outil magnifiquement simple et puissant. Par exemple, pour supprimer tous les fichiers de plus de 500Kb dans le répertoire courant :
$ find . -type f -size +500 | xargs rm
Lancer un script au démarrage sur Ubuntu
Write a script and put it in the /etc/init.d/ directory.
Lets say you called it FOO. You then run :
$ sudo update-rc.d FOO defaults
You also have to make the file you created, FOO, executable, using
$ sudo chmod +x FOO
You can check out :
$ sudo man update-rc.d
... for more information. It is a Debian utility to install scripts.
The option "defaults" puts a link to start FOO in run levels 2, 3, 4 and 5. (and puts a link to stop FOO into 0, 1 and 6.)
Changer le nom d'une machine
En admettant que l'on veuille renommer la machine "anciennom" par "nouveaunom" :
$ sudo hostname nouveaunom
Puis remplacer anciennom par nouveaunom dans les fichiers /etc/hostname et /etc/hosts
Gérer les libellés et tris d'un selectbox avec Propel et les helpers objets Symfony
Pour gérer un joli combobox avec des valeurs textuelles représentatives choisies pour un objet Propel et éventuellement les trier, on peut faire :
<?php echo object_select_tag($produit, 'getTypeProduitId', array ( 'related_class' => 'TypeProduit', 'peer_method' => 'doSelectOrderByCode', )) ?>
ou bien dans un generator.yml
fields:
departement_id:
params: text_method=getNomCode peer_method=doSelectOrderByCode
Installer rails sous Ubuntu Edgy
Une installation manuelle via la dernière version de Gem garantie de posséder la dernière version :
$ sudo apt-get install ruby irb ri rdoc ruby1.8-dev build-essential
$ wget http://rubyforge.org/frs/download.php/16452/rubygems-0.9.1.tgz
$ tar xvfz rubygems-0.9.1.tgz
$ cd rubygems-0.9.1/ && sudo ruby setup.rb
$ sudo gem install rails --include-dependencies
Créer un projet :
$ mkdir ~/www/rails && cd ~/www/rails
$ rails testapp && cd rails testapp
$ script/server
Lancez un navigateur sur http://0.0.0.0:3000/ et c'est bon.
Who committed in this SVN repository?
$ svn log -q | cut -d '|' -f 2 - | sort | uniq
Via Arnaud.
Utiliser un retour charriot dans un remplacement sed
Quand on veut utiliser un retour charriot (\n) dans un remplacement avec sed, on commence généralement par essayer ce genre de truc :
$ echo "one,two,three" | sed "s/,/\n/g"
Mais ça ne fonctionne pas ; il faut donc émuler le retour charriot, ce qui est faisable de cette façon :
$ echo "one,two,three" | sed "s/,/\\`echo -e '\n\r'`/g"
Bannir les cronmails
Si vous utilisez crontab, vous recevez sans doute souvent des emails à l'adresse du propriétaire du compte avec le détail des sorties standards et d'erreurs suite à l'execution des commandes programmées.
Pour éviter ces emails, on peut systématiquement masquer ces sorties lors de l'appel à la ligne, par exemple dans un crontab :
*/10 * * * * ./myprogram 1> /dev/null 2> /dev/null
Récupérer le nombre d'abonnés feedburner
Pour récupérer le nombre d'abonnés à un flux Feedburner, par exemple celui du flux de prendreuncafe.com :
<?php $feedName = 'prendreuncafe'; // identifiant feedburner $xml = @simplexml_load_file(sprintf('https://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=%s&dates=%s,%s', $feedName, date('Y-m-d', strtotime('-2 day')), date('Y-m-d', strtotime('-1 day')))); if (!$xml) throw new RuntimeException('Feed unavailable'); var_dump((int) $xml->feed->entry[0]['circulation']);
Source d'inspiration : Oncle Tom
Générer automatiquement des liens internationnalisés avec symfony 1.2
Par exemple, dans le layout :
<ul> <li><?php echo link_to(__('French'), sprintf('@%s?sf_culture=fr', $r = $sf_context->getRouting()->getCurrentRouteName())) ?></li> <li><?php echo link_to(__('English'), sprintf('@%s?sf_culture=en', $r)) ?></li> </ul>
[Symfony] Effacer partiellement le cache d'une application
Toujours utile depuis un contexte d'application différent de celui visé :
sfToolkit::clearGlob(sfConfig::get('sf_cache_dir').'/frontend/*/all/*/templates/toto.cache');
Gestion des tags en SQL
Un schema classique de gestion de tags :
CREATE TABLE Project ( project_id INT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL, url TEXT NOT NULL, PRIMARY KEY (project_id) ) ENGINE=MyISAM; CREATE TABLE Tags ( tag_id INT UNSIGNED NOT NULL AUTO_INCREMENT, tag_text VARCHAR(50) NOT NULL, PRIMARY KEY (tag_id), INDEX (tag_text) ) ENGINE=MyISAM; CREATE TABLE Tag2Project ( tag INT UNSIGNED NOT NULL, project INT UNSIGNED NOT NULL, PRIMARY KEY (tag, project), INDEX rv_primary (project, tag) ) ENGINE=MyISAM;
Pour récupérer tous les projets taggué php ou mysql :
SELECT p.name FROM Project p INNER JOIN Tag2Project t2p ON p.project_id = t2p.project INNER JOIN Tag t ON t2p.tag = t.tag_id WHERE t.tag_text IN ('mysql', 'php');
Pour récupérer tous les projets taggué php et mysql :
SELECT p.name FROM Project p CROSS JOIN Tag t1 CROSS JOIN Tag t2 INNER JOIN Tag2Project t2p ON p.project_id = t2p.project AND t2p.tag = t1.tag_id INNER JOIN Tag2Project t2p2 ON t2p.project = t2p2.project AND t2p2.tag = t2.tag_id WHERE t1.tag_text = "php" AND t2.tag_text = "mysql";
Tiré et adapté de la présentation Join-fu de Jay Pipes
Cross apps url helper for symfony 1.0
Here's a helper that allow to generate cross apps urls in symfony 1.0
/** * Generates cross-apps urls in symfony 1.0 * * @param string the app we want to go to * @param string the route in the app. Must be valid * @param array the arguments required by the route. Optional * @return string */ function cross_app_url($app, $route, $args = null) { $host = sfContext::getInstance()->getRequest()->getHost() ; $env = sfConfig::get('sf_environment'); $appRoutingFile = SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.$app.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'routing.yml' ; $route = substr($route, 1, strlen($route)) ; if (file_exists($appRoutingFile)) { $yml = sfYaml::load($appRoutingFile) ; $routeUrl = $yml[$route]['url'] ; if ($args) { foreach ($args as $k => $v) { $routeUrl = str_replace(':' . $k, $v, $routeUrl) ; } } if (strrpos($routeUrl, '*') == strlen($routeUrl) - 1) { $routeUrl = substr($routeUrl, 0, strlen($routeUrl) - 2) ; } } return sprintf('http://%s/%s/%s', $host, ($env == 'dev' ? $app . '_dev.php' : ($app != $main_app) ? $app : ''), $routeUrl); }
Adapted from here
Logger compatible Firebug et Opera Console
Une petite fonction qui permet de logguer dans la console de Firebug ou d'Opera, sans déclencher d'erreur si ces derniers sont indisponibles.
function log() { try { console.log.apply(console, arguments); } catch(e) { try { opera.postError.apply(opera, arguments); } catch(e) { } } } log("Voici un objet: %o", {toto: "tata", coucou: true});
Extraire toutes les chaînes d'un fichier binaire
En fait, c'est tout bête (mais qu'est ce que ça peut être utilie !) :
$ strings /usr/bin/iconv
Written by %s.
char
UCS-4
conversion from %s unsupported
conversion to %s unsupported
conversion from %s to %s unsupported
try '%s -l' to get the list of supported encodings
[...]
Convertir un timestamp unix en ligne de commande
C'est bête mais ça peut toujours servir.
$ date -r 1204748227
Wed Mar 5 12:17:07 PST 2008
Créer un patch SVN et l'appliquer
Pour mémoire, voici la méthode pour créer un patch depuis un dépôt subversion et l'appliquer sur un autre checkout de ce même dépôt :
$ cd /path/to/instance/1
$ svn diff /tmp/diff.patch
$ cd /path/to/instance/2
$ patch -p0 -i /tmp/diff.patch
Déplacement récursif SVN avec xargs
Pour déplacer n fichiers php d'un dépôt subversion :
$ find . -name *.php | xargs -I % svn mv "%" trunk/
On notera qu'on peut appliquer le principe pour toute commande dont l'ordre des arguments est exotique.
Lire les mails en texte brut sous OS X avec Mail.app
Ouvrir un terminal et taper :
$ defaults write com.apple.mail PreferPlainText -bool TRUE
Symfony, trier aléatoirement les résultat avec Propel et MySQL
Attention, cela ne fonctionnera probablement qu'avec MySQL :
<?php $c = new criteria; $c->addAscendingOrderByColumn('rand()'); $results = TotoPeer::doSelect($c);
Enbarquer un objet QuickTime en XHTML
Parfois, on a besoin d'inclure une vidéo QuickTime (.MOV) dans une page XHTML :
<!--[if IE]> <object id="ieqt" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="640" height="415"> <param name="src" value="toto.mov"> <param name="autoplay" value="false"/> <param name="controller" value="true"/> <param name="loop" value="false"/> <p><a href="toto.mov">Télécharger la vidéo</a>.</p> </object> <![endif]--> <!--[if !IE]><--> <object id="nonieqt" data="toto.mov" type="video/quicktime" width="640" height="415"> <param name="autoplay" value="false"/> <param name="controller" value="true"/> <param name="loop" value="false"/> <p><a href="toto.mov">Télécharger la vidéo</a>.</p> </object> <!--><![endif]-->
Ajouter la coloration dans le terminal Mac OS X
Pour avoir de belles couleurs au chargement d'une session dans le terminal OS X (ou iTerm), il faut éditer son fichier ~/.profile et y ajouter cette ligne :
export CLICOLOR=true
Et recharger le profil :
$ . ~/.profile
Comparer les différences entre deux répertoires
C'est tout con, mais encore faut-il le savoir :)
$ diff -rq rep1/ rep2/
[Symfony 1.1 beta] Créer un test unitaire et initialiser Propel
Depuis l'apparition du nouveau système de configuration de Symfony 1.1, voici un boostrap type pour vos tests unitaires nécessitant l'accès à l'environnement Propel :
<?php require_once(dirname(__FILE__).'/../../config/ProjectConfiguration.class.php'); $configuration = ProjectConfiguration::getApplicationConfiguration('main', 'test', true); include($configuration->getSymfonyLibDir().'/vendor/lime/lime.php'); sfContext::createInstance($configuration);
Pensez cependant à remplacer main par le nom de votre application courante (par ex. frontend).
[Symfony] Utiliser sqlite pour stocker le cache des templates
D'abord, s'assurer d'avoir le module sqlite de php5 chargé et activé :
$ sudo apt-get install php5-sqlite
$ sudo /etc/init.d/apache2 restart
Dans le fichier factories.yml de l'application concernée :
view_cache:
class: sfSQLiteCache
param:
automaticCleaningFactor: 0
database: %SF_ROOT_DIR%/cache/cache.db
Et voilà, maintenant les symfony cc se feront en un éclair.
[Symfony] Un validateur de date qu'il est bien
Quelques fonctionnalités en plus par rapport à sfDateValidator (qu'il étend), notamment l'interdiction de date futures ou passées et l'évitement du traitement de la langue courante utilisateur (utile pour les formats de date figés).
/** * Custom date validator * */ class myDateValidator extends sfDateValidator { /** * Execute this validator. * * @param mixed A file or parameter value/array * @param error An error message reference * * @return bool true, if this validator executes successfully, otherwise false */ public function execute(&$value, &$error) { $culture = $this->getContext()->getUser()->getCulture(); // Validate the given date if ($this->getParameter('with_culture')) { $value1 = $this->getValidDate($value, $culture); } else { $value1 = strtotime($value); } if (!$value1 || -1 == $value1) // Before php 5.1, strtotime() returns -1 on fail { $error = $this->getParameter('date_error'); return false; } // Is there a compare to do? $compareDateParam = $this->getParameter('compare'); $compareDate = $this->getContext()->getRequest()->getParameter($compareDateParam); // If the compare date is given if ($compareDate) { $operator = trim($this->getParameter('operator', '=='), '\'" '); $value2 = $this->getValidDate($compareDate, $culture); // If the check date is valid, compare it. Otherwise ignore the comparison if ($value2) { $valid = false; switch ($operator) { case '>': $valid = $value1 > $value2; break; case '>=': $valid = $value1 >= $value2; break; case '==': $valid = $value1 == $value2; break; case '<=': $valid = $value1 <= $value2; break; case '<': $valid = $value1 < $value2; break; default: throw new sfValidatorException(sprintf('Invalid date comparison operator "%s"', $operator)); } if (!$valid) { $error = $this->getParameter('compare_error'); return false; } } } if (!$this->getParameter('allow_future') && $value1 > time()) { $error = $this->getParameter('future_error'); return false; } if (!$this->getParameter('allow_past') && $value1 < time()) { $error = $this->getParameter('past_error'); return false; } return true; } /** * Initializes the validator. * * @param sfContext The current application context * @param array An associative array of initialization parameters * * @return bool true, if initialization completes successfully, otherwise false */ public function initialize($context, $parameters = null) { // Initialize parent parent::initialize($context, $parameters); // Set defaults $this->getParameterHolder()->set('with_culture', true); $this->getParameterHolder()->set('allow_future', true); $this->getParameterHolder()->set('future_error', 'Future dates not allowed'); $this->getParameterHolder()->set('allow_past', true); $this->getParameterHolder()->set('past_error', 'Past dates not allowed'); $this->getParameterHolder()->add($parameters); return true; } }
Compiler tous les fichiers PHP en un seul
Pour faire un gros fichier comportant l'intégralité d'un projet par exemple :
$ find . -name "*.php" |xargs php -w > mongrosprojet.php
Export/Import d'une base MySQL utf8
C'est pas facile, mais c'est possible.
I. Exportation de la base :
$ mysqldump -uuser -p --opt --default-character-set=utf8 mabase > mabase.sql
II. Reconversion :
$ iconv -f iso-8859-1 -t utf-8 mabase.sql > mabase_utf8.sql
III. Reimport :
$ mysql -uuser -p mabase < mabase_utf8.sql
[Symfony] [Validator] Valider une valeur en fonction d'une blacklist
Pour s'assurer qu'une valeur saisie par un utilisateur dans un formulaire Symfony ne fait pas partie d'une liste de valeurs interdites, on peut utiliser le validateur suivant :
Fichier sfBlacklistValidator.class.php :
<?php class sfBlacklistValidator extends sfValidator { public function initialize($context, $parameters = null) { // initialize parent parent::initialize($context); // set defaults $this->getParameterHolder()->set('blacklist_error', 'Value is not an allowed one'); $this->getParameterHolder()->set('case_sensitive', false); $this->getParameterHolder()->set('trim', true); $this->getParameterHolder()->add($parameters); return true; } public function execute(&$value, &$error) { // Forbidden names $blacklist = $this->getParameter('blacklist'); $casesensitive = $this->getParameter('case_sensitive'); $trim = $this->getParameter('trim'); if ($trim) { $value = trim($value); } if (is_array($blacklist) && count($blacklist) > 0) { if ($casesensitive) { $match = in_array($value, $blacklist); } else { $match = false; foreach ($blacklist as $item) { if (is_string($item) && strtolower($item) == strtolower($value)) { $match = true; break; } } } if ($match) { $error = $this->getParameterHolder()->get('blacklist_error'); return false; } } return true; } }
Dans un fichier de validation yml:
fields:
myfield:
sfBlacklistValidator:
blacklist: [admin, contact, info, infos, commercial, tech, support, sales, partnership, webmaster, business, owner]
case_sensitive: no
trim: yes
blacklist_error: The username you requested is not available
Les options sont assez explicites, mais en voici tout de même le détail :
- blacklist: tableau de valeurs prohibées au format YAML
- case_sensitive: effectuer les comparaisons en tenant compte de la casse
- trim: inclure les espaces en début et fin de chaînes
- blacklist_error: Message d'erreur à afficher en cas de valeur blacklistée
[Symfony] [Propel] Afficher la dernière requête effectuée
Pour afficher la dernière requête effectuée avec Propel :
echo Propel::getConnection()->getLastExecutedQuery();
C'est tout con, hein ?
Shortest XmlHttpRequest instanciation ever
if (!XMLHttpRequest) { window.XMLHttpRequest = function() { return new ActiveXObject('Microsoft.XMLHTTP'); } }
Formatter un document XML avec DOM et PHP5
Ça peut bien aider.
$dom = new DOMDocument('1.0', 'UTF-8'); $dom->preserveWhiteSpace = false; $dom->load('/path/to/file.xml'); $dom->formatOutput = true; file_put_contents('formatted.xml', $dom->saveXML());
Désactiver le bip système sous Ubuntu
Rien de plus exaspérant que ces bips disgrâcieux à chaque tabulation dans un shell. Pour remédier au problème :
$ echo "set bell-style visible" >> ~/.inputrc
Vim ou Bash figés après un CTRL + S ?
Oui ben ça nous arrive à tous un jour ou l'autre hein :p
Donc si vous aussi vous vous retrouvez avec un Vim ou un Bash figés après avoir connement tenté un Ctrl + S, le meilleur moyen de rétablir la situation est de faire un Ctrl + Q
Rendre l'execution d'un programme insensible aux déconnexions
On peut utiliser l'utilitaire nohup :
$ nohup batch_script.sh
CTRL+Z + bg mettront la tâche en arrière plan.
Lancer eclipse avec la JVM de Sun
GCJ c'est gentil, mais ça rame. Alors Eclipse avec GCJ... :/
Pour y remédier, on peut lancer Eclipse en forçant la JVM (update-alternatives reste sourd aux incantations à ce niveau)
/usr/bin/eclipse -vm /usr/lib/jvm/java-1.5.0-sun/jre/bin/java -vmargs -Xmx256M
On notera aussi la limitation de mémoire vive utilisable ;)
Pour installer la JVM de Sun si elle n'est pa sprésente sur le système :
sudo apt-get install sun-java5-jre
[Symfony] Cacher simplement un fragment de code
Cacher le résultat d'un processus coûteux pour 24h :
<?php if (!cache('huge_process_of_the_death', 86400)): ?> <?php foreach ($stuff as $item): ?> // Your amazingly huge iteration processes here <?php endforeach; ?> <?php cache_save() ?> <?php endif; ?>
Pour le cacher pour un utilisateur spécifique :
<?php if (!cache('huge_process_of_the_death'.md5($user->getEmail()), 86400)): ?> <?php foreach ($stuff as $item): ?> // Your amazingly huge iteration processes here <?php endforeach; ?> <?php cache_save() ?> <?php endif; ?>
On s'assure juste de prendre l'empreinte md5 d'un attribut unique dans la table associée ;)
Mailer un backup mysql comme attachement en ligne de commande
On va utiliser mutt :
$ sudo apt-get install mutt
La commande (cronable) :
$ mysqldump -uroot -p --all-databases --opt \
| bzip2 > /path/to/backup/export.sql.bz2 \
&& echo "En date du " `date` \
| mutt -s "[Nikobox] Backup MySQL total du `date | awk '{ print $2,$3,$4}'`" \
-a /path/to/backup/export.sql.bz2 you@fai.com
Sécuriser /tmp
Beaucoup de script-kiddies s'amusent beaucoup avec le répertoire /tmp, par défaut aisément accessible et donc réceptacle à executables falacieux de tous poils.
Voici une méthode permettant de remplacer ce point de montage par un nouveau, de 40Mo mais dont la particularité sera de ne pas autoriser l'execution de programmes (héhé) :
# create a 40MB block device which will be the /tmp file system cd /root dd if=/dev/zero of=/root/tmpMnt bs=1024 count=40000 mkfs.ext3 -F /root/tmpMnt # mount it at /tmp mv /tmp /tmp.backup mkdir /tmp mount -o loop,noexec,nosuid,rw /root/tmpMnt /tmp chmod 0777 /tmp # make it so it is used on boot up if ! grep -qai tmpMnt /etc/fstab ; then echo "/root/tmpMnt /tmp ext3 loop,noexec,nosuid,rw 0 0" >> /etc/fstab fi # check your syntax is ok mount -a # check that programs in /tmp will not run cp /bin/ls /tmp/ /tmp/ls
Pour remonter /tmp avec droits d'execution :
# umount /tmp # mount -o loop,rw /root/tmpMnt /tmp
Et remonter la partition sans les droits d'execution :
# umount /tmp # mount -o loop,noexec,nosuid,rw /root/tmpMnt /tmp
[Ubuntu] Mailer en ligne de commande
Il faut installer mailx :
$ sudo apt-get install mailx
Un test :
$ echo "Test" | mail monmail@gmail.com -s "Test de mail"
Copier une image ISO depuis un CD-Rom
C'est très simple :
$ dd if=/dev/cdrom of=/home/me/cdrom.iso
[Ubuntu] Intégrer Subversion dans Nautilus
SVN dans Nautilus via un clic droit, c'est possible :
$ sudo apt-get install nautilus-script-collection-svn
$ nautilus-script-manager enable Subversion
Merci glooze ;)
Ajouter automatiquement tous les nouveaux fichiers et dossiers dans un dépôt Subversion
The command line is my friend.
$ svn stat | grep ? | awk '{ print $2 }' | xargs svn add
[Symfony] Chemins systèmes
Voici les chemins systèmes par défaut dans Symfony.
// root directory structure 'sf_cache_dir_name' => 'cache', 'sf_log_dir_name' => 'log', 'sf_lib_dir_name' => 'lib', 'sf_model_dir_name' => 'model', 'sf_web_dir_name' => 'web', 'sf_data_dir_name' => 'data', 'sf_config_dir_name' => 'config', 'sf_apps_dir_name' => 'apps', // global directory structure 'sf_app_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.$sf_app, 'sf_model_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'model', 'sf_lib_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'lib', 'sf_web_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'web', 'sf_upload_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'web'.DIRECTORY_SEPARATOR.'uploads', 'sf_base_cache_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.$sf_app, 'sf_cache_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.$sf_app.DIRECTORY_SEPARATOR.$sf_environment, 'sf_log_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'log', 'sf_data_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'data', 'sf_config_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'config',
Exclure un paquet d'un dist-upgrade
Wajig permet de bloquer un paquet via sa sous-commande hold :
$ sudo apt-get install wajig
$ sudo wajig hold <package_name>
$ sudo apt-get update
$ sudo apt-get dist-upgrade
Ici le paquet <package_name> ne sera pas mis à jour.
Avec aptitude, vous pouvez conserver un paquet en faisant :
$ aptitude hold package_name
et enlever le drapeau « hold » avec
$ aptitude unhold package_name
[IRC] Récupérer un nick
Parfois après une déco, son pseudo est bloqué. On peut le récupérer comme ça :
/ns ghost <nick> <password>
Donner les pouvoirs d'administration système à un utilisateur
En admettant l'existance d'un utilisateur toto :
$ sudo adduser toto admin
L'utilisateur toto sera automatiquement ajouté aux sudoers et pourra donc executer le commande sudo en s'identifiant au moyen de son mot de passe.
[Symfony] Autoloader toutes les classes d'un répertoire particulier
Il est très simple de charger automatiquement toutes les classes PHP définies dans un répertoire avec Symfony :
require_once($sf_symfony_lib_dir.'/util/sfCore.class.php'); sfCore::initSimpleAutoload('/path/to/libs');
[Symfony] Cacher un objet Propel sérialisé
Peut être utile pour les gros objets couteux et utilisés souvent.
$key = md5('myPropelObjectKey'); $cache = new sfProcessCache(); if ($cache->has($key)) { $obj = unserialize($cache->get($key)); } else { $obj = Table::doSelect(); $cache->set($key, serialize($obj)) }
Compter le nombre d'occurence d'un terme dans un répertoire
Dans tous les fichiers de type texte, calcul du nombre d'occurence d'une chaîne de caractère avec grep et wc :
$ grep -r require_once /path/to/scan | wc -l
1454
On peut aussi exclure certaines ressources ou répertoires, avec grep -v :
$ grep -r require_once /path/to/scan | grep -v .svn | wc -l
735
Réduire le coût de performances de require_once
La fonction require_once étant assez coûteuse en PHP, il peut être intéressant de tester l'existence de l'objet que le fichier définit avant de le charger d'emblée :
class_exists('sfCache') or require_once($sf_symfony_lib_dir.'/cache/sfCache.class.php');
[Symfony] Traiter les OR sql avec Propel
Voici comment gérer les "ou" SQL dans Propel :
$criteria = new Criteria(); $criteria->add(TotoPeer::NAME, 'Gérard Bouchard'); $criterion = $criteria->getNewCriterion ( TotoPeer::ID, 5 )->addOr($criteria->getNewCriterion ( TotoPeer::ID, 10 )); $criteria->addAnd($criterion); TotoPeer::doSelect($criteria);
Ceci donnera quelque chose comme :
SELECT * FROM toto WHERE toto.NAME = 'Gérard Bouchard' AND ( toto.ID = 5 OR toto.ID = 10 );
Changer les caractères <CR> en <LF>
Convertir rapidement et simplement les caractères \r en \n :
$ perl -pi -e 's#\r#\n#gs' /path/to/file
Can't start server: Bind on TCP/IP port: Cannot assign requested address
Des fois, MySQL c'est chiant. Merci IRC !
<n1k0> help <n1k0> je dois installer un server mysql5 sur une ubuntu lts server toute fraiche <n1k0> apt-get install mysql-server-5.0 <n1k0> et là c'est le drâme <n1k0> il me sort ...failed or took more than 6s. <n1k0> Please take a look at the syslog. <n1k0> /usr/bin/mysqladmin: connect to server at 'localhost' failed <n1k0> error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)' <n1k0> Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists! <n1k0> dans le syslog, j'ai : <n1k0> [ERROR] Can't start server: Bind on TCP/IP port: Cannot assign requested address <n1k0> netstat, ps et lsof me montrent qu'aucun autre mysql ne tourne <n1k0> j'ai tenté --reinstall --purge, rien n'y fait <Yann2> et si t'essaie de démarrer le serveur? <david`bgk> port utilisé ? <n1k0> j'ai même rebooté la machine (!) <n1k0> port 3306 libre <Yann2> avec sudo /etc/init.d/ ? <n1k0> rien n'y fait <Yann2> meme message d'erreur? <n1k0> ouais <david`bgk> et /var/run/mysqld/mysqld.sock existe ? <n1k0> non justement <n1k0> mais d'ou vient le bleme ?? <worf|work> dans /etc/mysql/my.cnf regarde quel est le bind-adress <worf|work> si y en a un etc... <n1k0> j'ai aussi ^G/usr/bin/mysqladmin: connect to server at 'localhost' failed <[NikO]> j'adore les boulets sur msn, ils m'ajoutent dans leur contact, et ils me font 't'es ki ?' <n1k0> dans le syslog <worf|work> netstat -an | grep 3306 <worf|work> regarde si y a un truc qui listen aussi <n1k0> bind-address : 127.0.0.1 <worf|work> il doit servir qu'en local ce mysql ? <worf|work> ou d'autres machines devront s'y connecter ? <n1k0> rien n'ecoute <n1k0> non c'est du local pur <worf|work> dans ps y a aucun mysqld ? <n1k0> non <worf|work> tapes : safe_mysqld <worf|work> ou mysqld_safe <worf|work> (si ça existe) <n1k0> command not found <n1k0> ah <n1k0> Starting mysqld daemon with databases from /var/lib/mysql <n1k0> mysqld_safe[4716]: started <n1k0> STOPPING server from pid file /var/run/mysqld/mysqld.pid <n1k0> mysqld_safe[4729]: ended <n1k0> gné <worf|work> ls -la /var/lib/mysql <n1k0> total 20532 <n1k0> drwxr-xr-x 3 mysql mysql 4096 2007-01-10 13:35 . <n1k0> drwxr-xr-x 22 root root 4096 2007-01-10 13:21 .. <n1k0> -rw-r--r-- 1 root root 0 2007-01-10 13:21 debian-5.0.flag <n1k0> -rw-rw---- 1 mysql mysql 10485760 2007-01-10 13:35 ibdata1 <n1k0> -rw-rw---- 1 mysql mysql 5242880 2007-01-10 13:35 ib_logfile0 <n1k0> -rw-rw---- 1 mysql mysql 5242880 2007-01-10 13:21 ib_logfile1 <n1k0> drwxr-xr-x 2 mysql root 4096 2007-01-10 13:21 mysql <worf|work> ça m'a l'air pourtant pas mal <n1k0> Le truc qui m'inquiète c'est : <worf|work> chown mysql:mysql /var/lib/mysql <n1k0> http://www.debianforum.de/forum/viewtopic.php?t=59014&sid=f89fc839052a659222b63b77b55572d5 <n1k0> et surtout http://www.linuxforums.org/forum/servers/41668-mysql-problems-_-solved-_.html <n1k0> Genre personne y comprend rien <n1k0> le chown a rien changé <worf|work> dans ton my.cnf vire ton bind-adresse <n1k0> ok <n1k0> ça marche ! <n1k0> bouarf <worf|work> ton interface loopback est pas en bon état :) <n1k0> yep <worf|work> ferme ton 3306 avec un firewall <worf|work> et pi toute façon quand tu fais tes GRANT restreint les ensuite à l'ip de la machine. <Rik24d> david`bgk: je parlais bien évidemment des négo entre apple et les opérateurs <worf|work> ifconfig lo <worf|work> ça dit quoi ? <n1k0> lo Link encap:Local Loopback <n1k0> LOOPBACK MTU:16436 Metric:1 <n1k0> RX packets:0 errors:0 dropped:0 overruns:0 frame:0 <n1k0> TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 <n1k0> collisions:0 txqueuelen:0 <n1k0> RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) <worf|work> c le script réso qui pue <worf|work> ifconfig lo UP <Rik24d> n1k0: http://paste.inertie.org ;) <david`bgk> paste.inertie.org :p <david`bgk> arf <n1k0> Rik24d, flemme + mode panic = excusez moi <neuro`> Quelqu'un qui torche en rewrite rules ici ? <david`bgk> c'est juste que c'est nouveau mais personne l'utilise ;) <n1k0> YEAH <n1k0> merci mille fois worf|work <worf|work> verifie tes scripts de démarrage <n1k0> I owe you a beer, quand tu veux <worf|work> c'est pas normal que lo soit pas UP <worf|work> et ça doit etre ça qui merde, pas mysql <n1k0> yep <n1k0> mais là le truc tourne, je peux installer ma demo <n1k0> je ferai un gros check up cet aprem <n1k0> merci encore <worf|work> de rien
Utiliser la JVM de Sun au lieu de GCJ
Vérifier la présence de la mchine virtuelle Java de Sun :
$ update-java-alternatives -l
java-1.5.0-sun 53 /usr/lib/jvm/java-1.5.0-sun
java-gcj 1041 /usr/lib/jvm/java-gcj
La mettre par défaut :
$ sudo update-java-alternatives -s java-1.5.0-sun
Puis :
$ sudo vi /etc/jvm
Écrire tout en haut du fichier :
/usr/lib/jvm/java-1.5.0-sun
[Edgy] Sources.list bien cool
De quoi subvenir à la plupart des besoins.
# Ubuntu officials deb http://archive.ubuntu.com/ubuntu/ edgy main restricted multiverse universe deb http://archive.ubuntu.com/ubuntu/ edgy-updates main restricted multiverse universe deb http://archive.ubuntu.com/ubuntu/ edgy-backports main restricted universe multiverse deb http://security.ubuntu.com/ubuntu edgy-security main restricted multiverse universe # Ubuntu commercials deb http://archive.canonical.com/ubuntu edgy-commercial main # Beryl deb http://ubuntu.beryl-project.org edgy main # Asher deb http://asher256-repository.tuxfamily.org edgy main dupdate french deb http://asher256-repository.tuxfamily.org ubuntu main dupdate french # Medibuntu deb http://medibuntu.sos-sts.com/repo/ edgy free deb http://medibuntu.sos-sts.com/repo/ edgy non-free # Wine deb http://wine.budgetdedicated.com/apt edgy main # Geany deb http://gauvain.tuxfamily.org/repos edgy contrib
Générer la PHPDoc d'un projet
$ sudo apt-get install php-pear
$ sudo pear install PhpDocumentor
$ phpdoc -d /path/to/project/sources -t /path/to/project/doc
Multiton en PHP5
class Multiton { private $instances = array(); public function getInstance($var1, $var2, $var3) { $uid = md5((string)$var1.(string)$var2.(string)$var3); if (!isset(self::$instances[$uid])) { self::$instances[$uid] = new Multiton($var1, $var2, $var3); } return self::$instances[$uid]; } }
Lire le @#!$% de format mp3 sous Ubuntu Edgy
Après avoir installé la moitié des packages universe ou autres medibuntu, c'était en fait un simple :
$ sudo apt-get install gstreamer0.10-ffmpeg
Now, banshee rocks.
Downgrader un package sous Ubuntu
On peut forcer la version d'un paquet à installer :
$ sudo aptitude install nomdupaquet=1.2.3-version2
Récupérer la taille d'une vidéo en PHP avec ffmpeg
On a besoin de http://ffmpeg-php.sourceforge.net/, puis :
extension_loaded('ffmpeg') or die('ffmpeg extension not loaded'); $ffmpegInstance = new ffmpeg_movie('/path/to/movie.avi'); $ffmpegInstance->getDuration(); // Gets the duration in secs. $ffmpegInstance->getVideoCodec(); // What type of compression/codec used
Redirect HTTP -> HTTPS requests in a VirtualHost
<VirtualHost 100.101.102.103:80> ServerName subdomain.domain.tld DocumentRoot /path/to/docroot <IfModule mod_rewrite.c> RewriteEngine on RewriteLog /var/log/apache2/https_rewrite.log RewriteLogLevel 1 RewriteCond %{SERVER_PORT} !^443$ RewriteCond %{SERVER_NAME} ^subdomain.domain.tld$ RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [L,R] </IfModule> </VirtualHost> <VirtualHost 100.101.102.103:443> ServerName subdomain.domain.tld DocumentRoot /path/to/docroot SSLEngine On SSLCertificateFile /etc/apache2/ssl_conf/myservicename.crt SSLCertificateKeyFile /etc/apache2/ssl_conf/myservicename.key </VirtualHost>
Changer l'éditeur par défaut sous Ubuntu
$ sudo update-alternatives --config editor
Et là, choisir vi :-)
Effacer les lignes vides d'un fichier
$ sed '/^$/d' fichier.txt
Installer DBDesigner4 sur Ubuntu
$ wget -c http://213.115.162.124/external/DBDesigner4/DBDesigner4-0.5.4-0.i586.rpm
$ wget -c http://prdownloads.sourceforge.net/skychart/libborqt-6.9.0-2.i386.rpm?use_mirror=switch
$ sudo alien DBDesigner4-0.5.4-0.i586.rpm
$ sudo alien libborqt-6.9.0-2.i386.rpm
$ sudo dpkg -i dbdesigner4_0.5.4-1_i386.deb
$ sudo dpkg -i libborqt_6.9.0-3_i386.deb
$ sudo ln -sf /usr/lib/DBDesigner4/*.so /usr/lib
Une dernière chose :
http://forums.mysql.com/read.php?113,59885,59926#msg-59926
[Symfony] Executer une requête spécifique (custom query) avec Propel
$con = Propel::getConnection(); $stmt = $con->prepareStatement('SELECT foo, bar FROM baz WHERE name=? AND active=?'); $stmt->setString(1, 'MyName'); $stmt->setString(2, '1'); $rs = $stmt->executeQuery(ResultSet::FETCHMODE_NUM);
Ou encore plus con :
Propel::getConnection()->executeUpdate('SET FOREIGN_KEY_CHECKS=0');
Foreach et les variables passées en référence
Merci Thibs ;)
$arr = array(1, 2, 3, 4); foreach ($arr as &$value) { $value = $value * 2; } print_r($arr); // $arr vaut maintenant array (2, 4, 6, 8)
[Symfony] Utiliser un helper dans une action
sfLoader::loadHelpers(array('First', 'Second'));
Simple !
Lister les process arboressentiels sous nunux
Au choix :
$ pstree
ou :
$ ps afx
Migrer un dépôt Subversion d'une machine à une autre
Sur l'ancienne machine :
$ svnadmin dump /var/lib/subversion/myproject > ~/myproject.svndump
$ scp ~/myproject.svndump new-server:
Sur la nouvelle machine :
$ svnadmin create /var/lib/subversion/myproject
$ svnadmin load /var/lib/subversion/myproject < ~/myproject.svndump
Via http://fashion.hosmoz.net/blog/post/2006/11/09/Migrer-un-depot-subversion
Le pattern Strategy en PHP5
<?php interface IStrategy { function filter( $record ); } class FindAfterStrategy implements IStrategy { private $_name; public function __construct( $name ) { $this->_name = $name; } public function filter( $record ) { return strcmp( $this->_name, $record ) <= 0; } } class RandomStrategy implements IStrategy { public function filter( $record ) { return rand( 0, 1 ) >= 0.5; } } class UserList { private $_list = array(); public function __construct( $names ) { if ( $names != null ) { foreach( $names as $name ) { $this->_list []= $name; } } } public function add( $name ) { $this->_list []= $name; } public function find( $filter ) { $recs = array(); foreach( $this->_list as $user ) { if ( $filter->filter( $user ) ) $recs []= $user; } return $recs; } } $ul = new UserList( array( "Andy", "Jack", "Lori", "Megan" ) ); $f1 = $ul->find( new FindAfterStrategy( "J" ) ); print_r( $f1 ); $f2 = $ul->find( new RandomStrategy() ); print_r( $f2 ); ?>
Le pattern ChainOfCommands en PHP5
<?php interface ICommand { function onCommand( $name, $args ); } class CommandChain { private $_commands = array(); public function addCommand( $cmd ) { $this->_commands []= $cmd; } public function runCommand( $name, $args ) { foreach( $this->_commands as $cmd ) { if ( $cmd->onCommand( $name, $args ) ) return; } } } class UserCommand implements ICommand { public function onCommand( $name, $args ) { if ( $name != 'addUser' ) return false; echo( "UserCommand handling 'addUser'\n" ); return true; } } class MailCommand implements ICommand { public function onCommand( $name, $args ) { if ( $name != 'mail' ) return false; echo( "MailCommand handling 'mail'\n" ); return true; } } $cc = new CommandChain(); $cc->addCommand( new UserCommand() ); $cc->addCommand( new MailCommand() ); $cc->runCommand( 'addUser', null ); $cc->runCommand( 'mail', null ); ?>
Le pattern Observer en PHP5
<?php interface IObserver { function onChanged( $sender, $args ); } interface IObservable { function addObserver( $observer ); } class UserList implements IObservable { private $_observers = array(); public function addCustomer( $name ) { foreach( $this->_observers as $obs ) $obs->onChanged( $this, $name ); } public function addObserver( $observer ) { $this->_observers []= $observer; } } class UserListLogger implements IObserver { public function onChanged( $sender, $args ) { echo( "'$args' added to user list\n" ); } } $ul = new UserList(); $ul->addObserver( new UserListLogger() ); $ul->addCustomer( "Jack" ); ?>
Le pattern Factory en PHP5
<?php interface IUser { function getName(); } class User implements IUser { public static function Load( $id ) { return new User( $id ); } public static function Create( ) { return new User( null ); } public function __construct( $id ) { } public function getName() { return "Jack"; } } $uo = User::Load( 1 ); echo( $uo->getName()."\n" ); ?>
Synchroniser son serveur à l'heure atomique
$ sudo apt-get install ntpdate
$ sudo ntpdate europe.pool.ntp.org
Puis dans un crontab en root :
# m h dom mon dow command 0 0 * * * ntpdate europe.pool.ntp.org
Compter le nombre de fichiers en fonction d'un pattern
$ ls -R /my/path/ | grep -v monpattern | wc -l
Dumper toutes les bases mysql et les réimporter
Dump :
$ mysqldump -uroot -p --all-databases --opt > export.sql
Reimport :
$ mysql -uroot -p < export.sql
Avec compression bz2 :
Export :
$ mysqldump -uroot -p --all-databases --opt | bzip2 > export.sql.bz2
Réimport :
$ bzcat export.sql.bz2 | mysql -uroot -p
Faire un screencast sous Ubuntu Edgy
Pas facile vu que ffmpeg nécessite un patch. Heureusement, y'a un .deb de la version patchée :
$ wget -c http://erunar.co.uk/debs/ubuntu_dapper/ffmpeg-0.4.9-p20051216_i386.deb
$ dpkg -i ffmpeg-0.4.9-p20051216_i386.deb
Pour lancer une capture :
$ ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -vd x11:0,0 -s 1400x1050 ~/Desktop/test.avi
Il faut adapter 1400x1050 à la résolution de l'écran, oeuf corse.
Exporter et réimporter la liste des paquets installés
Genre pour reproduire la config d'un ancien serveur vers un nouveau serveur.
Export :
$ sudo dpkg --get-selections > selections.txt
Réimportation :
$ sudo dpkg --set-selections < selections.txt
Réinstallation des paquets :
$ sudo apt-get dselect-upgrade
[Ubuntu] Installer wifi-radar et network-manager
La gestion native par défaut du wifi sous Ubuntu laisse un poil à désirer, voici quelques outils intéressants pour y pallier :
$ sudo apt-get install wifi-radar network-manager-gnome
Note concernant Network Manager :
Il faut vider les paramètres de configuration des interfaces réseau dans le fichier /etc/network/interfaces et rebooter pour que le logiciel fonctionne correctement.
Installer les pilotes libres ATI sous Edgy
$ sudo apt-get update
$ sudo apt-get install linux-restricted-modules-$(uname -r)
$ sudo apt-get install xorg-driver-fglrx
$ sudo depmod -a
$ sudo aticonfig --initial
$ sudo aticonfig --overlay-type=Xv
À la fin du fichier /etc/X11/xorg.conf :
Section "ServerFlags" Option "AIGLX" "off" EndSection Section "Extensions" Option "Composite" "Disable" EndSection Section "DRI" Mode 0666 EndSection
Puis :
$ sudo shutdown -r now
Pour confirmer que ça marche :
$ fglrxinfo
display: :0.0 screen: 0
OpenGL vendor string: ATI Technologies Inc.
OpenGL renderer string: RADEON 9600 Generic
OpenGL version string: 2.0.6011 (8.28.8)
Singleton en PHP5
Instance unique d'un objet.
<?php class Singleton { private static $_instance ; private function __construct() { } public static function GetInstance() { if (!isset(self::$_instance)) { self::$_instance = new Singleton() ; } return self::$_instance; } } ?>
Obtenir un tableau de caractères depuis une chaîne en PHP4
En php5 on a str_split : http://fr.php.net/manual/fr/function.str-split.php
Et en PHP4 :
$chars = preg_split('#(?<=.)(?=.)#s', $string);
