Linux et son shell : trop fort !
Un shell façon rétro qui simule exactement les premiers moniteurs.
Un shell façon rétro qui simule exactement les premiers moniteurs.
Si jamais vous faites un site Internet, que vous le mettez sur localhost et que vous lancez un navigateur, il se peut que, comme moi, vous ayez envie de voir exactement ce qui se passe.
Dans ce cadre, un « espion » parfait pour cela est wireshark (analyseur de trames réseau).
Après plusieurs minutes, voire heures, vous verrez que quelles que soient vos actions, rien ne se passe.
L’explication est simple : Windows, peu importe sa version, « coupe » les arrivées réseau si elles sont en loopback = sur localhost.
Un grand merci, encore une fois, pour Windows !
Il faut utiliser un outil, RawCap, qui hacke un peu Windows et génère un fichier « .pcap
» compatible avec Wireshark.
En ligne de commande, on peut faire le dump de tout le traffic, y compris le localhost
.
Il vous suffit d’utiliser l’utilitaire tcpdump
, exemple :
$ $ sudo tcpdump -vv -i lo port 8000 tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
Et à partir de là il écoutera sur le port 8000. Lancez Chrome, allez sur localhost:8000
et là vous verrez :
(pour la note, même s’il n’y a pas de serveur, ce qui est le cas ici, il écoute et trace vraiment tout)
17:23:14.100160 IP6 (flowlabel 0x52956, hlim 64, next-header TCP (6) payload length: 40) ip6-localhost.44238 > ip6-localhost.8000: Flags [S], cksum 0x0030 (incorrect -> 0xfe61), seq 1512481496, win 43690, options [mss 65476,sackOK,TS val 3860198845 ecr 0,nop,wscale 7], length 0
17:23:14.100165 IP6 (flowlabel 0xe143c, hlim 64, next-header TCP (6) payload length: 20) ip6-localhost.8000 > ip6-localhost.44238: Flags [R.], cksum 0x001c (incorrect -> 0xe6c0), seq 0, ack 1512481497, win 0, length 0
17:23:14.100189 IP (tos 0x0, ttl 64, id 63584, offset 0, flags [DF], proto TCP (6), length 60)
localhost.43918 > localhost.8000: Flags [S], cksum 0xfe30 (incorrect -> 0x631e), seq 4099830766, win 43690, options [mss 65495,sackOK,TS val 1743693574 ecr 0,nop,wscale 7], length 0
17:23:14.100194 IP (tos 0x0, ttl 64, id 12132, offset 0, flags [DF], proto TCP (6), length 40)
localhost.8000 > localhost.43918: Flags [R.], cksum 0x7eb1 (correct), seq 0, ack 4099830767, win 0, length 0
17:23:14.153839 IP6 (flowlabel 0xc30e0, hlim 64, next-header TCP (6) payload length: 40) ip6-localhost.44242 > ip6-localhost.8000: Flags [S], cksum 0x0030 (incorrect -> 0xaa17), seq 1123880506, win 43690, options [mss 65476,sackOK,TS val 3860198859 ecr 0,nop,wscale 7], length 0
17:23:14.153847 IP6 (flowlabel 0xee9c9, hlim 64, next-header TCP (6) payload length: 20) ip6-localhost.8000 > ip6-localhost.44242: Flags [R.], cksum 0x001c (incorrect -> 0x9284), seq 0, ack 1123880507, win 0, length 0
17:23:14.153884 IP (tos 0x0, ttl 64, id 20755, offset 0, flags [DF], proto TCP (6), length 60)
localhost.43922 > localhost.8000: Flags [S], cksum 0xfe30 (incorrect -> 0x1c4e), seq 3564886671, win 43690, options [mss 65495,sackOK,TS val 1743693588 ecr 0,nop,wscale 7], length 0
17:23:14.153891 IP (tos 0x0, ttl 64, id 12140, offset 0, flags [DF], proto TCP (6), length 40)
localhost.8000 > localhost.43922: Flags [R.], cksum 0x37ef (correct), seq 0, ack 3564886672, win 0, length 0
17:23:19.161265 IP6 (flowlabel 0x606b8, hlim 64, next-header TCP (6) payload length: 40) ip6-localhost.44246 > ip6-localhost.8000: Flags [S], cksum 0x0030 (incorrect -> 0x1e75), seq 983670096, win 43690, options [mss 65476,sackOK,TS val 3860200111 ecr 0,nop,wscale 7], length 0
17:23:19.161281 IP6 (flowlabel 0xe0662, hlim 64, next-header TCP (6) payload length: 20) ip6-localhost.8000 > ip6-localhost.44246: Flags [R.], cksum 0x001c (incorrect -> 0x0bc6), seq 0, ack 983670097, win 0, length 0
17:23:19.161360 IP (tos 0x0, ttl 64, id 18581, offset 0, flags [DF], proto TCP (6), length 60)
localhost.43926 > localhost.8000: Flags [S], cksum 0xfe30 (incorrect -> 0xe872), seq 99211285, win 43690, options [mss 65495,sackOK,TS val 1743694840 ecr 0,nop,wscale 7], length 0
17:23:19.161372 IP (tos 0x0, ttl 64, id 13102, offset 0, flags [DF], proto TCP (6), length 40)
localhost.8000 > localhost.43926: Flags [R.], cksum 0x08f8 (correct), seq 0, ack 99211286, win 0, length 0
Plein de personnes utilisent « calc » sous Windows. C’est bien.
Mais, comme la plupart des outils Windows : Linux c’est 20x moins ergonomique, mais 20x puissant.
Bah comme Linux en général, en fait…
Let me introduce bc
.
C’est le « calc » de Windows, mais en plus laid et en 20 x plus puissant que la calculatrice Windows (déjà dit).
Le seul truc bizarre de bc
c’est qu’il ne fait que des calculs en entier.
En bref : bc -l
et hop tout est en flottant et fonctionne.
To make a long story short: bc -l
and everything is ok.
La vitesse de répétition du clavier est liée non pas au hardware (comme je l’ai cru pendant des années), mais au software, donc au système d’exploitation.
Mon ami Windows (« ami »… vous sentez l’ironie ?), qui est fait principalement pour les personnes qui pensent (à tort) qu’on est plus rapide avec une souris qu’avec un clavier, propose un délai avant de répéter les touches très long, même au minimum, et une vitesse de répétition plutôt lente, pour des personnes comme moi qui aiment aller vite.
Mon vrai ami Linux, lui, permet d’aller extrêmement vite, et c’est génial. Bon ok, il permet d’aller si vite qu’on peut faire des petites blagounettes à son camarade de classe. Alors Ubuntu a eu l’idée complètement débile (et je reste poli) de copier Windows et de limiter la vitesse de répétition, et le délai, à des temps très longs, qui se rapprochent de ceux de Windows.
Pourquoi brider tout cela ? Quel est l’intérêt de limiter sa voiture à 50km/h si elle peut aller à 200km/h (et que les autoroutes ne sont pas limitées !).
La solution : après avoir demandé ici sur stackoverflow, voici la réponse, je vous la mets en français : ouvrez un terminal et copiez-collez ce code :
gsettings set org.gnome.settings-daemon.peripherals.keyboard repeat-interval 20
gsettings set org.gnome.settings-daemon.peripherals.keyboard delay 140
gsettings set org.cinnamon.settings-daemon.peripherals.keyboard repeat-interval 20
gsettings set org.cinnamon.settings-daemon.peripherals.keyboard delay 140
Et voilà. C’est le genre de choses, quand j’ai fini de coder toute la journée, et que je reviens sur Windows pour jouer un peu, qui fait que si je dois faire autre chose que jouer, je me mets à détester Windows et rebooter rien que pour écrire mes mails (au final je reste sur Mint parce que je ne vais pas re-rebooter pour rejouer…).
Commandes « one-line » |
|
Connaître l’architecture de sa machine | dpkg --print-architecture |
Chercher les fichiers qui prennent de la place | ncdu |
Archiver au format :
|
tar -cjf "$(date '+%Y.%m.%d-%Hh%Mm%Ss').x.tar.bz2" htdocs/* |
Archiver au format :
|
tar -czf "$(date '+%Y.%m.%d-%Hh%Mm%Ss').x.tar.gz" htdocs/* |
Redirection de la sortie |
|
stderr vers stdout |
command 2>&1 |
stdout vers un fichier et stderr vers un autre |
command > out > 2>error |
stderr vers stdout (&1) puis stdout vers un fichier |
command >out 2>&1 |
stderr vers stdout (&1) puis stdout ajouter un texte et l’afficher, sans problème de buffering (seule solution trouvée qui fonctionne chez moi) |
echo "bonjour" 2>&1 | awk -W interactive '{ print "Site SokoBan > "$0; fflush(stdout); }' |
Tout rediriger vers un fichier |
Exemple court :echo "test" &> /dev/null
Exemple long : |
Nettoyage de disque |
|
Comment supprimer ses vieux noyaux (= Mint, Ubuntu etc.) Oui c’est aussi simple que ça ! |
sudo purge-old-kernels
|
pip (= pip3) |
|
Mettre tous les packages pour une version spécifique de python (ici 3.7) | sudo -H LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/python3.7 -m pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | sudo -H LD_LIBRARY_PATH=/usr/local/lib xargs -n1 /usr/local/bin/python3.7 -m pip install -U
|
Vider le cache complet des packages puis enchainer une mise à jour des packages |
|
Ignorer pour toujours une mise à jour d’un packet (ex ici, avec Python2.7 qui n’est plus maintenu) |
|
Mettre à jour tous les packages puis arrêter l’ordinateur (c’est le shutdown -h now quej’ai longtemps cherché, sudo halt » et autres ne fonctionnent pas
|
|
copy/paste vim (trailing whitespaces!) |
|
Solution au problème : quand on copie colle sous vim avec la souris et qu’il ajoute plein d’espaces à la fin Note : le -b signifie « CLIPBOARD »c’est ce qui change tout ! |
xsel -b -o | sed 's/[ \t]*$//' | xsel -b
|
Sous Mint : – aller dans les raccourcis claviers ; – ajouter un nouveau personnalisé ; – ce dernier doit lancer un script séparé mais dans un terminal = gnome-terminal -e (sinon le code seul, en direct, ne fonctionne pas) |
gnome-terminal -e /xxx/trim.copy.paste.sh
et dans le fichier
|
https |
|
Regénérer avec acme.sh : | root@inyab2:~# acme.sh --renew -d hqf.fr |
Pour génerer le https, avec création de tous les certificats + mise en place des renouvellements, utiliser certbot : | root@inyab:~/certbot# ./certbot-auto |
Déplacer certbot dans le dossier de letsencrypt pour être plus homogène : | cd /etc/letsencrypt && mv ~/certbot . |
S’il y a des problèmes d’accents, ordre shell pour tout chercher : | grep -r -P '[^\x00-\x7f]' /etc/apache2 /etc/letsencrypt /etc/nginx |
Renouvellement automatique : | cd /etc/letsencrypt/certbot && ./certbot-auto renew |
Si jamais ça ne fonctionne pas, mettre toute la configuration en commentaire, puis demander à générer un certificat : | cd /etc/letsencrypt/certbot && ./certbot-auto --nginx -d www.monsite.com |
Autre option : faire son dossier à la main, s’assurer que nginx peut y accéder (= faire un fichier manuellement et l’ouvrir via le navigateur), et lancer certbot en précisant où déposer les certificats. | cd /etc/letsencrypt/certbot && ./certbot-auto certonly -d www.ergofip.com,ergofip.com,configurateur.ergofip.com -w /web/htdocs/ergofip/htdocs/ergofip/ |
Changer le prompt |
|
J’ai vu plein de choses, de discussions un peu partout, mais celle qui a fonctionné le mieux 100% sans fautes est ici, et je résume dans ce qui suit. | |
Séquence de caractères « non-visibles » = qu’on veut cacher, entourée par \[ et \]
|
\[ code \] |
Dans cette séquence de caractères « non-visibles », ajouter le code d’échappement qui précise qu’on veut mettre une couleur \033[X;YYm , et remplacer :– X par 0 (foncé) ou 1 (= plus clair)– YY par un code couleur
|
\[\033[X;YYm\] |
Black | \[\033[0;30m\] |
Blue | \[\033[0;34m\] |
Brown | \[\033[0;33m\] |
Cyan | \[\033[0;36m\] |
Green | \[\033[0;32m\] |
Purple | \[\033[0;35m\] |
Red | \[\033[0;31m\] |
Finir par « reset à la couleur de base » | \[\033[0m\] |
Exemple de prompt qui affiche toutes les couleurs et qui termine par un reset à la couleur du prompt :export PS1="\[\033[0;30m\]Black\[\033[0;34m\]Blue\[\033[0;33m\]Brown\[\033[0;36m\]Cyan\[\033[0;32m\]Green\[\033[0;35m\]Purple\[\033[0;31m\]Red\[\033[1;30m\]Black\[\033[1;34m\]Blue\[\033[1;33m\]Brown\[\033[1;36m\]Cyan\[\033[1;32m\]Green\[\033[1;35m\]Purple\[\033[1;31m\]Red\[\033[0m\]" |
Déclaration de script |
|
Shebang le meilleur Merci stackoverflow |
#!/usr/bin/env bash |
La calculette version Linux = 10 fois plus puissante, ne pas oublier l'option "l" pour calculer avec des virgules (man bc ) |
bc -l |
Outils de capture d'écran |
|
|
sudo apt-get install scrot sudo apt-get install shutter
|
Note : pour mettre shutter par défaut, lire la documentation ici. |
Notifications scriptées sous gnome |
|
Comment envoyer un message sous gnome (= Mint, Ubuntu etc.) |
#!/bin/bash
|
Toute l’explication est ici, simple et claire, en anglais.
Mais je vais résumer l’idée au cas où vous ne seriez pas forcément tenté de tout lire : lorsque vous installez un jeu, le programme Steam (que j’appellerai dorénavant simplement « Steam » parce que je suis fainéant) va demander au serveur Steam de distribution de contenu le plus proche. Et ça n’est pas forcément toujours le plus proche, ce qui fait que cela risque d’être long, mais surtout, vous serez toujours limité à la vitesse de votre connexion Internet. Ici, l’article explique comment faire la demande de votre Steam en priorité à un serveur Nginx local qui servira de cache : si ce dernier n’a pas le jeu en cache, il va aller faire suivre la demande de manière classique. Bien évidemment, si vous êtes comme moi et que vous possédez plus de 500 jeux sur Steam – oui, 500, certaines personnes croient que je mens… – il vous faudra un disque de plus de un terra pour qu’il garde la plupart des jeux en cache (oui oui, vous voulez quelques exemples de jeux lourds ? Je vous en donne après), mais cela dit à chaque fois que vous voudrez réinstaller un jeu, ou si vous achetez un nouvel ordinateur portable, ou vos amis arrivent avec leur portable chez vous et vous voulez leur faire installer, tester ou éventuellement acheter un jeu sur steam dans tous les cas c’est génial. Lisez l’article ici :
how-to-build-a-local-steam-cache-server
Quelques jeux qu’il est très bon d’avoir en cache :
J’arrête là, on en est déjà à plus de 100Go pour 13 jeux, imaginez pour plus de 500 jeux… ils ne font pas tous plus de 2Go, heureusement !
Allez sur Google et tapez « Linux », vous verrez le résultat de recherche.
Ils en sont arrivés à ce point de peur de Linux qu’ils paient pour les mots clé !
Autre news récente : Le ministère italien de la défense abandonne Microsoft Office pour LibreOffice
Vim : enregistrer une macro est très simple :
q[lettre]
débute l’enregitrement de la macro [lettre]
q
termine l’enregistrement"[lettre]P
fait un paste de l’enregistrement dans le fichier en cours d’éditionDonc moi en pratique :
qa
débute l’enregitrement de la macro a
q
termine l’enregistrement de la macro a
tabe
pour ouvrir un nouvel onglet"aP
pour faire un paste de la macro a
:w mymacro.vim
pour sauver ma macro dans le fichier mymacro.vim
vim -s mymacro.vim [fichier]
http://vimregex.com/#Non-Greedy
<?xml
et </head>
::%s/<?xml \_.\{-\}<\/head>\n//g
</body
et <body>
::%s/<\/body\_.\{-\}<body\_.\{-\}>\n//g
Installer :
Personnellement j’ai crée un dossier que j’ai appelé third_party
.
Ce qui fait que mon arborescence est comme cela :
. ├── locale │ ├── en │ ├── fr │ └── sv ├── produits │ ├── migrations │ └── templatetags ├── pyweb ├── static │ ├── css │ ├── fonts │ ├── images │ ├── js │ └── produits ├── templates │ └── produits └── third_party ├── authomatic_0_1_0 ├── defusedxml-0.4.1 ├── google_appengine_1_9_25 └── python-openid_2_2_5
Dans Facebook il faudra aller dans le coin des développeurs, et créer une application jusqu’à arriver à un écran comme celui-ci :
Même chose pour gmail :
Et enfin la relation dans le code :
Pour terminer : Facebook ne renvoyait pas les emails, lorsqu’on s’authentifiait.
C’est un bogue connu depuis que Facebook a modifié son API très récemment.
La solution est ici : editez votre fichier \authomatic\providers\oauth2.py
.
Allez à la classe Facebook.
Copiez-collez ce code, qui ne change presque rien (je vous laisse chercher) sauf l’URL user_info_url
qui a été modifiée pour la v2.4 : et voilà, il ne vous reste plus qu’à suivre le tutoriel de authomatic avec Django, qui est assez bien fait, et tout devrait fonctionner !
class Facebook(OAuth2): """ Facebook |oauth2| provider. * Dashboard: https://developers.facebook.com/apps * Docs: http://developers.facebook.com/docs/howtos/login/server-side-login/ * API reference: http://developers.facebook.com/docs/reference/api/ * API explorer: http://developers.facebook.com/tools/explorer Supported :class:`.User` properties: * city * country * email * first_name * gender * id * last_name * link * locale * location * name * picture * timezone * username Unsupported :class:`.User` properties: * birth_date * nickname * phone * postal_code """ user_authorization_url = 'https://www.facebook.com/dialog/oauth' access_token_url = 'https://graph.facebook.com/oauth/access_token' # Correction merci à miohtama : # https://github.com/peterhudec/authomatic/issues/112 user_info_url = 'https://graph.facebook.com/me?fields=' \ 'id,email,name,first_name,last_name,address,gender,' \ 'hometown,link,timezone,verified,website,locale,languages' user_info_scope = ['email', 'user_about_me', 'user_birthday', 'user_location']
// Exemple copié collé et adapté sur stackoverflow :
// http://stackoverflow.com/questions/15630770/node-js-check-if-path-is-file-or-directory
// http://stackoverflow.com/questions/7268033/basic-static-file-server-in-nodejs
//
var http = require('http'),
url = require('url'),
fs = require('fs'),
mongoose = require('mongoose'),
fileSystem = require('fs'),
path = require('path');
var mimeTypes = {
"html": "text/html",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"png": "image/png",
"js": "text/javascript",
"css": "text/css"};
var server;
var Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;
var personneSchema = new Schema({
nom: String,
prenom: String
});
var Personne = db.model('Personne', personneSchema);
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
console.log('DB connexion reussie');
server = http.createServer(function (request, response) {
if (request.url=='/personnes') {
console.log("> JSON");
Personne.find({}).select('nom prenom').exec(function (err, p) {
if (err) {
return console.log(err);
}
var retour='[';
for (var i = 0; i < p.length; i++) {
retour+='{'+ p[i].nom+', '+p[i].prenom+'},';
};
retour=retour.substr(0, retour.length-2)+']';
response.writeHead(200, {
'Cache-Control': 'no-cache, must-revalidate',
'Expires': 'Mon, 26 Jul 1997 05:00:00 GMT',
'Content-type': 'application/json'
});
response.end(retour);
});
// Stopper tout traitement :
return;
}
var uri = url.parse(request.url).pathname;
var filename = path.join(process.cwd(), uri);
console.log("> " + filename);
fs.exists(filename, function(exists) {
if ((!exists) || (fs.lstatSync(filename).isDirectory())) {
console.log(">> fichier inexistant : " + filename);
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('404 Not Found\n');
response.end();
// Stopper tout traitement :
return;
}
var mimeType = mimeTypes[path.extname(filename).split(".")[1]];
response.writeHead(200, {'Content-Type':mimeType});
var fileStream = fs.createReadStream(filename);
fileStream.pipe(response);
});
//var p = new Personne({
// nom: 'Pons',
// prenom: 'Olivier'
//});
//p.save(function (err) {
// if (err) {
// return console.log(err);
// }
// var query = Personne.find();
// query.select('nom prenom');
// query.exec(function (err, p) {
// if (err) return console.log(err);
// for (var i = 0; i < p.length; i++) {
// console.log(p[i].nom+' '+p[i].prenom);
// };
// console.log('Nombre total d\'enregistrements : '+p.length);
// });
//})
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");
});