Ne pas oublier que pour un service systemd, stdin est /dev/null… sinon on peut passer du temps de debug bizarre au moment où on veut passer un script en service systemd… ici socat, qui y est très sensible puisque c'est son seul taff (de gérer des flux).
Je voulais pouvoir fournir un flux d'informations d'un script shell (bash) à quiconque voudrait le recevoir et jouer avec.
Forcément, on pense à un fifo en premier, mais les write sont bloquants. A priori pas simple le O_NONBLOCK en bash.
Ensuite on pense à des socket UNIX, sauf que c'est celui qui écoute qui la crée, et on ne peut pas écouter à plusieurs.
Ce thread fait un peu le tour. Une proposition parle de détourner UDP pour ça, car en mode datagram les paquets sont envoyés sans connexion, donc peuvent être perdus.
Avec socat c'est très facile (udp-datagram / udp-recv). Et l'envoi n'est effectivement pas bloquant. Par contre si on écoute à plusieurs sur le port, en mode reuseport, on n'a pas de duplication mais un balancing. La duplication s'effectue en mode broadcast (possible sur 127.255.255.255 par exemple).
socat udp-recv:3333,reuseport -
socat - udp-datagram:127.255.255.255:3333,broadcast <<< coucou
Pour renvoyer des flux TCP ailleurs (bounce), on peut utiliser socat facilement (pas besoin de root pour les ports > 1024 ni d'iptables).
Exemple :
socat TCP-LISTEN:4242,fork TCP:machine-destination:3032
C'est une sorte de NAT sur un seul port, et qui évite de devoir monter une session de tunnel SSH.
On en apprend toujours : j'ai bloqué un moment sur du code C, pour comprendre pourquoi mes printf n'apparaissaient pas quand je faisais une redirection dans un fichier, et un tailf dessus…
Forcément c'était une histoire de buffer, forcément un write allait être la solution. Mais je voulais quand même savoir, et effectivement le buffering n'est apparemment pas le même par défaut si on envoie sur de l'interactif (line-buffered) ou un fichier (full buffering) !
La commande "pv" a pas mal d'options. Pour avoir rapidement une idée du nombre de requêtes sur une page web qui se fait par exemple DDoS, on peut construire quelque chose comme :
tailf /var/www/<site>/access.log | grep lapage | pv -l -i 10 -r > /dev/null
On aura le nombre de ligne par seconde, sur les 10 dernières secondes.
Tester simplement si un dossier a été copié, sans tenir compte des owner/dates/etc. donc sans passer par tar :
find /path -type f | sort -u | xargs cat | md5sum
On peut troller sur md5 mais pour ça, ça fait largement le boulot, et si vraiment ça t'amuse, pas compliqué de mettre un sha42sum quelconque :)
Pour appliquer une limite de débit à n'importe quel flux en ligne de commande : pv --rate-limit ! Ici appliqué à dd, mais ça devrait être pareil pour tout (cat, nc, …).
Je ne savais pas que strace avait des catégories de syscall prédéfinies, pratique.
On peut donc avec strace -e trace=network tracer tous les calls en rapport avec le réseau d'un process. Il y a pas mal d'autres catégories comme signal, memory…
J'y aurais pas pensé : pour avoir que la première et la dernière ligne d'un pipe (ou autre), envoyer dans un subshell head et tail. Par exemple pour premier et dernier fichier d'un dossier :
ll dossier | (head -n2 && tail -n1)
(oui c'est head -n2 parce qu'il y a la ligne total débile là, on pourrait la virer en rajoutant une étape de pipe mais c'était juste pour visualiser alors je m'en fiche d'une ligne inutile)
EDIT:
On me souffle ça, c'est probablement mieux :
ll dossier | sed -n '2p;$p'
Une liste de photos et envie de faire un tar avec seulement les dernière ? Au lieu de s'embêter à utiliser une interface graphique et de sélectionner, d'imaginer des solutions à base for et de ln ou autre, il suffit juste d'utiliser cette option : --after-date=date (ou juste -N)
On peut donner un fichier (considéré comme tel si commençant pas '.' ou '/') comme référence, pratique.
Suite à une discussion AFK où on se demandait comment marchaient les shebang (#! au début d'un script), voici un site avec des explications en long, en large et en travers, avec même un historique et un tableau expliquant comment ça se passe pour pleeeein de systèmes et selon les versions.
C'est donc bien au niveau du noyau, au moment de l'exec, quand le noyau détermine le format binaire du fichier. Si le format n'est pas compris (un script sans shebang) c'est le shell qui réagit et essaye de l'interpréter lui-même (car exec* lui aura renvoyé un ENOEXEC).
À noter qu'apparemment le shebang récursif (l'interpréteur est lui-même un script avec shebang) n'est pas très répandu parmi les unix (mais est supporté par Linux), et que en général tous les arguments sont repris tels quels, sans séparation (on aura donc un seul argument côté interpréteur en plus du nom du fichier, quel que soit le shebang).
Le code Linux est ici : https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/fs/binfmt_script.c
Le parcours des différents formats est ici : search_binary_handler() sur http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/exec.c
Petit test (Linux 3.16), un shebang récursif (2 niveaux) fonctionne bien, met bien tous les arguments en un seul. Par contre si le 2e script n'a pas de shebang, il se passe juste rien et le code de retour de bash est 0.
Petit bout de C pour jouer avec la mémoire cache de fichiers.
Apparemment ça se base sur mincore() pour avoir la liste des pages mémoire correspondant à un fichier mmap()é qui sont déjà en cache. Après pour forcer le tout à rester en RAM (exemple 5), il fork, mmap() tous les fichiers puis mlock() dessus et hop.
Le code est configuré pour au maximum des fichiers de 500 Mio, et n'est pas disponible dans Debian (malgré des tentatives apparemment). Et j'ai même l'impression que c'est plutôt bien écrit. :P J'ai testé les différents usages (les exemples), ça juste marche bien.