ping
can resolve .local
domains, but e.g. host
can't, which is annoying when trying to resolve the IP address of a mDNS host from a e.g. script.
Fortunately, there is avahi-resolve
that can do that, and is easy enough to use in scripts.
The reason I needed that was to consolidate a setup where a network scanner provides a mDNS name, but it can't be used in the SANE device path, only the IP works. So, replace the IP field in the call with "$(avahi-resolve --name -4 NAME.local | awk '{print $2}')"
and voila.
It is possible to get an estimation on the health status of the device by checking the parameters
EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A
andEXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B
.
The estimation is given in steps of 10% so a value of 0x01 means that 0% to 10% life time used.
This functionality was introduced in eMMC 5.0.# mmc extcsd read /dev/mmcblk2 | grep EXT_CSD_DEVICE_LIFE_TIME_EST eMMC Life Time Estimation A [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]: 0x01 eMMC Life Time Estimation B [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]: 0x01
It's a bit tricky to find how to get an estimated SSD lifetime for an eMMC board, but here is how to use and read mmc
tool (from mmc-utils) for that.
This is similar to SMART's SSD_Life_Time
, although the value is a bit counterintuitive.
There's a lot of info on the web, but I never can find a complete canonical way of doing this when I need it, so here's mine:
On the source machine, dpkg --get-selections > my-selections
(here, everybody agrees though)
On the target machine:
# apt update
# apt-cache dumpavail | dpkg --merge-avail
# dpkg --clear-selections # that's dangerous if you don't set reasonable selections afterwards!
# dpkg --set-selections < my-selections
# apt-get -u dselect-upgrade
And voila.
‒ Je l’avoue : 99 % de ma haine pour l’AI vient du fait que TOUS les services ont réussi à intégrer ça dans leur roadmap en moins de 6 mois ; mais ça fait 15 ans que « l’accessibilité c’est compliqué, on a pas le temps » 😫
‒ L'accessibilité ne rapporte pas d'argent. La bulle qu'est les nouvelles technos est bien plus lucrative.
So true, et tellement souvent pour le buzz plutôt que comme technologie pour résoudre un problème…
If you're fed up by websites installing absurd shortcuts like e.g. ctrl+k (yes, I'm looking at you, GitHub).
Just set permissions.default.shortcuts
to 2
(3
doesn't seem to work for me) in about:config, and you're finally free.
Disclaimer: I just tested that moments ago, so maybe there's downsides to this, but for now it just felt amazing stopping worrying whether ctrl+k will do what I want or a random useless action.
Got a stubborn capslock, e.g. in a VM?
xdotool key Caps_Lock
or the more convoluted, but that likely doesn't require installing additional software:
python3 -c 'from ctypes import *; X11 = cdll.LoadLibrary("libX11.so.6"); display = X11.XOpenDisplay(None); X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2), c_uint(0)); X11.XCloseDisplay(display)'
Quoting the Bash manual page:
If a compound command or shell function executes in a context where -e is being ignored, none of the commands executed within the compound command or function body will be affected by the -e setting, even if -e is set and a command returns a failure status. If a compound command or shell function sets -e while executing in a context where -e is ignored, that setting will not have any effect until the compound command or the command containing the function call completes.
All this isn't so clear, but it actually means that if a simple command (or a pipeline, etc.) exits with an error code inside a function which the caller checks, that command will not be subject to set -e
.
In practice, it pretty much means that using functions renders set -e
moot:
set -e
foo() {
false # this command returns 1
true
}
foo # that one would fail
foo && echo "No errors!" # would print "No errors!", and pass fine
All this basically means set -e
is untrustworthy when using shell functions to factorize the code. Worse, it gives an impression of safety, where there isn't any.
See also SO answer 37191242 and the bash-bug thread linked there for a "rationale" (can't say I understand why they don't introduce a custom shell option for this, though).
[edit] I was confused about set -E
, so scrapped it. But it's basically unrelated, only affects ERR traps.
When someone states "if you have nothing to hide, you have nothing to fear," this is a pretty good answer:
"I need privacy, not because my actions are questionable, but because your judgement and intentions are."
Source: https://libreddit.mha.fi/r/privacy/comments/fvocq2/i_need_privacy_not_because_my_actions_are/
To import the environment of another process, one can use while read -d '' -r ev; do export "$ev"; done <"/proc/$(pgrep -u "$USER" -x PROCNAME)/environ"
(when using bash).
This is particularly handy e.g. when connecting to a machine through SSH while a graphical session is running and wanting to interact with it (X, DBus, etc.).
This leverages some Bash specifics, like read -d ''
to use NUL as the line separator. There are solutions only using POSIX constructs, but the only I know involves a temporary file, which is not as handy. Before discovering read -d ''
I was using another Bashism: process substitution, in the form of <(tr '\0' '\n' </proc/$(pgrep -u "$USER" -x PROCNAME)
. It isn't as good as it would not properly handle newlines in the environment, though, but it could easily be converted to a POSIX-compliant construct using a temporary file. Note that the naive alternative of piping the same thing to the while loop (and thus to read
) will not work as it would run the loop in a subshell, not affecting the environment of the current shell. Another alternative would be to evaluate the output of such a subshell that would echo it, but that would require escaping the values, to which I don't know a robust POSIX solution (there are plenty of handmade ones around, but most fail in odd corner cases -- and no, printf %q
is not in POSIX).
Imaginons une base de donnée qui contient des données dans un encodage différent de celui de stockage… c'est le bordel.
Dans mon cas, j'avais une colonne (enfin, plus d'une…) en utf8, qui contenait la représentation latin1 d'une donnée utf8. #brainfuck.
À priori, je me suis retrouvé avec ça en forçant une communication utf8 à une BDD latin1 qui avait des colonnes utf8. J'imagine donc que naturellement mes données étaient interprétées en latin1 à l'arrivée, et converties en utf8 pour remplir la colonne. Je me retrouve donc avec ce bousin de double encodage.
Bref, je m'en sors avec une version alambiquée des idées de cette page :
UPDATE mytable SET mycolumn = CONVERT(CAST(CONVERT(mycolumn USING latin1) as BINARY) USING utf8);
La partie magique est bien sûr le CONVERT(CAST(CONVERT(mycolumn USING latin1) as BINARY) USING utf8)
: on demande une conversion de la valeur en latin1, puis on force une interprétation binaire pour oublier toute notion d'encodage, et on convertit le binaire en utf8. Le résultat est la suppression du "surencodage" latin1 au milieu. Mais évidemment ça ne marche qu'avec des données représentables en latin1 j'imagine, mais je ne sais même pas si avec mon setup j'aurais pu enregistrer des données incompatibles… je préfère ne pas y penser.
[edit]
Si on souhaite voir les lignes qui seraient affectées, ont peut utiliser SELECT mycolumn FROM mytable WHERE mycolumn <> CONVERT(CAST(CONVERT(mycolumn USING latin1) as BINARY) USING utf8);
: on sélectionne les lignes pour lesquelles la conversion a un effet.
PS : je suis une quiche en SQL (preuve en est la situation dans laquelle je me suis mis…), donc il y a peut-être d'autres solutions meilleures, une solution pour ne pas avoir à répéter le nom de colonne 2 à 3 fois (ce qui augmente fortement le risque de typo quand on fait ça à la main), etc.
:D
Morts du Covid-19 en France: L'équivalent d'un avion de ligne qui s'écrase PAR JOUR.
Ce n'est pas lui qui a inventé cette comparaison à sensation, mais elle reste toujours aussi pourrie. Cette piqûre de rappel me donne envie de m'énerver ici.
Bref, quel est le rapport entre le nombre de morts d'un virus et le nombre de morts d'un crash aérien ? Aucun, mais le crash aérien fait sensation. Même si au final la majorité des avions de ligne transportent au maximum quelques 200 passagers (pour quelques 300 morts du COVID à priori¹).
Au passage, si j'en crois les stats de l'INSEE, on a quelques 2000 morts par jour, un peu moins de 100 de plus qu'en 2019 sur la même période. Les quelques 300 morts du COVID représentent donc ~15% des morts. Au passage, on notera qu'en 2020, l'INSEE donne une moyenne inférieure à 2019 de quelques 150 morts, juste pour rire un peu (encore ici, le diable est probablement dans les détails de ce que cachent ces chiffres bruts de décoffrage par un avion de ligne).
Bref, on fait toujours dire aux données ce qu'on veut, et quand ça suffit pas on rajoute du sensationnel. Rien de nouveau, mais ça reste à gerber.
D'autant plus que je ne vois pas ce que ça rajoute : les chiffres eux-mêmes me parlent plus que le crash d'un hypothétique avion rempli de chatons arc-en-ciel, et ce sans me donner envie de trucider l'auteur de l'article.
--
¹ Non, je n'ai pas cherché plus loin, et je n'ai pas spécialement envie de le faire pour cet article. Ça correspond à la louche mouillée à la jauge d'un avion de ligne moyen (et même plus), donc ça ne jure pas avec le propos que j'assassine. Et mon propos n'est pas axé sur les nombres, ce qui est justement ce qui m'emmerde.
Si votre compte PayPal est inactif pendant au moins 12 mois consécutifs, nous pouvons facturer des frais d'inactivité annuels. "Inactif" signifie que vous ne vous êtes pas connecté à votre compte PayPal ou que vous n'avez pas utilisé votre compte PayPal pour envoyer, recevoir ou virer de l'argent.
[…]
A3.13 Compte PayPal inactif
Les frais d'inactivité seront inférieurs au montant indiqué ci-dessous ou au solde restant sur votre compte.
Euro :12,00 EUR
Rien que ça. Bon, ça ne semble que s'appliquer pour les utilisateurs ayant un solde sur leur compte PayPal, mais quand-même. Des frais par ce que tu ne fais rien – et que tu ne coûte rien du coup, me faites pas rire à prétendre que quelques entrées dans une BDD a une incidence sur leur commerce.
Et même si c'est bien mentionné sur leur récapitulatif de mise à jour des conditions envoyé par mail, ça l'est de façon… très pudique :
Autres modalités juridiques – Nos droits – Frais d'inactivité
Nous introduisons des frais d'inactivité pour les comptes qui restent inactifs pendant au moins 12 mois consécutifs.
Via https://sebsauvage.net/links/?5goOXg
Edit : johndescs m'apprend qu'en France la loi autorise les banques à facturer des frais jusqu'à 30€ pour les comptes hors épargne réglementée (comme par exemple un simple compte courant)… youpi.
Un billet (de mon « Directeur ») contre la proposition présidentielle contre l'IEF, feat vous-voyez-qui (je ne le savais pas, il m'en a fait part ce matin) :]
Sinon, le contexte et pourri : PPL anti-IEF, #3 (?). Enfin je ne sais pas encore où ça en est, c'est peut-être encore des propos en l'air pour faire du buzz présidentiel, mais ça reste pourri, ineffectif (à priori les chiffres seraient maintenant de 8% de suspicions de raisons religieuses dans les enfants IEF en 2020), réducteur et oublieux même des situations où l'école républicaine est juste absente (écoles qui ferment par ce que villages trop petits, etc.). V3. Pour rappel, on a eu la même en 2014 et 2016… mais là ça a pour lui le buzz présidentiel en plus.
Même si les explications liées ici sont un peu approximatives à priori, ça n'en reste pas moins mon problème et la solution : active le memory remapping.
Donc j'ai récemment upgradé un ordi avec une ASUS P5B d'occasion car la CM précédente n'avait que 2 solts DDR2 plus un problème (de contrôleur mémoire ?) si plus de 3Go étaient installés (OS instable + erreurs memtest). À y repenser en écrivant ça, peut-être aurais-je dû jouer avec les voltages si jamais l'option existe ? Je n'y connais pas des masses.
Mais bref, j'ai donc une P5B, tout marche bien, sauf que j'installe 5Go de RAM (2×2 + 1×1) mais le BIOS et Linux n'en voient que 4Go. Oui, 4, y'en a un qui a disparu. Je sais que mes barrettes sont bonnes, je les ai toutes testées séparément. On notera ici que j'ai bien 4Go, pas seulement les 3 l'adressage en dessous des 3Go. Et si j'en met 6 (je n'avais juste pas la barrette sous la main au premier montage, maintenant je suis à 2×2 + 2×1), je n'en vois que 5.
Bref, il semble que sans le memory remapping, le BIOS cache le 4ème Go. Si je comprends bien, c'est normal pour éviter des conflits d'adresse avec les périphériques PCI, même si pour le moment je ne me suis pas documenté plus avant et ça reste donc un peu vague dans mon esprit.
Mais bref, en résumé, activer le remapping découvre la plage du 4ème Go, quelle que soit la quantité de RAM effectivement installée.
If using the SP Flash Tool on your favorite desktop GNU/Linux distro you're experiencing upload failures, like if the communication was broken a few seconds after it started, it's probably ModemManager's fault.
SP Flash Tool is communicating with the smartphones using a USB-modem-like technique (involving cdc_acm
), and doing so leads to ModemManager to think it has to do its thing, actually interfering with the communication, leading to errors like that:
cdc_acm 1-1.2:1.1: failed to set dtr/rts
Fixing this is trivial: just disable ModemManager while using SP Flash Tool, and you should be good to go.
Cet abus des caractères Unicodes « esthétiques » est une très mauvaise chose, car toute sémantique disparaît de ce genre de « textes », ce qui a (entre autres) pour conséquence de rendre ces « textes » inaccessibles (illisibles par les utilisateurs de synthèses vocales, par exemple).
Avant toute chose, il faut que les données soient sémantiques, sinon elles ne veulent plus rien dire ; si les utilisateurs souhaitent réellement ce genre d'apparence (qui est discutable à mon avis, mais soit), il faut que la plate-forme propose ça de façon sémantique (dans ce cas, permettre de choisir la police).
Comme le dit Unicode lui-même : « To be used for mathematical variables where style variations are important semantically. For general text, use standard Latin and Greek letters with markup. »
- https://ban.netlib.re/shaarli/?do=rss . IPv6 capricieuse (ne fonctionnait pas en début d'aprem, fonctionne depuis le milieu d'aprem).
Hum, en fait ma v6 était cassée depuis une migration de mon « hébergeur » (wink wink à l'intéressé) et j'avais pas mis à jour ma zone. Maintenant c'est fait, ça devrait marcher. Par contre, je ne comprend pas comment tu pourrais avoir revu ma v6 fonctionner, elle était juste obsolète depuis un moment…
C'est vrai, mais il y a une limite à ce raisonnement : pour qu'un gus prenne sur lui l'étude d'un autre logiciel (libre ou pas, ce n'est pas mon sujet), il faut que celui-ci soit techniquement ou qualitativement supérieur à la norme. Or, winwin versus nux ou MS Office versus LibreOffice, y'a pas de différence quand t'es une secrétaire. Les deux vont faire chier (si, nux peut faire chier), les deux permettent de saisir le courrier demandé par le boss, sur les fonctions de base, GIMP apporte rien par rapport à Photoshop (et inversement), etc. C'est juste une guéguerre de chapelles (genre en vrai winwin, quand t'as compris la logique, que tu t'es formé, que t'as les bons outils d'administration et les bonnes pratiques, ça juste fonctionne aussi bien que nux, faut arrêter de mentir). Donc quand tu vois l'ordi comme un simple outil pour faire le taff demandé afin de toucher ton salaire, t'en a rien à faire d'une alternative tant que ça t'apporte rien, que ça ne te simplifie pas la vie, que ça ne te permet pas d'aller plus vite (et même, si le boss s'en rend compte et qu'il te file plus de taff, t'as rien gagné, donc, parfois, faut pas chercher à optimiser son temps), etc.
On est d'accord, l'ordinateur, le logiciel, ce sont des outils, et tant qu'ils font ce qu'on leur demande, pourquoi en changer ? Et même si j'ai pris le chapeau melon du libriste évangéliste pour rebondir sur ta remarque, ce n'est (plus) mon cas, et je n'ai plus l'énergie à mettre dans ce débat avec des gens désintéressés, que je ferais d'ailleurs probablement plus chier qu'autre chose.
Je voulais juste souligner que l'homme est une créature aux habitudes tenaces. Même une solution "techniquement ou qualitativement supérieur" sera souvent ignorée car demandera une réadaptation ; il faut donc que cette solution apporte vraiment quelque chose de tangible à l'utilisateur, et que l'utilisateur s'en rende compte pour qu'il décide de faire l'effort de s'adapter.
Et même si c'est un trait humain des fois déplorable, il a de très bonnes raisons d'être également, et je le vois (parfois à regret) sur moi aussi : je n'apprend pas à utiliser certains outils qui je sais me simplifierait certaines tâches, car je pense que le facteur "temps perdu avec ma technique actuelle"/"temps d'apprentissage de la solution" est trop bas pour moi -- souvent par ce que ce sont des tâches relativement rares. En résumé, des fois le pragmatisme de "juste arriver au résultat" gagne sur "choisir l'outil techniquement et qualitativement supérieur".
En gros, si je devais faire plus court : je ne blâme pas le salarié lambda, il a raison de ne pas se poser de questions, car, dans l'écrasante majorité des cas, ça lui apportera aucun avantage. C'est mon point de divergence avec toi.
En fait on ne diverge pas vraiment, moi non-plus je ne blâme pas cette personne. Je ne blâme pas grand monde en fait, les outils qu'ils choisissent restent leur problème. Ça me gène un peu plus quand on impose un outil privateur, voir pire, qu'on oblige à signer des CDG douteuses, ce qui arrive de plus en plus (et même moi j'en signe plus que de raison, soyons réaliste), mais je m'éloigne pas mal du sujet.
- "Faire du graphisme / de la retouche avec GIMP ?! Vous êtes sérieux ?! Vous avez déjà essayé, au moins ?! Faites pas chier, je veux mon Mac, mon Illustrator et mon Photoshop. Laissez-moi exercer mon métier !".
Bref, arrêtons d'utiliser nos arguments d'informaticiens (libre = pas sûr, pas pro, gnagna), le débat avec les utilisateurs n'est pas du tout sur ce terrain. On est sur de l'affect (comme la deuxième personne sus-citée qui se sentait clairement dévalorisée de ne pas avoir de MS Office : pour elle, le prix qu'on met dans son environnement de travail est un indicateur de l'attention qu'on lui prête, et quand t'es payée que dalle sans possibilité d'évolution, je comprend qu'on se rattache à ce genre de choses), sur un effet de réseau / marketing (premier point), et sur un manque d'alternatives crédibles sur certains métiers couplé à un melon des libristes qui sont convaincus que leur solution fait le taff sans connaître celui de la personne à laquelle ils proposent une alternative trop-trop meilleure.
Je vais faire mon libriste au melon démesuré, mais pour ce dernier point je pense que tu ne couvre pas l'ensemble du problème qui est aussi en grande partie que les "alternatives" libres ne sont pas le même logiciel, et ne s'uitlisent pas pareil. Au final la qualité de l'outil n'a que peu de rapport avec la question, la question est beaucoup que la personne est là pour faire son taf, pas pour prendre en main quelque chose de nouveau.
J'ai envie d'inventer un exemple : va proposer à un gars d'un studio d'animation qui utilise un autre outil de passer au logiciel 3D Blender, pourtant reconnu par de nombreux "pros" comme excellent (pour certaines tâches à minima) voir meilleur que les alternatives non-libres. Il n'aura très probablement ni le temps ni l'énergie d'apprendre ce nouvel outil, sauf s'il est lui-même intéressé et prend sur son temps perso.
Au final, c'est presque l'histoire du gars qui essaie d'attraper des poissons avec ses mains et qui n'a pas le temps d'apprendre à utiliser un filet par ce qu'il doit attraper des poissons (oui, c'est une caricature, et elle biaise mon propos :)
Il y a des choses intéressantes, mais il manque ce qui me semble le plus important pour toute idée de défensivité en (Ba)SH : le quoting. Il faut grosso modo quoter toutes les variables, sauf cas particuliers. Par exemple, le snippet tout simple utilisé pour obtenir PROGNAME
a un comportement probablement inattendu si $0 contient des espaces :
# avec un script "/tmp/foo bar.bash" :
$ bash foo\ bar.bash
foo
# avec un script "/tmp/a b c d.bash" :
$ bash a\ b\ c\ d.bash
basename: extra operand ‘c’
Try 'basename --help' for more information.
# ouch.
Tout ça est dû au fait que sans quoting, l'expansion des variables est sujette au découpage de mots et l'expansion des chemins (pour le fun, essayer avec un script nommé *
), ce qui est en général (très) dangereux. La solution est simple : quoter toutes les subsitutions (ce qui inclus $()
), et par exemple le PROGNAME
devient readonly PROGNAME=$(basename "$0")
. On note ici la seule exception : l'assignation à une variable, qu'il n'est pas nécessaire de quoter, mais je recommanderais de toujours quoter, même ça, par ce que ça protège par exemple d'une erreur de refactoring.
Aussi comme le mentionne Sky dans son commentaire (au milieu du reste), utiliser set -e
(avorter le script si une commande dont le retour n'est pas vérifié échoue) est une excellente pratique qui évite une cascade de problèmes lorsque une commande échoue de façon inattendue, que je recommande fortement pour tout nouveau script.
À noter cependant que ça ne marche pas dans tous les cas qu'on pourrait attendre, par exemple foo=$(false)
ne terminera pas le script (car la commande est considérée comme vérifiée). J'ai l'habitude d'avoir une fonction du style die() { echo "$@">&2 ; exit 1; }
et de vérifier également ce type d'assignation en utilisant foo=$(false) || die "failed to do something"
.
Je ne vois même pas comment on peut imaginer qu'une telle application soit pertinente, du moins si on ne dispose pas de moyen d'identification des cas efficaces, rapides et en grande quantité (les fameux tests) : l'application elle-même ne pourra qu'émettre des suppositions puisqu'elle n'a pas accès à des données fiables, mais peut au mieux détecter des situations à risque. On a deux possibilité : soit l'application est très encline à reporter des cas et on obtiendra obligatoirement une énorme quantité de faux-positifs (gens non-contaminés avertis), soit l'application est conservative et risque de créer de nombreux faux-négatifs (gens contaminés non avertis). Si on a beaucoup de faux-positifs, il faut pouvoir aisément et efficacement tester ces cas, et on risque dans tous les cas de créer un sentiment d'inefficacité et donc une baisse de l'utilisation. Si on a beaucoup de faux-négatifs, ça ne sert pas à grand chose, voire crée un faux sentiment de sécurité et un relâchement.
J'ajouterai que l'idée même d'une "appli" pour ce genre de situation me semble être un effet de mode, qu'on cherche à rendre l'informatique magique, la solution à tous les problèmes. Oui, l'informatique peut aider à traiter des données, mais non, elle ne peut pas les générer de nulle part. Je n'arrive pas à savoir si le gouvernement pense qu'ils sont obligés de proposer un outil informatique pour plaire aux citoyens, ou si eux-même croient au miracle de l'informatique et qu'aucun "expert" n'a noyé leurs illusions.
Via je ne sais plus qui… j'avais Guigui en tête mais je ne retrouve pas, donc allez savoir.
Aussi sur le même sujet (toute la forme ne me parle pas, mais grosso je suis d'accord) : https://grisebouille.net/stopconneries/ (via https://sebsauvage.net/links/?J9rs8A)
In Git 2.9, you can now ask it to filter the diffs [interactive staging] shows through any script you like:
$ git config interactive.diffFilter diff-highlight
When you change a swap partition (let's say you removed and added a new one because you wanted to change paritions layout on a non-LVM setup, and swap contents is not something to bother keeping), you'll have to update /etc/fstab; but that's not actually enough. With only this, initramfs will wait for a bit and complain that the resume partition couldn't be found. This is due to the setting in /etc/initramfs-tools/conf.d/resume which should match your preferred swap partition. Once updated, don't forget to re-run update-initramfs -u -k all
.
$ dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -n
Points intéressants sur des corner-cases de NULL qui peuvent se révéler problématiques.
Pour ceux qui utilisent Adwaita sans compositing avec les versions récentes de GTK, il y a des bordures moches et larges autour des fenêtres. Meh. Bon moi j'ai mis un certain temps à essayer de faire quelque chose, par ce que bon, ça m'empêche pas non-plus de vivre. Mais c'est pas beau. Et ça bouffe de la place pour rien. J'ai découvert que c'était les ombres des "Client Side Decorations". C'était pas un bug, donc j'ai pas cherche beaucoup plus loin. Et aujourd'hui, je me suis bougé les miches pour ajouter le petit bout de CSS qui va bien et enlever ça.
Donc, dans ~/.config/gtk-3.0/gtk.css, ajouter :
/* remove window shadows & the extra border */
decoration,
decoration:backdrop,
messagedialog.csd decoration,
.solid-csd decoration,
.solid-csd decoration:backdrop {
box-shadow: none;
}
.solid-csd decoration {
padding: 0;
}
Très pratique quand pour accéder à un host on doit rebondir sur un autre.
La solution naïve est bien sûr ssh host1 -t 'ssh host2'
, mais il y a plusieurs problèmes :
ssh unalias
-t
pour un shell interactifLa solution via ProxyCommand est beaucoup mieux, puisque ça donne un proxy au SSH local lui-même, donc pas besoin de -t
explicite, et pas besoin de forwarder l'agent (ça se passe normalement à travers le tunnel ainsi créé).
<edit> De plus, comme c'est une configuration au niveau de SSH, tout ce qui l'utilise en profite : scp, rsync, etc. </edit>
<edit2> Ajout de la version avec ssh -W
à la place de nc
</edit2>
J'en arrive personnellement à ça (avec les hosts renommés)
# jump to server2 through server1
Host server2
ProxyCommand ssh -W %h:%p %r@server1
# ou alternativement avec `nc` si ssh est trop vieux pour connaître -W
#ProxyCommand ssh %r@server1 nc %h %p
Bien sûr ça se combine avec un alias local facilement :
# jump to server2 through server1
Host localalias
Hostname server2
ProxyCommand ssh -W %h:%p %r@server1
À noter que le lookup de server2 a lieu sur le proxy, donc un nom local au proxy marchera -- mais pas l'inverse, un alias local sur le client ne résoudra pas.
Aussi, puisque la commande proxy est un SSH, on peut lui passer toute option SSH (dans mon cas, -4
par ce que le lien IPv6 entre moi et l'host a une forte latence que le lien IPv4 n'a pas).
Pour "corriger" les dépendances d'un paquet Debian un peu foireux, il y a plusieurs solutions. La plus maligne est sans doutes l'outil equivs
qui permet de créer facilement des paquets virtuels qui fournissent des noms et/ou dépendent d'autre paquets.
Mais il y a des cas plus compliqués, par exemple avec les conflits : si on a un paquet A qui dépend du paquet B¹, mais que B² est installé et est en conflit avec B¹, on ne peut pas simplement créer le paquet virtuel B¹ qui dépend de B², puisque B² n'accepte pas que B¹ soit installé.
Mais on n'abandonne pas, et vu qu'à ce stade on est entrain de faire des gros hacks bien sales, éditons le .deb de A à la main pour le faire dépendre de B² à la place de B¹.
Pour ça, il faut connaître le format des paquets Debian, mais justement la page Wikipedia liée nous dit tout. Donc, allons-y :
$ # on va travailler dans un dossier temporaire
$ mkdir /tmp/debhack && cd /tmp/debhack
$ # on extrait les fichiers du .deb
$ ar x ~/paquet-version_arch.deb
$ # on extrait les fichiers de contrôle (ici tar.gz, mais peut être d'autre formats de tar)
$ tar xzvf control.tar.gz
$ # maintenant on s'amuse avec le fichier `control` nouvellement décompressé. On peut faire ce qu'on veut, là on va juste changer les dépendances donc
$ sed -e 's/B¹/B²/g' -i control
$ # on en profite pour changer la version du paquet
$ sed -e 's/Version:.*$/&+local1/' -i control
$ # et à partir de là on recrée notre paquet
$ tar czvf control.tar.gz control md5sums
$ # attention, l'ordre de debian-binary est important !
$ ar cr …/paquet-version_arch+local1.deb debian-binary control.tar.gz data.tar.xz
Et voilà, on a un .deb mis à jour et tout frais.
On aurait pu aller plus loin et modifier le contenu du paquet, changer la description et je ne sais quoi. Attention cependant si vous changez le contenu du paquet (data.tar.xz), car il y a des sommes de contrôle pour chaque fichier dans le fichier md5sums de control.tar.gz, donc il faudra aussi les mettre à jour.
Vous avez une application qui ne fonctionne pas comme il faut, et vous n'avez pas le courage de tout rebuild pour faire des tests ? Vous sortez GDB, normal. Après quelques recherches, vous trouvez que cette application oublie purement et simplement d'initialiser une de ses bibliothèques ? Pas de problème, on va injecter l'appel manquant.
C'est tout simple : ajouter un breakpoint là où l'on souhaite injecter l'appel (moi j'ai choisi main
tout simplement : break main
), puis lancer le programme (run
). Quand le breakpoint est atteint, on appelle la fonction le plus simplement du monde avec call
, et on reprend l'exécution comme si de rien n'était avec continue
.
Et voilà, pas besoin de patch binaire :] (bon OK le faire à chaque lancement c'est super chiant, même si ça peut se scripter en envoyant des commandes sur l'entrée standard de GDB)
Pour que ça fonctionne il faut bien sûr soit injecter à une adresse connue (par ex. une fonction exportée), soit avoir les symboles de débogage pour que GDB puisse trouver l'adresse.
Petite commande sympa pour connaître la progression d'une opération sur des fichiers (cp, sha*sum, dd, etc.), qui semble marcher vraiment et qui est packagée dans Debian (unstable).
Testé vite fait (donc pas en détail du tout), mais ça a l'air bien pratique pour créer des itinéraires ou traces à la main.
Ever got annoyed how you get "root" as author in your etckeeper commits made through sudo? I do. The problem does not exist with etckeeper commit
, but the etckeeper interface doesn't allow for committing only a subset of the changes (which is one of many Git super-useful features). So I want to use git commit
. But it records myself as root.
The problem is that sudo makes us essentially root. One could argue that well, it's the point! Indeed it is, though here we want to get root's rights, yet still be ourselves. There are various possible solutions to this, and here are some:
1) use sudo -E
. This tells sudo not to reset any of the environment variables, which keeps among other things $HOME, in which Git will find your .gitconfig. This is easy, but it's a nuclear option with a nuclear cloud coming back your way: you lose all security advantages of sudo's environment cleanup.
2) if you're the only one on the machine, you can set user.name
and user.email
in the /etc repository. But if you're gonna do this, it's arguable how useful it is to know who committed, as it'll still always be the same person, just not root.
3) manually pass --author
to git commit
. This is annoying, though.
4) set GIT_AUTHOR_NAME/GIT_AUTHOR_EMAIL/GIT_COMMITTER_NAME/GIT_COMMITTER_EMAIL variables in your environment (.profile, .bashrc, wherever you get them the way you want), and list them in sudo's env_keep configuration setting. This mostly just Does What You Want™ -- but beware! these environment variables take precedence over Git's configuration, so it will apply whenever you use Git, not only in /etc, and regardless of your user.name and user.email settings.
You can pick whichever solution you like the best (or find another one). A clever user could even write a script or shell function to wrap the git call to set the author info when appropriate (either a full wrapper being "smart", or a special named one for use when committing in /etc).
Bonus, because I'm so kind, here's a script that picks the values from the .gitconfig of the user that called sudo, and runs git with whichever argument you gave it:
#!/bin/sh
# set to the git executable
GIT=git
# if running under sudo, try and use the caller's git config
if [ -n "$SUDO_USER" ]; then
if [ -z "$GIT_CONFIG" ]; then
sudo_user_home=$(getent passwd "$SUDO_USER" | cut -d: -f6)
[ -n "$sudo_user_home" ] && GIT_CONFIG="$sudo_user_home/.gitconfig"
fi
[ -n "$GIT_CONFIG" -a -f "$GIT_CONFIG" ] && export GIT_CONFIG
[ -z "$GIT_AUTHOR_NAME" ] && GIT_AUTHOR_NAME=$("$GIT" config user.name)
[ -z "$GIT_AUTHOR_EMAIL" ] && GIT_AUTHOR_EMAIL=$("$GIT" config user.email)
[ -n "$GIT_AUTHOR_NAME" ] && export GIT_AUTHOR_NAME
[ -n "$GIT_AUTHOR_EMAIL" ] && export GIT_AUTHOR_EMAIL
fi
exec "$GIT" "$@"
Can be put in e.g. /usr/local/sbin/etcgit or something similar and called instead of git
. Or it could be used as a drop-in replacement for git
itself (just set GIT to the absolute path to the real git so the script doesn't call itself recursively).
Of course, the script has to be in the PATH sudo uses (~/bin is not).
Le s_client
d'openssl peut être très pratique pour effectuer des tests… sauf quand il quitte ou renégocie comme ça sans raison apparente.
En effet, en "mode interactif" (par défaut), s_client
se croit malin de renégocier quand il voit une commande qui commence par R (par exemple un "RCPT TO" SMTP), et de quitter quand il voit une commande qui commence par Q. Particulièrement pratique lors d'une tentative d'AUTH LOGIN avec des identifiants/mots de passe dont le base64 commence par l'un ou l'autre…
Mais tout n'est pas perdu ! Il est possible de désactiver le "mode interactif" avec les options -quiet
ou -ign_eof
. Et là, plus de problèmes de renégociation ou de déconnexion intempestive.
En écho à http://shaarli.guiguishow.info/?QBpzwg
I wanted to create a new LV on one of my VGs, but I wanted it to be allocated at the end of the PV because I knew that I wouldn't want to extend it (or if I ever did, I wouldn't care about its content -- it was for a /tmp partition), and I wanted the LVs on that same PV to be able to extend linearly if possible. Basically, I wanted to create a new LV that wouldn't get in the way.
The only solution I found was kind of the nuclear one, but it works great: specify which Physical Extents (PEs) the LV should be allocated on. This can easily be specified to lvcreate
as a :PEStart-PEEnd
suffix to the PhysicalVolumePath
argument.
But to provide the correct PE range, we first need to find what "correct" is here. For that, pvdisplay --maps
comes in handy, showing how PEs are allocated on a PV. Once you got the free PE range(s), and the PE size, you can easily calculate how many PEs you'll need, and so which range to specify. Beware though, apparently if you want to allocate the very last PE, you should not specify it, but simply give an "open" range, like ":PEStart-": otherwise, lvcreate
told me the range was incorrect (and if you guess it was a 0-based PE value and lower start and end by 1, you get 1 free PE at the end).
As you provide PE ranges, I suggest you provide the size of the LV in Logical Extents (LEs, --extents
) instead of megabytes or gigabytes (--size
) -- anyway you already calculated how many PEs you needed for the size you wanted.
I also chose to explicitly specify the allocation policy as contiguous, just to be sure LVM wouldn't try and be a smartass behind my back in case I messed up with my ranges.
In the end, I ended up with this command:
lvcreate --alloc contiguous -l768 -n NewLVName VGName /dev/mapper/PVName:37149-
And a pvdisplay --maps
nicely shows I got free PEs only before that LV -- so you could extend the previous one even with the contiguous allocation policy.
PS: well, actually I didn't use this command exactly, because I didn't know about that last PE range issue, so I first allocated it one PE too short of the range I wanted. But then, I decided it was alright and just extended the LV by one PE, using lvextend --alloc contiguous -l+1 /dev/mapper/VGName-LVName /dev/mapper/PVName:37148-
.
I had problems with selecting the device to use for early-networking, because apparently its name was not very stable (e.g. upgrade from Linux 2.6.26 to 2.6.32 had changed it a the time, but there was more), leading to my early networking to fail unexpectedly -- which is especially problematic if you need it to boot.
Trying once again to fix this, I noticed that the documentation of the ip
kernel parameter specifies that the device
might be empty and then the kernel with try to find the first that actually works:
<device> Name of network device to use. If this is empty, all
devices are used for RARP/BOOTP/DHCP requests, and the
first one we receive a reply on is configured. If you
have only one device, you can safely leave this blank.
Although this snippet is not very clear on whether it would work with a static IP, it does work just fine :)
So, if your setup has no risk of finding an inappropriate interface (e.g. if you only have one actually working in early boot) it's very handy to simply let the kernel choose for you.
Voilà un outil que je ne connaissais pas et qui peut s'avérer bien utile dans certains cas :)
Le monde n'est pas super clair à ce sujet, donc un petit tuto/récapitulatif :
1) il faut bien sûr commencer par monter le système de fichier racine qui contient les ecryptfs (la partition système du Ubuntu) :
sudo mount /dev/sda1 /mnt
(/dev/sda1 est bien sûr à adapter au cas où)
2) à partir de là il y a deux solution : la solution « magique » avec le script ecryptfs-recover-private
et la solution manuelle où l'on comprend ce qui se passe. S'il s'agit simplement de récupérer des données, je conseille le script qui est beaucoup plus simple et nécessite moins de connaissances sur l'ecryptfs à ouvrir.
2.1) avec le script ecryptfs-recover-private
il n'y a presque rien à faire, juste le lancer en root :
sudo ecryptfs-recover-private
On peut éviter de le laisser chercher l'ecryptfs à monter en lui donnant en argument :
sudo ecryptfs-recover-private /mnt/home/.ecryptfs/<username>/.Private/
(il faut bien sûr remplacer <username>
par l'identifiant de l'utilisateur)
L'outil va poser quelques questions simples (comme le mot de passe de l'utilisateur à qui appartient les données chiffrées), et normalement va monter une version (en lecture seule, sauf si l'option --rw
a été passée) des données déchiffrées quelque part dans /tmp/ecryptfs.*
(il dit bien sûr où).
2.2) La solution manuelle est un peu plus complexe, et reproduit à peu près ce que fait le script. Le seul réel avantage est de comprendre ce qui se passe.
2.2.1) Il faut connaître la passphrase utilisée pour l'ecryptfs lui-même, qui n'est pas le mot de passe de l'utilisateur à qui appartient les données. Si vous ne l'avez pas, il est cependant possible de la retrouver avec le mot de passe utilisateur :
sudo ecryptfs-unwrap-passphrase /mnt/home/.ecryptfs/<username>/.ecryptfs/wrapped-passphrase
2.2.2) maintenant il faut insérer les clés FNEK (chiffrement des noms de fichiers, FileName Encryption Key) dans le keyring :
sudo ecryptfs-add-passphrase --fnek
Cette commande demande la passphrase de l'ecryptfs telle que retrouvée ci-dessus, pas le mot de passe utilisateur.
Cette commande affiche deux tokens, le premier est la signature du mount (ci après $mount_sig
), et la deuxième celle du FNEK (si après $fnek_sig
). On va en avoir besoin juste après.
Note : il est nécessaire de ré-invoquer ecryptfs-add-passphrase
avant chaque montage, car les tokens sont retirés du keyring lors du démontage.
2.2.3) Il ne reste plus qu'à monter l'ecryptfs. On crée d'abord un point de montage bien sûr :
mkdir ~/priv
(ou n'importe où ailleurs)
puis on monte l'ecryptfs :
sudo mount -t ecryptfs /mnt/home/.ecryptfs/<username>/.Private/ ~/priv -o ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_sig=$mount_sig,ecryptfs_fnek_sig=$fnek_sig,ecryptfs_passthrough=n,no_sig_cache
(certaines options ici ne sont pas absolument nécessaires et si non renseignées seront demandées interactivement, les donner sur la ligne de commande évite ça)
La passphrase de l'ecryptfs sera demandée, et une fois renseignée le montage devrait réussir, et les fichiers disponibles dans ~/priv
(ou quel que soit le point de pontage choisi) \o/
3) Note : le point de montage appartient à l'UID de l'utilisateur à qui appartiennent les fichiers chiffrés, ce qui n'est pas forcement celle de l'utilisateur d'un live Ubuntu (999), donc il faudra peut-être changer les droits du point de montage après coup, ou accéder aux fichiers en root.
Vous vous souvenez peut-être de mon post blâmant journald qui polluait mes logs et remplissait /var/log ? (http://ban.netlib.re/shaarli/?RVgspw) Bon et bien j'avais assez tort, ce n'est pas directement la faute de systemd en fait (ça passe par lui, mais ce n'est pas sa faute).
Ce qui remplit /var/log c'est juste syslog, qui écrit les logs de journald sur le disque (et les écrit trois fois, je n'ai pas cherché pourquoi). Quoi qu'il en soit ça fait longtemps que syslog fait ça, mais ça n'a pas grande incidence car peu d'applications logguent via syslog.
Le vrai problème est que les développeurs de GDM ont imaginé que c'était une bonne idée que de logguer la sortie de la session X explicitement via journald au lieu du bon vieux .xsession-errors (ou de $XDG_CACHE_HOME/gdm/session.log dans les versions plus récentes de GDM). Ça a l'air gentillet dit comme ça, mais ça envoie beaucoup de choses dans jounrald, qui sous Debian les renvoie à syslog, qui les écrit sur le disque.
Bref, maintenant il faut attendre que ce problème soit corrigé dans Debian. Pour ça il y a probablement deux solutions :
(3. ne pas utiliser GDM. Là le problème est qu'avec par exemple lightdm certaines choses fonctionnent moins bien (au moins sous MATE, mais je pense que ce sera pareil sous GNOME), comme les mises en veilles/reboot/changement d'utilisateurs/délock depuis le DM, etc.)
Pas très nouveau non-plus mais ce billet présente très bien ces différentes sources qui en effet contiennent de vrai petits (ou grands) bijoux.
Comme il dit pas un scoop mais toujours intéressant.
De plus en plus de développeurs C s'éloignent du standard C89 avec entre autres l'avènement de C11. Il serait en effet facile d'imaginer qu'au minimum C99 soit raisonnablement bien répandu 15 ans plus tard. Mais c'est sans compter Microsoft Visual C++.
Microsoft ne supporte pas C99 avec MSVC. Même au niveau de la bibliothèque standard des fonctions qui leur serait pourtant assez facile de fournir n'existent pas, et leur équivalent n'est pas exactement équivalent.
Prenons l'exemple amusant (ou pas) de snprintf()
. Cette variante plus sûre de sprintf()
a en effet été standardisée dans C99. De son côté, MSVC fournit différentes variantes de fonctions qui ressemblent, dont _snprintf()
. Elles ressemblent suffisamment pour qu'un développeur naïf ajoute quelque chose comme #define snprintf _snprintf
pour compiler avec MSVC, mais ces fonctions ont de subtile différences qui peuvent se révéler ennuyeuses, voire pire, dangereuses.
Par exemple, C99 dit que snprintf()
retourne le nombre d'octets qui auraient été écrits si le buffer avait été suffisamment grand. Une astuce pratique qui repose sur cette propriété (via la variante vsnprintf()
) est de calculer la taille nécessaire pour un buffer avec vsnprintf(NULL, 0, fmt, ap)
¹ pour l'allouer ensuite. Mais _snprintf()
de MSVC retourne -1
si le buffer est trop petit.
C99 dit aussi que snprintf()
écrit toujours le \0
final si la taille du buffer est > 0, même si la sortie est tronquée par ce que le buffer est trop petit. Mais _snprintf()
de MSVC n'écrit le \0
final que si la sortie n'a pas été tronquée. Cette différence est dangereuse pour un habitué du comportement de C99, car il est alors courant de ne pas vérifier la valeur de retour de snprintf()
: même si ce n'est pas parfait, dans la pratique si l'appel est correct (format valide et arguments appropriés) snprintf()
réussira toujours. Au pire la sortie sera tronquée, mais rien de plus grave. Avec le comportement de _snpritnf()
par contre si la sortie est tronquée, utiliser le buffer peut être dangereux puisque il n'a pas de \0
final, et donc les fonctions de manipulation de chaînes ne qui ne prennent pas d'argument de taille vont lire au delà de la fin du buffer.
Tout ceci rend l'utilisation de snprintf()
assez difficile si l'ont veut supporter MSVC. Il y a bien sûr différentes solutions. La plus évidente est de ne pas dépendre du comportement de C99 et de toujours vérifier la valeur de retour. Si tous les appels vérifient que la valeur de retour n'est pas négative, et même si le comportement sera différent avec MSVC si la sortie est tronquée, il n'y a pas de risques puisque _snprintf()
retourne -1
lorsque la sortie est tronquée. Cependant cette solution peut impliquer beaucoup de petits changements ennuyeux, et a un comportement différent sous MSVC. De plus, il y a fort à parier que si snprintf()
a été utilisé dans le passé il le sera encore dans le futur, et il faudra donc toujours penser au comportement différent sous MSVC.
Une autre solution évidente, bien que plus compliquée, est d'écrire un wrapper pour fournir une version de snprintf()
qui se comporte comme C99 le demande. Avec _vsnprintf_s(buf, count, _TRUNCATE, fmt, ap)
et _vscprintf()
il reste assez simple d'écrire ce wrapper, même s'il faut faire attention aux détails de ces API (par exemple _vsnprintf_s()
n'accepte pas un count de 0).
Enfin bref, tout ça pour dire qu'il semble que C89 a encore de beaux jours devant lui, tout comme les bibliothèques qui fournissent une compatibilité C99 (et plus si affinité).
¹ Pour être complètement honnête, les implémentations pre-C99 de snprintf()
ont pour la plupart de subtiles différences, comme par exemple SUSv2 qui n'autorise pas count à être 0. C'est pour ça que l'ont voit souvent une variante avec un buffer de taille 1 :
char dummy;
int len = vsnprintf(&dummy, 1, fmt, ap);
Avec l'option -x
de less, il est possible de définir la position des fins de tabulations (tab stops). C'est fort pratique pour visualiser un fichier qui utilise des tabulations d'une largeur différente de 8 (la valeur par défaut), avec par exemple less -x4
.
Encore mieux, il est possible de spécifier plusieurs positions, ce qui est très utile par exemple pour visualiser un diff d'un fichier contenant des tabulations : en effet, comme chaque ligne d'un diff contient un caractère de contrôle en plus (+, - ou espace), les tabulations peuvent ne plus être alignées (si par exemple une tabulation de 8 commençait à l'offset 7, elle commencera alors à l'offset 8… et terminera alors à 16).
Et donc pour ce cas, il suffit de définir une première largeur de 9 (8 + le caractère de contrôle de diff), puis une de 8 : less -x9,17
.
Et bien sûr c'est fort pratique pour Git : si la majeure partie des sorties de Git qui contiennent des tabulations que vous consultez sont des diffs (ce qui est fort probable), définir core.pager
à less -x9,17
(ou autre valeur appropriée à votre projet) permet d'avoir des tabulations bien alignées sans avoir à définir PAGER à la main pour chaque appel.
À noter bien sûr que cette propriété de configuration peut être aussi bien définie dans votre ~/.gitconfig global que le .git/config d'un dépôt particulier (très pratique si un projet particulier utilise un largeur de tabulation différente de 8).
Après vous être pris la tête pendant un bon moment à voir « le patch ne s'applique pas », vous vous rendrez compte que git am
supprime les CR par défaut.
J'imagine que le but est de simplifier la vie des gens qui reçoivent des patchs par email (puisque la fin de ligne pour les mails est CR-LF) et que la plupart des fichiers utilisent seulement LF.
Moins pratique par contre si l'on a utilisé git format-patch
et qu'un des fichiers avait des CR-LF.
Solution : passer l'option --keep-cr
à git-am.
Et encore une vidéo sympa (heh) sur la neutralité du net. Bien plus frivole que la précédente bien sûr, vous avez vu le titre. Presque SFW -- la neutralité du net est SFW donc la question ne se pose même pas.
Merci karchnu pour le lien :)
Edit : quelques remarques pertinentes de quelqu'un de pertinent : http://shaarli.guiguishow.info/?BYFLwQ
Mais moi je suis naïf est pense/espère que des choses comme ça peuvent éveiller un intérêt chez certains pour se poser la question des détails et enjeux. Oui, je suis optimiste.
Bon je sais que c'est #old, mais je ne l'avais pas lié et ça vaut le coup.
Apparemment déjà quelqu'un s'est dit que c'était malin de mettre les logs de Xsession (donc que qu'on avait dans ~/.xsession-errors) dans /var/log/{messages,syslog,user.log}. Oui, les trois tant qu'à faire.
Enfin bref, déjà ça avait pas l'air super malin dit comme ça, mais quid de quand une application lancée par la session part en vrille et affiche tout un tas de bousin dans stderr ? Sans surprise, ces trois fichiers grossissent à vue d'œil.
Les miens ont atteint 320M chacun avant que je ne trouve et tue le programme incriminé (et encore, je m'en suis rendu compte dans la minute), ce qui m'a bouffé à peu de choses près 1G dans /var (je n'ai pas de /var, donc dans /). Et même si je n'ai pas vérifié, je pense que vu que le logger (journald) est un service système, il va avoir tous les droits pour utiliser les blocs réservés et donc remplir le FS à s'en rendre malade.
Ah le bon vieux temps où une telle chose n'aurait rempli "que" $HOME…
Enfin bref, le plus intéressant dans l'histoire est que si j'en crois la documentation de journald.conf, le comportement par défaut est de ne pas logguer les sessions avec le système. Mais ma conf de journald (celle par défaut dans Debian testing/unstable) est vide (tout est commenté) et devrait j'imagine utiliser les valeurs par défaut… enfin bref j'ai tenté de définir manuellement SplitMode=uid
, on verra ce que ça donne.
Bref, je ne sais pas à qui revient vraiment la faute (journald tout pourri ou mauvaise conf dans Debian ?), mais le résultat est le même, mes logs on été pourris par une application bénigne en userspace qui est partie en vrille (comme le font et vont le faire les apps userspace). Et quid d'un petit malin qui fait ça exprès.
La suite (peut-être) au prochain numéro.
Je savais qu'on pouvait tout faire, mais bowdel !
Lire aussi la section suivante pour les plages : http://git-scm.com/docs/git-rev-parse#_specifying_ranges
A simple way to force Firefox/Iceweasel to clear its local DNS cache.
Ça a l'air d'une opération toute bête, mais utiliser Icedove comme client de flux Atom/RSS en provenance de sites HTTPS non vérifiés par une autorité installée est très subtil. Simplement essayer d'ajouter le flux ne va pas marcher avec le très subtil et mensonger message d'erreur « L'adresse de flux est introuvable ».
L'utilisateur naïf va tenter d'importer le certificat dans les préférences après avoir vérifié trois fois que son adresse est correcte, mais c'est sans compter que comme Firefox, il n'utilise que le CN pour les exceptions manuelles [1].
Donc, pour ajouter une exception qui marche, on va procéder en deux étapes :
Vraiment subtil mais ça marche.
[1] Ou même que ça ne marche pas du tout, je ne suis pas sûr puisque ça n'a pas ajouté d'entrées dans le fichier d'exceptions. Enfin bref.
Je le savais déjà, mais c'est quand-même beau.
hg n'a pas directement le format-patch
de Git, qui est très pratique non seulement pour envoyer des patches par mail (où hg a l'extension Patchbomb), mais aussi pour simplement exporter vers un fichier par exemple pour attacher à un rapport de bug.
hg a export
qui fait le boulot, mais qui n'écrit pas automatiquement dans un fichier. Pour ce faire, il faut utiliser -o
(--output
), et écrire un nom de fichier à la main. Heureusement on peut utiliser des des formats automatisés comme %n
et %m
. Pour une sortie similaire à format-patch
on utilisera -o '%n-%m.patch'
.
Comme tout ça est bien verbeux, je suggère un alias (http://www.selenic.com/mercurial/hgrc.5.html#alias) :
[alias]
format-patch = export -v -o '%n-%m.patch'
[defaults]
dans l'hgrc
permet de configurer les options par défaut des différentes commandes, comme par exemple -vf
pour log
.
Les branches sous Git sont réputées pour êtres différentes de celles des autres systèmes, et c'est vrai. La fonctionnalité de hg la plus proche de celle des branches Git sont les bookmarks
.
Pas évident de prime abord, mais ça marche plutôt bien (au moins pour un utilisateur occasionnel venant de Git).
Le comportement par défaut du log
de hg est proprement exaspérant pour un utilisateur de Git : la révision par défaut étant tip:0
(qui n'est pas nécessairement l'état courant).
Pour avoir le log de l'état courant du dépôt, comme le fait Git par défaut : -f
(--folow
). On ajoutera -v
pour avoir des messages complets.
Pour inclure les différences on utilisera p
, comme avec Git (peut-être en combinaison avec -g
pour avoir le format étendu de Git, même s'il ne change rien pour les diffs les plus courants).
Un autre must-have, le pendant du color
de Git, et fonctionne à peu près pareil.
Must-have, particulièrement pour tout utilisateur de Git qui a l'habitude d'un comportement pratique par défaut. Comme son nom l'indique, cette extension permet d'utiliser un pager automatiquement sur la sortie de la plupart des commandes, comme par exemple log
ou export
.
Les options suggérées pour less sont très bonnes, et fonctionnent comme Git :
F : quitter less automatiquement si la sortie tient sur l'écran
R : garder les séquences d'échappement pour la coloration (utile en particulier avec l'extension color)
X : ne pas vider la vue à la sortie, indispensable quand on utilise F
Quand on importe un certificat auto-signé dans Firefox, il ne s'applique qu'à un seul sous-domaine particulier (celui d'où on l'a importé si on a ajouté une exception, ou le CN si on l'a importé dans le gestionnaire). C'est bien, mais quand il y a plusieurs sous-domaines (ou domaines) qui utilisent le même certificat (via un subjectAltName), ça devient vite ennuyeux de refaire la même manip' pour chaque sous-domaine (et de les vérifier tous).
Heureusement, il y a une astuce : modifier le fichier cert_override.txt dans le dossier du profil. Il vaut mieux d'abord avoir ajouté une exception (et non uniquement avoir importé le certificat) pour avoir une entrée à dupliquer aisément. Il suffit ensuite de dupliquer la ligne appropriée dans ce fichier et de changer le domaine (1ère entrée), puis de relancer Firefox.
SIGUSR1 dans est bloqué dans les sessions graphiques, merci GDM…
"Sometimes it may be necessary to blacklist a module to prevent it from being loaded automatically by the kernel and udev. One reason could be that a particular module causes problems with your hardware. The kernel also sometimes lists two different drivers for the same device. This can cause the device to not work correctly if the drivers conflict or if the wrong driver is loaded first.
You can blacklist a module using the following syntax: module_name.blacklist=yes."
$GLOBALS
;Instead, if you need a similar feature, look at class (or function) static variables.
self::$my_class_global
.If you don't have a class… well, first check if your code couldn't get better organized by being in one. If not, either create a state class (abstract class MyState { static $foo = 0; }
) and use it as a global, or know what you do and use a global, with all its attached baggage.