carnet(1) is a logbook and note taking helper. It provides a way to record seamlessly journal entries, along automated recording of the time and date. As an option, it can also record all sorts of interesting information, like recorded calendar(1) activities, or what could be playing on music players like mocp(1).
The log book is a set of text files, one per week, made of entries separated by a time stamp, and specific markers to separate days of the week; this avoids exploding the file size of a long running log file typed for a while by a proficient writer, while also avoiding the explosion of file numbers that could appear with compulsive writers.
In a hurry? You can download the latest version at the bottom of this page, but you may want to go through the whole page if this is your first contact with the utility.
Warning: while the utility is now available to the public, there are several rough edges, several documented in the BUGS file, and probably many more that flown below my radar.
The main purpose of carnet is to open a scratch pad in which to take notes that may be easily retrieved, without having to go through the hurdles of finding in which location to store the note, how to name the file, things like that. Just type in your prompt:
$ carnet
and boom! You can go ahead and type in your note in your favorite text editor:
2025-25.txt - semaine précédente 2025-27.txt - semaine suivante 2024-42.txt - première semaine Journal de bord, an 2025, semaine 26 ________________________________________________________________________ Date : dimanche (2025-06-29) 22:52 : sur fond de : Yes - Close To The Edge J'aime bien le morceau en train de passer à la radio. :)
carnet will try hard to pass the right options to start edition straight at the end of the file, after having appended all the timestamps and informations that give context to the entry. Only the last line, highlighted in the hard-copy here above, has been typed in. Of course, when a proficient writer fills thick entries, the decorum gives way to the content.
There also exists an option --activity which is purposed to gratify the writer with a sense of achievement after a well filled week:
$ carnet -a 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 2024-42|===|===|===|===|===|===|===|===|===|===|===|= 2024-43|===|===|===|===|===|=== […] 2025-25|===|===|===|===|===|===|===|===|=== 2025-26|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|=== 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 Dist.: | .O |-------|=======#======|---------------| O . Deci.: | - - - - - - - - - - - Perc.: | === =+ ===## =+==#-+ #=# # +== = + = = = = 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 Apparent size: 1233.9kiB raw: 1300kiB density: 94.91% Mean apparent size per week: 33.3kiB raw: 35.1kiB Number of entries: 3117 of weeks: 37
The first part is the histogram per week, trimmed for the sake of brevity, showing the information stored in each week. Each character amounts for 1kiB. The second part paints a box-and-whiskers plot of the distribution of size of entries for each week, and the Deciles and Percentiles lines attempt to represent the same values with an ASCII heat map of activities per week. Yes, it takes some getting used to to notice that weekly activity happens following a pattern which resembles to a Poisson distribution; it will make more sense as entries are going to be added during day to day activities. Then some random information follows, with relation to the size occupancy of the carnet in the file system. The Deciles and Percentiles require the Perl variant of the carnet_activity script.
I have found it tremendously beneficial to prepare time sheets thanks to the timestamped information stored in the carnet. As I work, I fire `carnet` to record what I do, for example :
________________________________________________________________________ Date : mardi (2025-06-24) 08:06 : I arrived at the office. 10:13 : Since I arrived, I worked on the foo project.
Date and timing information are automatically fed by carnet, I just have to write down what I was doing since the last entry. This can be especially useful if it is necessary to estimate time spent on given projects for whatever billing reason. This is where the --search function shines:
$ carnet -s '\<foo\>' 2025-25.txt : lundi (2025-06-17) : 10:01 : I attended the kick-off meeting of the foo project. ________________________________________________________________________ 2025-26.txt : mardi (2025-06-24) : 10:13 : Since I arrived today, I worked on the foo project.
carnet also includes a configurable option to prevent risks of doing overtime hours, through the CARNET_OVERTIME environment variable, indicating in hours the normal duration of a work day:
________________________________________________________________________ Date : Wednesday (2025-07-09) 09:23 : Starting the day, […] 18:42 : warning: overtime for 19m. Ouch, I'm running late, it's time to go.
As seen above, the --search option takes regular expressions in argument that are directly fed to awk. This makes the retrieval of entries on a certain topics seamless to the extent that one is fluent with regular expressions. Let's say that I want to prepare a document summarising my activity of setting up and configuring my mail server; assuming I took good not of what I was doing, compulsively. Retrieving most of the information would look like:
$ carnet -s 'exim|mail' […] ________________________________________________________________________ 2025-08.txt : vendredi (2025-02-21) : 19:31 : En passant les mises à jour, j'ai vu passer des changements dans le fichier de configuration de mon serveur mail motorisé par exim4. J'ai passé un peu de temps à faire le tri entre les nouveautés et mes propre changements de configuration. […]
Note that this is an excerpt of the output. The full set of entries is actually much larger at the time of writing:
$ carnet -s 'exim|mail' | wc -l 936
Since version 1.4.0, the carnet implements basic functionalities to record tasks needing to be achieved at some point, but not immediately. This is useful to avoid the sense of urgency that might induce e.g. a zero inbox email policy. To record a todo item, just run the carnet and mark work needed with a stylized ascii checkbox like "[ ]" at the beginning of a line, or more simply by starting a paragraph with "TODO:"
23:07 : TODO: describe the use case for todo items. 23:08 : [ ] Demonstrate multiple ways to materialize todo items.
The option --todo of the carnet command will faciliate easy retrieval of all items still non-achieved that have been recorded in the carnet:
$ carnet --todo 2025-30.txt : lundi (2025-07-21T23:07) : TODO: describe the use case for todo items. ________________________________________________________________________ 2025-30.txt : lundi (2025-07-21T23:08) : [ ] Demonstrate multiple ways to materialize todo items.
Resolving a todo item amounts to either mark the begining of the paragraph as "DONE:" or to check the stylized box with e.g. "[*]" or "[x]":
23:07 : DONE: describe the use case for todo items. 23:08 : [*] Demonstrate multiple ways to materialize todo items.
carnet conventiently provides a --done option to facilitate retrieving of resolved issues:
$ carnet --done 2025-30.txt : lundi (2025-07-21T23:07) : DONE: describe the use case for todo items. ________________________________________________________________________ 2025-30.txt : lundi (2025-07-21T23:08) : [*] Demonstrate multiple ways to materialize todo items.
The --todo and --done command line argument also admit an optional parameter to specify alternate states, like for marking tasks pending, cancelled, or low priority. These are mostly free form texts within the brackets, so can be used with any state one may imagine:
$ carnet --todo cancelled 2025-29.txt : vendredi (2025-07-18T17:40) : [cancelled] J'ai une quantité d'informations stockées dans le carnet rédigé en Anglais qu'il faudra à un moment que j'importe dans mon fil de carnet personnel.
While assembling a Zettelkasten engine was not the initial goal of carnet, it is possible to interlink the different feuillets of the carnet by referencing them via their timestamp, using the YYYY-MM-DDThh:mm time and date format, and to feed this time stamp to the option --feuillet since v1.3.0. To this end, --search and other read-only options will output each entry with their timestamp highlighted to this time format, in order to facilitate retrival and cross references:
$ carnet --search zettelkasten […] 2025-27.txt : samedi (2025-07-05T22:25) : sur fond de : Canvas Solaris - The Binaural Beat J'ai publié la version 1.2.3 de carnet afin d'avoir quelque chose d'opérationnel avant de commencer à rajouter une option pour supporter un usage en mode Zettelkasten. Le fonctionnement restera assez sommaire : comme écrit plus tôt (Cf: 2025-07-05T18:23), je compte fournir un format de date et d'heure qui pourra être passé en argument pour ressortir une entrée de journal en particulier. La navigation dans le Zettelkasten se fera en copiant et collant la date comme paramêtre de l'option. […] $ carnet --feuillet 2025-07-05T18:23 File: /home/emollier/doc//carnet/2025-27.txt 18:23 : J'ai passé un petit coup de balai. Pour l'idée de faire un Zettelkasten en utilisant le carnet (Cf: 2025-07-05T11:25), il me faut deux choses : * construire facilement un marqueur pour référencer un ticket par sa date et son heure, ce que je peux faire très simplement en ajustant le format de sortie de la fonction de recherche ; manifestement je pars sur un format YYYY-MM-DDThh:mm, parce que c'est ce qui me semble le plus évident ; * ajouter une option pour référencer une entrée par son marqueur ; j'hésite sur le nom de l'option, peut-être quelque chose comme --feuillet ?
This is not the best example at hand, but it will do. The idea is that one can surf between ideas, and eventually discover unexpected relations between thoughts. A strongly interlinked Zettelkasten is a tool designed for organising one's ideas in the perspective of publications, plural.
carnet presents itself as a shell script which, at t time, is mostly used on Debian 13 trixie and later. Portability issues are to be expected to other operating systems, having tested it on NetBSD 10 and witnessed several issues on that operating system level. The dependencies set is thus mostly usual, with a need for a Bourne compatible Shell like dash, coreutils, you name it.
carnet also requires a text editor and a pager, but one can bring one's own utilities. The idea is not to write a complete software suite, but glue together components appropriate to anyone's ergonomics.
Gnu Awk motorizes most of the queries and search abilities of carnet.
carnet also embeds a companion script written in Perl, to practically extract and report the activity in the carnet as weeks go on. Versions of carnet 1.0.y stuck to using shell scripting for the activity report if pulling the Perl interpreter is a big no-no. Note that carnet versions 1.1.y will need Perl for the activity report, but will otherwise run fine without it; this is merely a cosmetic option.
As mentioned above, certain utilities will enhance the content of the carnet, without impeding its usability when they are missing. A well maintained calendar(1) will be able to provide the schedule of the upcoming week when starting a new one, before listing the first entries. If playing music with MOC, the carnet will be capable of recording the track currently airing. None of these options are fundamental to the carnet, but are niceties to give context to some entries.
For the moment, carnet is rather confidential: I don't plan to provide operating system packages of it, unless there proves to be wide interest in carnet. To install it, download the latest version made available at the end of this page, verify its integrity and extract it. For example with the version 1.1.1:
$ gpg --verify carnet-1.1.1.tar.xz.asc gpg: assuming signed data in 'carnet-1.1.1.tar.xz' gpg: Signature made Sun Jun 29 20:27:31 2025 CEST gpg: using RSA key 8F91B227C7D6F2B1948C8236793CF67E8F0D11DA gpg: Good signature from "Étienne Mollier <emollier@emlwks999.eu>" [ultimate] gpg: aka "Étienne Mollier <emollier@debian.org>" [ultimate] gpg: aka "Étienne Mollier <etienne.mollier@mailoo.org>" [ultimate] Primary key fingerprint: 8F91 B227 C7D6 F2B1 948C 8236 793C F67E 8F0D 11DA $ tar xvf carnet-1.1.1.tar.xz carnet-1.1.1/ carnet-1.1.1/scripts/ carnet-1.1.1/scripts/gen_test_carnet.pl carnet-1.1.1/BUGS carnet-1.1.1/LICENSE carnet-1.1.1/TODO carnet-1.1.1/carnet_activity.pl carnet-1.1.1/carnet carnet-1.1.1/makefile carnet-1.1.1/carnet.fodg
The carnet presents itself under the form of a shell script which may be installed, along companion script and manual page if applicable, using usual make targets:
$ make echo '[REPORTING BUGS]' > BUGS.roff sed 's/^$/.PP/' BUGS >> BUGS.roff help2man \ --name 'note taking logbook helper' \ --section 1 \ --locale C.UTF-8 \ --include BUGS.roff \ --output carnet.1 \ --no-info \ ./carnet gzip --verbose --force --best --keep carnet.1 carnet.1: 50.5% -- created carnet.1.gz $ sudo make install mkdir -p /usr/local/bin install carnet /usr/local/bin chmod 0755 /usr/local/bin/carnet install carnet_activity.pl /usr/local/bin chmod 0755 /usr/local/bin/carnet_activity.pl mkdir -p /usr/local/share/man/man1 install carnet.1.gz /usr/local/share/man/man1
But it can also be deployed by hand, to avoid the need to depend on html2man. The shell script carnet is mostly self sufficient, notably the argument --help provides most of the useful information transcribed automatically to the manual page. It is even useful even if its companion Perl script for the statistics activity page is not around; one would simply have to make without the --activity option.
Remark: carnet versions 1.0.y did not depend on the companion script for displaying activity statistics, at the cost of more difficult portability outside Debian, and a performance penalty of the shell script compared to the perl script.
For now, most of the configurable options of the carnet are provided under the form of environment variables, but note that it has also been designed to avoid the need for extra configuration before getting started. Currently accounted environment variables are:
This software is copyright 2024-2025, Étienne Mollier. It is shipped under AGPL-3+, the Gnu Affero General Public License, at version 3 or any later version. See the LICENSE file for more details.
Several versions are made available, to preserve history to some extent, especially while the git tree is not published. Note that each archive is signed with my gpg key 8F91 B227 C7D6 F2B1 948C 8236 793C F67E 8F0D 11DA advertised on my whoami page and also used for Debian Development purpose; thus it should be well known by multiple independent channels. Archives and signatures are available in the present directory:
![]() | Name | Last modified | Size |
---|---|---|---|
![]() | Parent Directory | - | |
![]() | archives/ | 2025-08-13 20:50 | - |
![]() | carnet.svg | 2025-06-29 22:43 | 13K |
![]() | carnet-1.6.5.tar.xz | 2025-08-13 20:49 | 31K |
![]() | carnet-1.6.5.tar.xz.asc | 2025-08-13 20:49 | 833 |