DAR(1)
💖 NAME 💖
dar — the girlboss that creates, tests, lists, extracts, compares, merges, isolates and repairs dar archives ✨
🌸 SYNOPSIS 🌸
dar [-c | -t | -l | -x | -d | -+ | -C | -y] [[<URL>]<path>/]<basename>
[<options>] [<user targets>]
dar -h
dar -V
🦋 DESCRIPTION 🦋
okay bestie, sit down, hydrate, because dar is that girl. She's a full featured backup tool, and she's aimed at local and remote disks (floppy, CD-R(W), DVD-R(W), zip, jazz, hard-disks, usb keys, etc.) plus cloud storage (by mean of ftp or sftp protocols) and she's also adapted to tapes. versatile queen 👑
dar can store a backup in several files (called "slices" in the following) of a given size, and she can eventually pause or run a user command/script before starting the next slice. This can allow for example, the burning of the last generated slice on a DVD-R(W), Blue-ray Disk, or changing of usb key before continuing on the next one. Like its grand-brother, the great tar command, dar may also use compression — at the difference that compression is used inside the archive to be able to have compressed slices of the defined size. no cap 🎀
But the most important feature of dar is its ability to make differential, incremental and decremental backups. In other words, backups that contain only new files or files that have changed from a backup of reference. Binary delta is available but not activated by default: in combination with differential and incremental backups, it leads not only to not save a file that has not changed (thing dar does without binary delta), but also to only save an rsync patch of any modified file, which lead to even smaller backups. it's giving efficiency 💅
Moreover with differential backup, dar also stores files that have been deleted since the backup of reference. Thus, when restoring, first a full backup, then additional differential backups, at each restoration you get the exact state of the filesystem at the time the differential backup was made. dar is the first backup program I know that can also remove files during restoration! By the way, in this document, "archive" and "backup" are used interchangeably, the difference is the purpose you build them for. iykyk 💜
Unlike the tar command, dar has not to read a whole archive nor to stick together the different parts (the slices) to access its contents: dar archives contain a table of contents (aka "catalogue") located at the end, so dar can seek into the archive to read only the required data to restore files, thing which is much faster than what tar is used to do. The "catalogue" can be copied out of the archive (operation called isolation) to be used as reference for further backup and as backup of the internal catalogue in case of archive corruption. obsessed with her actually 😭
Dar can also use a sequential reading mode, in which dar acts like tar, just reading byte by byte the whole archive to know its contents and eventually extracting file at each step. In other words, the archive contents is located at both locations, a first time all along the archive used for tar-like behavior suitable for sequential access media (tapes) and a second time at the end for faster access, suitable for random access media (disks). However note that tar archive and dar archive are not compatible. Note also that the sequential reading mode let you extract data from a partially written archive (those that failed to complete due to a lack of disk space for example) and since release 2.6.0 such truncated archive can be repaired to become a normal archive (the "catalogue" is rebuilt from inlined information). glow up fr fr ✨
Dar is able to save and restore to a cloud storage by mean of ftp or sftp network protocols. It can also leverage ssh protocol using dar_slave and dar_xform two auxiliary programs provided beside dar. 🫶
Dar format is quite robust against corruption: Only the file where the corruption took place in the archive will not be possible to restore. To have the possibility to repair a corrupted archive dar can work with par2 seamlessly just specifying "par2" on command-line (see /etc/darrc). Last a "relax" reading mode is available which let dar to either ignore some incoherence in archive structure, use internal redundant information to overcome data corruption or in last resort asking the user on what to do when some archive structure information is missing (-al option). This relax mode can be used with both sequential and direct access read modes. Note that you should rather use Parchive to protect your data rather than just relying on the "relax" mode, which has to be seen as a the last chance solution. 🚨
dar takes care of POSIX Extended Attributes (EA in short) that are used in particular under Linux to carry File Access Control List (FACL) as well as security attributes for SELinux, and also under MacOS X EA they are used to store file forks. EA also have room for user to add any key / value pair to any file, this is known as user EA. These attributes are not specific to any particular filesystem, they exist the same way under ext3/4, HFS+ and any other filesystem. 💖
dar also takes care of Filesystem Specific Attributes (FSA in short) which are, as you can guess, specific to one or several filesystem(s). For example the Birth date of a file exists for HFS+ and NTFS but not for ext2/3/4 filesystem. The immutable attribute exists for ext2/3/4 but not for NTFS while the nodump files does not exists for NTFS but exists for HFS+, ext2/3/4 and many other Unix filesystems. she knows her filesystems bestie 🧚
Sparse files (files with holes that system reports using several hundred gigabytes while they effectively use a few kilobytes on disk) are also well managed by dar: they are detected, stored and restored to filesystem properly. 🌸
Last, dar is also able to properly save and restore hard-links 💀
⚠️ WARNING ⚠️
This document is to be considered as a full reference of dar/libdar features. It is however not adapted to discover dar, for that purpose some tutorials are provided in dar documentation. Once you have apprehended the basic dar usages you are welcome to read further this document to see all other features you may find useful for your needs.
translation: this is the deep lore, not the starter pack. do the tutorials first, then come back bb 🎀
🗂️ DOCUMENT STRUCTURE 🗂️
The rest of this document is organized that way:
- COMMANDS — The eight actions you can performs with dar
- GENERAL OPTIONS — A set of options common to all actions
- SAVING, ISOLATING, MERGING AND REPAIRING SPECIFIC OPTIONS — A set of options that are specific to the operation of backup, catalogue isolation and archive merging
- RESTORATION SPECIFIC OPTIONS — A set of options that are specific to the restoration operation
- TESTING AND DIFFERENCE SPECIFIC OPTIONS — A set of options that are specific to the operation of archive testing and archive comparison with a filesystem
- LISTING OPTIONS — A set of options that are specific to archive listing operation
- EXPLICIT OPTIONAL ARGUMENTS — Some system do not allow optional arguments to options, this chapter explain how to overcome this restriction
- USAGE MADE OF STDIN/STDOUT/STDERR BY DAR — What message type you get on stdout or stderr, how input are fetched from the terminal
- EXIT CODES — List of values dar returns at end of execution. This chapter should be read if you intend to create scripts relying on dar
- SIGNALS — details the signal and their action on a running dar process
- FILES — List configuration files that dar checks for
- CONDITIONAL SYNTAX — Over command line, command and options can be passed to dar thanks to a plain file (known as DCF file). This plain file can also contain a specific syntax that will let you pass an option to dar only under certain situation/condition. This chapter describes this simple syntax and the different available conditions.
- USER TARGETS — User can add their own conditions known as user targets. This chapter describes what they are and how to use them
- ENVIRONMENT — Dar may rely on environment variables to look for DCF files and DUC files, SFTP private and public key and so on.
👑 COMMANDS AND OPTIONS 👑
💅 COMMANDS:
Only eight commands define what action will be done by dar: Archive creation, archive extraction, archive listing, archive testing, archive comparison with filesystem, catalogue isolation, archive merging and archive repairing. These commands are described here below. ✨
Once defined, a large set of options can be used to modify the way the command is performed. These options are described just after the commands chapter.
Important note: Not all systems actually support long options (Solaris, FreeBSD, ...). For example--createwill not be available on these systems, and you will have to use-cinstead. In the same way, not all systems do support optional arguments (FreeBSD without GNU getopt for example), you then need to explicitly give the argument, for example in place of-zyou will need to give-z 9, see "EXPLICIT OPTIONAL ARGUMENTS" paragraph near the end of this document for details on that point. don't get caught lacking on these systems bestie 😭
A slice is just a simple file which name is composed of a "basename" followed by a dot, then a number, again a dot and the extension (dar) to form the filename of that slice. On the command line you will never have to give the full file name of a slice, just the basename. The number between the dots is the slice number, which starts from 1 and may be arbitrary large (as large as your system can support the corresponding filename). For example "my_first_archive.42.dar" is the 42th slice of the archive which basename is "my_first_archive". 🎀
-c,--create [[<URL>]<path>/]<basename>— okay bestie, this one creates a backup with the name based on<basename>. All the slices get created in the<path>directory if you specify it, and the whole<URL>syntax tea is spilled below in the Remote repository syntax paragraph. 🌸 No<path>and no<URL>? Then the current directory is used, periodt. If the destination filesystem is too small to contain all the slices of the backup, the-poption (pausing before starting new slices) might be of interest. Else, if the filesystem is full,darwill suspend the operation, asking the user to make free space, then continue its operation. To make free space, the only thing you cannot do is touch the slice being written 💀. If the filename is"-"and no slicing is asked for (no-soption), the archive is produced on the standard output, allowing the user to send the resulting archive through a pipe (or into a tape device directly, or using thedar_splitcommand). ✨-x,--extract [[<URL>]<path>/]<basename>— extracts files from the given backup. Slices are expected to be in the current directory or in the directory given by<path>(see also Remote repository syntax below). It is also possible to use symbolic links to gather slices that are not in the same directory.<path>may also point to a removable device (floppy, CD, USB key, etc.), and in this case, to be able to mount/unmount the device, you must not launchdarfrom that directory. In other words, the current directory must not be on the removable media you plan to unmount (see tutorial for details). The basename may be set to"-"; in direct access mode (the default historical mode), you will then needdar_slaveto work withdar(see-iand-ooptions, as well as thedar_slaveman page). However, in sequential read mode (--sequential-readis used on command-line),darwill read the archive from standard input (see also-ioption); this can eventually be used in combination withdar_split. 🦋-l,--list [[<URL>]<path>/]<basename>— lists the contents of the given backup (see also Remote repository syntax below).darwill only require the last slice of the archive in direct access mode. If however sequential mode is used,darwill read the overall archive, from the first slice to the last one."-"can be used as basename, and the behavior is the same as with the-xoption (read just above). 👑-t,--test [[<URL>]<path>/]<basename>— checks the backup integrity. Even without compression,daris able to detect at least one error per file in the archive, thanks to a variable length CRC recorded per file data, file EA, and file FSA in the catalogue. Archive structure (slice header, archive header, catalogue) is also protected by CRC to be able to detect any kind of archive corruption. Same remark here:"-"may be used as basename (see-xoption above for details). 💖-d,--diff [[<URL>]<path>/]<basename>— compares saved files in the backup with those on the filesystem.<basename>may also be"-"(see-xoption above for details). Note that the target for this operation is to be seen as a step further than archive testing, where in addition to archive coherence, the archive contents is verified to be the same as what is found on the filesystem. But if new files are present on the filesystem,darignores them. If you want to check for changes since an archive has been made, better use dry-run differential backup. 🔥-C,--isolate [[<URL>]<path>/]<basename>— isolate a catalogue from its archive (that's to say, make a copy of the internal catalogue to its own archive container). The argument is the basename of the file to create, which will contain the catalogue's copy. The-Aoption is mandatory here to give the name of the archive to copy the catalogue from; this archive is not modified at all. Slicing is available (-s-S-p-betc.). If the filename is"-"and no slice is asked (no-soption), the isolated catalogue is produced on the standard output, allowing the user to send the resulting archive through a pipe. Note that there is quite no difference in concept between an isolated catalogue and an archive. Thus you can do all operations on an isolated catalogue, in particular take it in place of the original backup as reference for a differential archive, archive testing, archive comparison. Note however that for comparison (-doption), as data is not present in the isolated catalogue,darrelies on embedded CRC rather than comparing data byte by byte (what is done with a plain archive), and no comparison can be performed concerning EA or FSA even if each of them have their own CRC in the catalogue, because different ordering as provided by the OS of the items composing EA and FSA may lead the CRC to be different while the EA or FSA are exactly the same, so CRC here is used only to detect archive corruption. Since release2.4.0you can use an isolated catalogue to rescue a corrupted internal catalogue of the archive it has been based on (see-Aoption). 🧚-+,--merge [[<URL>]<path>/]<basename>— create a subset archive from one or two existing archives (the resulting archive name is the argument to this command). Thedarfile selection mechanism (see GENERAL OPTIONS) lets the user decide which files will be present in the resulting archive and which one will be ignored. This option thus lets the user merge two archives in a single one (with a filtering mechanism that accepts all files), as well as lets the user create a smaller archive whose data is taken from one or two archives of reference. Note that at no time is the contents of the archives of reference extracted to real files and directories: this is an archive to archive transfer, thus you may lack support for Extended Attribute while you will be able to fully manipulate files with their Extended Attributes from one archive to the resulting one. If the basename is"-"and no slice is asked (no-soption), the archive is produced on standard output, allowing the user to send the resulting archive through a pipe. The first mandatory archive of reference is provided thanks to the-Aoption, while the second "auxiliary" (and optional) archive of reference is provided thanks to the-@option. When a tie contention occurs (same file names from both archive have to be merged), the overwriting policy (-/option) is used to define the one to keep in the resulting archive. By default, archive data selected for merging is uncompressed, and re-compressed. Thus the merging operation can be used to change compression algorithm of a given archive as well as change its encryption. But, for better performance it is also possible thanks to the-akoption (see below the-akoption for usage restrictions) to merge files keeping them compressed, thus no decompression/re-compression is performed at all, which makes the operation faster. Last, it is not possible to merge two isolated catalogues. 💅-y,--add-missing-catalogue[[<URL>]<path>/]<basename> — okay so this one is the repair bestie 💖. It builds a "repaired" archive based on the archive you handed over with the-Aoption. The repairing only kicks in for the case where an archive got interrupted anddarcouldn't cleanly finish the archive creation process (think: ran out of disk space, power outage, and so on). What it actually does: it reads the tape marks in sequential reading mode to gather up the content of the archive, and once it hits the end, it recreates the missing table of content (aka the catalogue) that lives at the end of the archive ✨. Heads up — the damaged archive is not modified, a repaired copy gets built right beside it 🫶.
Why not just append the catalogue straight onto the archive? Three reasons, bestie, and they're all valid: first, it was simpler to implement that way since it lets the code reuse routines from the merging operation; second, out of precaution so dar doesn't mess up an existing archive because of a bug 🐛; and last, it wouldn't be compatible with archive signing and gpg encryption under certain conditions (several recipients, or the archive is signed and you're not the one who signed it).
During the repairing operation, the repaired archive may have a different slicing (-s and -S options), a different encryption (-K and associated options, including gpg encryption and signing), a different repository slices permissions and ownership (--slice-mode option), user comment (--user-comment), generated hash (--hash) and min digits in slice number (--min-digits) — but compression cannot be changed and tape marks cannot be removed (you can do that once repair has completed using the merging operation). And last but very much not least: file filtering is not allowed during archive repairing 🚫.
-h,--help— shows you the help usage, literally just the rundown of how to use it 💅-V,--version— shows you the version information ✨
🦋 Remote repository syntax for [<URL>]<path> 🦋
Okay so for all the commands described above, plus some options detailed below (the -A and -@ options), that <path> optional argument can totally be a Unix path like /var/tmp when the archive is sitting on the same host dar is running on. But bestie, it can also use a <URL> to define the remote host the archive is to be read from or written to 🌈. The "<URL><path>" combo follows the usual syntax:
proto://[login[:password]@]hostname[:port]/path
proto— it's eitherftporsftp💫login— optional, and if you don't provide it, it defaults toanonymous. Fun fact: if the login string comports an@, it needs to be escaped by\\(a pair of backslashes) so libdar doesn't go thinking that's the hostname starting part 🙈. Example: login isme@here.comand host iswww.example.org, so you getsftp://me\\@here.com@www.example.org/some/file. You may also need to escape any other special characters the same way, like for example colon (:) or slash (/) if they're part of the login string.password— if a login is provided, the associated password may be given after a colon (:), but ngl that exposes the secret password to other users of the current system who can access the table of process (usingtop,ps,/procor other ways) 😭. If the login is given without a password, the password will be asked interactively bydarat run time, which is much more secure 💖. Alternatives: either rely on~/.netrcfor FTP transfers (for that you need to use the--alter=file-authenticationoption described below), or for SFTP transfers you can rely on public key authentication (you also have to use--alter=file-authenticationin that case to avoid a password being asked interactively) 🔐.hostname— the name or IP address of the host to connect to. Forsftp, the server's public key gets checked against the~/.ssh/known_hostsfile (or the file pointed to by the environment variableDAR_SFTP_KNOWNHOST_FILE, see more details about that variable at the bottom of this man page) — the host must be known and the public key received from the network must match the one in that file, elsedaraborts 💀. So if you wanna operate with a new sftp server, first usesshorsftpcommands to do the usual fingerprint verifications which updates theknown_hostsfile accordingly, then run dar/libdar toward this sftp server 👑.port— if you don't provide it,darwill use the default/standard port in regard to the protocol specified in the"proto"field 🌸path— a unix path where the archive resides that you wanna read from the remote repository, or where to write the archive to in that remote repository. The given path is absolute, in regard to the remote root filesystem available for the given account through the requested protocol. See also--network-retry-delayoption below ⭐.
🌈 GENERAL OPTIONS 🌈
-v,--verbose— for backward compatibility, this is literally just an alias to"-vt -vm"(both options set) 💅-vs,--verbose=skipped— shows you the files that got skipped because of file filtering exclusion specified by the user 👀-vt,--verbose=treated— shows you the treated files because of file filtering inclusion specified by the user, or because no file filtering was specified at all. For each file, a message gets displayed before the file is treated ✨. Heads up: this option is not available for archive isolation and it's useless for archive listing since it's always set there — unless-qis used 🙈.-vd,--verbose=dir— shows you the directory under process. The messages show before entering a directory, so you can get a less verbose output than-vtwhile still being able to follow whatdaris doing 🦋. Note that-vtand-vdare mutually exclusive — pick a lane bestie.-vm,--verbose=messages— shows detailed messages about whatdaris currently performing, but not related to the currently treated or skipped files and directories 💬-vf,--verbose=finished— issues a summary after each treated directory, containing the amount of data backed up in that directory as well as the average compression ratio 📊. This one is only available for archive creation.-va,--verbose=all— is equivalent to-vm -vs -vt, see also the-Qand-qoptions below. Note: when usingdarfrom a script, better use dar's exit status to know which way the operation has ended (see EXIT CODES at the end of this document) 👑-vmasks,--verbose=masks— displays raw information about the masks set bydarand passed to libdar 🎭-avc,--alter=verbose-libcurl— activates verbose output from libcurl (that's the remote repositories context, iykyk). Consider this a debug option relative to remote connection problems 🐛-q,--quiet— suppresses the final statistics report 🤫. If no verbose output is asked beside this option and-qcrypto(see below), literally nothing is displayed if the operation succeeds. When usingdarfrom a script, better use dar's exit status to know which way the operation has ended (see EXIT CODES at the end of this document) 💅-qcrypto,--quiet=crypto— disables the warning that shows when reading a ciphered backup about the impossibility to detect a wrong key 🔑-b,--beep— makes the terminal ring when user action is required (like for example the creation of a new slice using the-poption) 🔔-B,--batch <filename>— in the file whose name is given as argument to this option, you can put any option or argument as used on the command line, and it'll be parsed as if they were in place of the"-B <filename>"option ✨. This way you can overcome the command line size limitation 💪. Commands in the file may be spread over several lines, and the-Boption can also be used inside files, which leads a file to include other files. But an error occurs in case of a loop (a file that includes itself, directly or not) and DAR aborts immediately 💀. Comments are allowed, and must start by a hash#character on each line. Note that for a line to be considered as a comment, the hash character must be the first character of the line (space or tab can still precede the hash though). See Conditional Syntax below for a richer syntax in this type of configuration files known as DCF file (Dar Configuration File) 📁. See also the environment variableDAR_DCF_PATHin the ENVIRONMENT section at the end of this document.
Note that you can use quotes simple (´arg´), double ("arg") and back-quotes (`arg`) inside such a file, but they need to be balanced (have an ending one) 🙏. To use such a character without the meaning of a quote — for example as an apostrophe — you need to escape it using a backslash ("That\'s an example"). And of course, to add a single backslash as a normal character in the file you'll have to double it ("c:\\windows" for example) 💅
-N,--noconf— do not try to read either~/.darrcor/etc/darrcconfiguration files 🚫. See the files section below.-Q— so when dar gets launched from somewhere that is not a terminal (cronjob energy 💀), it normally spits an initial warning onto stderr. This flag tells it bestie, don't. But ngl, there's a catch: every question dar would ask the user gets auto-answered with'no', and most of the time that just aborts the program. Also heads up — you literally cannot use this option inside a configuration file (the-Boption). And since version 2.2.2, giving this option also forces the non-interactive mode, even if dar is launched from a terminal — which makes it possible for dar to run in the background ✨. When you do that, it's recommended to also redirectstdoutand/orstderrto files:
dar -Q ... &> /dev/null &
-n,--no-overwrite— do not allow overwriting. Plot twist though 🎀: if an overwriting policy is specified (peep the-/option), then-nonly applies to slices overwriting — the overwriting of files during restoration or merging is handled by the overwriting policy instead. If there's no overwriting policy,-napplies to restored files as well as generated slices. iykyk 💅-w,--no-warn— no warning before overwriting (this applies to slice overwriting and to overwriting decisions made by the overwriting policy). By default overwriting is allowed, but dar does issue a warning before proceeding. This option may receive'a'as argument 👀 (see just below):-wa,--no-warn=all— this implies the-woption, and on top of avoiding warning for file overwriting, DAR also avoids signaling a file about to be removed when its type is not the expected one. Here's the lore 📖: files are removed when they have been recorded as deleted since the archive of reference. At restoration of the differential archive, if a file of the given name exists, it is removed, but if the type does not match the file that was present at the time of the archive of reference (directory, plain file, fifo, socket, char or block device, etc.), a warning is normally issued to prevent the accidental removal of data that was not saved in the backup of reference. (See also-koption)-A,--ref [[<URL>]<path>]/<basename>— depending on the context, this specifies the archive to use as reference, which is mandatory for archive isolation (-Coption) and merging operation (-+option). Otherwise it specifies the rescue catalogue to use when restoring (-xcommand), testing (-tcommand) or comparing (-dcommand) an archive. All slices of the reference backup are expected to be on the same directory given by<path>, or the current directory by default. Usually only the last slice is required to extract the catalogue of reference ✨. If necessary, the use of symbolic links is also possible here, to gather slices that do not reside in the same directory. You can also point<path>to a USB key, DVD-R(W) or any other mounted directory, because dar will pause and ask the user for required slices if they are not present 🙈.
The argument to -A may be of four types:
- An existing archive basename, which will be taken as reference
- a dash (
"-"). In direct access mode (default mode, when--sequential-readis not used) it may imply the use of-oand-ioptions — this allows the archive of reference to be read from a pair of pipes withdar_slaveat the other ends. Dar_slave can be run through ssh on a remote host for example. Note that this type of argument ("-") is only available when-Ais used for isolation (-Coption) and merging (-+options). In sequential mode (--sequential-readis used), the archive of reference is read from standard input or from the named pipe specified by-ioption;-ooption has no use in sequential mode. Note that merging operation (-+option) cannot read archive of reference in sequential mode. - a plus sign (
"+") which makes the reference be the current directory status. This argument is only available for archive creation (-coption). In other words, no file's data will be saved — just the current status of the inodes will be recorded in the catalogue. This feature is known as the "snapshot" backup. A snapshot backup can be used as reference later on to detect or save only the files that have changed since the snapshot was made 👑 - a
<date>, if-afoption has been placed before-Aon the command-line or in an included file (see-Boption). For more about that feature see-afoption below.
During backup operation (-c option) the archive of reference, given thanks to the -A option, is used for comparison with existing files on the filesystem. Dar will then backup only files that have changed since the archive of reference was done 💖. If no -A option is given, the backup operation is a full backup. With -A option, if the archive of reference is a full backup, some call it a differential backup, while if the archive of reference is a differential backup, some call this type of backup an incremental backup. For dar there is no difference in structure between incremental and differential backup — both are usually designated globally as "differential" backup in the documentation. periodt. 💅
During merging operation (-+ option), the contents of the -A given archive will be taken eventually with the contents of the -@ auxiliary archive if specified (see below), to form a new archive from files of this or these archives. Note that you can filter out files from the operation and set up subset of the original archive(s) 🎀
During Catalogue isolation (-C option), dar will create the isolated catalogue from the one given with -A option.
During testing, diff or extraction (-t, -d or -x options respectively), the table of contents (the catalogue) will be read from the archive given with -A instead of using the internal catalogue of the archive. The archive given for rescue must have been previously isolated from this same archive (else the contents will not match and dar will refuse to proceed to this operation) 🚫. This acts as a backup solution to the case of corruption inside an archive's catalogue, while the best way is still to use Parchive to protect your data against media error ⭐
-af,--alter=fixed-date— this one modifies the-Aoption's behavior, making it receive a<date>as argument instead of the default[<path>]/<basename>argument. Available for archive creation (-coption) and archive restoration from adar_managerdatabase (see-aefdoption). Either way, it must be placed before the-Aoption to have any effect 👀
For archive creation, the <date> is used to define which files to save: files whose modification is newer or equal to <date>, and which to consider unchanged: those older than <date>.
For archive restoration from a dar_manager database, the given date defines the latest state into which to restore the data and EA. Without this option, the most recent available state is restored.
The <date> is passed to the -A option (which must follow the -af option) and is expected to be a date in the two following possible formats:
- a number of second since Jan 1st, 1970
- a date with the following structure
[[[year/]month/]day-]hour:minute[:second]
Here are some examples of date:
"-af -A 91836383927108078""-af -A 2005/11/19-19:38:48"Which is 38 past 7 PM and 48 seconds, the 19th of November 2005"-af -A 20:20"Which is 20 minutes past 8 PM of the current day"-af -A 2-00:08"Which is 8 minutes past noon, the second day of the current month"-af -A 2/2-14:59"Which is 1 to 3 PM, the 2nd of February in the current year
oh and real quick, about that date — it's relative to the system timezone, which gets overridden if the TZ environment variable is set (go peek at tzselect(1) if you want the full tea ☕).
-@,--aux [[<URL>]<path>]/<basename>,--on-fly-isolate [<path>]/<basename>— this one's a double agent bestie, fr. It names either an auxiliary archive of reference (that's the merging context) or the name of the on-fly isolated catalogue (that's the creation context). So it's only on the menu when you're using-+(merging) or-c(archive creation). And yes,--auxand--on-fly-isolateare literally aliases of the same single option — it's the context you're in (creating vs merging) that makes it act one way or the other. 💅
Merging era: on top of -A, which is mandatory here, you can hand over a second archive of reference using -@. Boom — now you can merge two archives into one single archive. Also go look at -$ (encryption), -~ (command execution) and -% (crypto block size), because those are the other options that deal with the auxiliary archive of reference. They are the respective equivalents of the -J, -F and -* options, except relative to the archive you gave with -A. 🫶
Backup era: in a backup context, -@ lets you specify the archive name for an on-fly isolation. With on-fly isolation you can also use -$ (to define the encryption algorithm and passphrase), -~ (to execute a command once the on-fly isolated catalogue is done) and -% (crypto block size). The on-fly isolated catalogue is always bzip2 if possible, else gzip, else lzo compressed (at compression level 9), else not compressed at all — and it is also always a single sliced archive. Because command lines have, like, zero room to breathe, you cannot change the compression algo or the slice size for on-fly isolation. 😭
Need something fancier? Either go hunt for a GUI built over libdar, or just do a normal isolation — meaning a not-on-fly one. (Side note, you can absolutely isolate an already-isolated catalogue; it's basically a copy, but you get to switch up the encryption, compression or slicing if you want. Slay.) You can also use dar_xform on an isolated catalogue if all you wanna change is the slices size — that path is faster, since no decompression/re-compression and no encryption/decryption is needed. 🧚
Real talk: if you use the merging operation on an isolated catalogue instead of isolating the isolated catalogue, the resulting archive won't be usable as a rescue for the internal catalogue of the original archive. Don't do it accidentally, bestie. 💀
Also --aux-ref is a synonym for --aux.
-R,--fs-root <path>— this path points at the directory tree that holds all the files getting enrolled in the operation (backup, restoration, or comparison). By default it's the current directory. Every other path you use with-Por-gon the command line is — and must be — relative to this path (or relative to the current directory if-Risn't around). Heads up:-Ris useless for testing (the-toption), isolation (the-Coption) and merging (the-+option). Also check out-ap. ✨-X,--exclude <mask>— the mask is a string with wildcards (think*and?, see glob(7) for the details) and it's applied to filenames that aren't directories. If a file matches the mask, it's excluded from the operation, periodt. By default (no-Xanywhere on the command line), nothing gets excluded.-Xcan show up several times, and in that case a file won't be considered for the operation if it matches at least one-Xmask. See also-arand-am. 🦋-I,--include <mask>— same deal, mask applied to filenames that aren't directories (glob(7) has the wildcard lore). If a file matches the mask and doesn't match any mask given with-X, it gets selected for the operation. By default (no-Iand no-X), all files are included.-Ican also appear several times — in that case every file matching one of the-Imasks will be considered for the operation, as long as it doesn't also match one of the-Xmasks. See also-arand-am. 🌸-P,--prune <path>— don't consider the file or directory sub-tree at that path.-Pcan appear several times on the command line. How it differs from-X: the mask isn't applied to just the filename, it takes the path into account too. And on top of that, it applies to directories as well (-Xdoes not 👀). By default (no-Pon the command line), no sub-tree or file is excluded, and the whole directory tree (as indicated by-R) is considered. Also,<path>may contain wildcards like*or?— see glob(7) or regex(7) for more, plus-arif you want regex instead of glob expressions. 🔥-g,--go-into <path>— the files or directory to only take into account, i.e. the opposite vibe of-P.-gcan be used several times on the command line. Same situation as before: the difference from-Iis that the mask is applied to path+filename and it also concerns directories. By default every file under the-Rdirectory is considered. Otherwise, if one or more-goptions are given, only those get selected (so long as they don't match any-Poption). Every path you give this way must be relative to the-Rdirectory, which defaults to the current directory.
Warning: -g cannot receive wildcards. They will not be interpreted. Not even a little. 🙈
-[,--include-from-file <listing_file>[:<eols>]— files listed in the listing file get included in the operation. No wildcard expression is interpreted inside that listing file.<eols>is expected to be a comma separated list of End Of Line Sequences. If you don't specify<eols>, then lines in the listing file have to be separated by either the'\n'or the'\r\n'sequence of characters — which is the same as passing<listing_file>:'\n','\r\n'. You can provide as many sequences as you want, but the longest match always wins if two sequences share the same beginning. 💅
If your filename contains a colon (:) you must add an eols, or the default one: <filename_with_colon>:'\n','\r\n'. If your eols needs to contain a comma (,) or a backslash (\), escape it with a backslash: '\,' and '\\'. Quotes around eols may be necessary so the shell doesn't interfere with them. And since release 2.8.0 the limit on line size has been removed, so you can use arbitrarily long lines if you need to. ✨
Now, this option applies to any files and directories exactly like -g does — but with one important difference: -g only uses relative paths to the root directory (the one you gave with -R), while -[ can use absolute paths too, but only for operations that have an fs_root argument (archive creation, comparison, extraction, and so on — not archive listing, testing and merging). Another difference: when the argument is a directory, -g will include all the subdirectories under that directory, whereas if the same entry shows up in a listing file given to -[, only that directory gets included — no subdirectory or subfile gets enrolled in the backup. With -[ you have to list the exact set of files you want to back up. So yes, you can generate a listing file with:
find / -print > somefile
and hand that generated somefile to -[ as its argument. 💜
But note: dar will never save files outside of the root directory tree you gave with-R, even if some of them are listed in thesomefilefile. Never ever. 🚫
-],--exclude-from-file <listing_file>[:eols]— files listed in the listing file get excluded from the operation. If a directory is listed in the file, all of its contents get excluded. This option is the exact opposite of-[and it behaves the same way-Pdoes (in particular, it's compared against the whole path+filename and it applies to files and directories). Same as with-[, the-]listing file can contain absolute paths, but wildcards are not expanded there either. 🎀
🌈 File selection in brief:
OK so real talk bestie, let's talk about which files actually get picked for the operation, because this is where the drama lives 💅
So like, <pink>-I</pink>, <pink>-X</pink>, <pink>-P</pink>, <pink>-g</pink>, <pink>-[</pink> and <pink>-]</pink> are the options that decide which files get operated on. But here's the tea: <pink>-I</pink> and <pink>-X</pink> only look at the name of files and do not apply to directories, whereas <pink>-P</pink>, <pink>-g</pink>, <pink>-[</pink> and <pink>-]</pink> use the filename and the path — so they do apply to directories. 🌸
Since version 2.2.0 there are two whole modes of interpreting these options: the normal original method, and the ordered method.
✨ the normal method (the default, and the one we've been yapping about) ✨
A directory is elected for operation if no <pink>-P</pink> or <pink>-]</pink> option excludes it. If at least one <pink>-g</pink> or <pink>-[</pink> option is given on the command line, then one <pink>-g</pink> or <pink>-[</pink> option must cover it, else it is not elected for operation. If a directory is not selected, no recursion is done in it — the directory is pruned, bye girl ✂️. For non-directory files, the same is true (P, <pink>-g</pink>, <pink>-[</pink> and <pink>-]</pink> do apply) and a second test must also be satisfied: no <pink>-X</pink> option must exclude the filename, and if at least one <pink>-I</pink> option is given, one must match the given filename (using or not wildcards).
🔥 the ordered method (when -am is given on the command line) 🔥
The ordered method takes care of the order of presence between <pink>-X</pink> and <pink>-I</pink> on one hand, and of <pink>-P</pink>, <pink>-g</pink>, <pink>-[</pink> and <pink>-]</pink> on the other hand. (Side note bestie: it also has the same action concerning EA selection when using <pink>-u</pink> and <pink>-U</pink> options, but that's no more file selection, okay?) In the ordered method the last argument takes precedence over all the previous ones. Let's take an example:
-X "*.mp?" -I "*.mp3" -I "toto*"
Here dar will include all files except files of name "*.mp?" (those ending with "mpX" where X is any character), but it will however include those ending with ".mp3". It will also include files which name begin by "toto" whatever they end with. This way, "toto.mp2" will be saved (while it matches "*.mp?" it also begins by "toto") as well as "toto.txt" as well as "joe.mp3" (while it matches "*.mp?" it also ends by "mp3"). But will not be saved "joe.mp2" (because it does not begin by "toto", nor ends by "mp3", and match "*.mp?" mask). As we see, the last option (-I or -X) overcomes the previous one. <pink>-P</pink>, <pink>-g</pink>, <pink>-[</pink> and <pink>-]</pink> act together the same, but as seen above they do not only act on filename, but on the whole path+filename. Note that (-g, -P, -[, -]) and (-X, -I) are independent concerning their relative order. You can mix -X -I -g -P -] -[ in any order, what will be important is the relative positions of <pink>-X</pink> options compared to <pink>-I</pink> options, and the relative positions of <pink>-g</pink>, <pink>-[</pink>, <pink>-]</pink> and <pink>-P</pink> options between them.
In logical terms, if <prev_mask> is the mask generated by all previous mask on the command line, <pink>-I <mask></pink> generates the new following mask: <prev_mask> or <mask>. While <pink>-X <mask></pink> generates the new following mask: <prev_mask> and not <mask>. This is recursive each time you add a <pink>-I</pink> or <pink>-X</pink> option. Things work the same with <pink>-P</pink>, <pink>-g</pink>, <pink>-[</pink> and <pink>-]</pink> options.
This ends the file selection explication, let's continue with other options 💖
-u,--exclude-ea <mask>— Do not consider the Extended Attributes (EA) that are matched by the given mask, bestie. By default, no EA are excluded, if the support for EA has been activated at compilation time. This option can be used multiple times. ✨-U,--include-ea <mask>— Do only consider the EA that match the given mask. By default, all EA are included if no<pink>-u</pink>or<pink>-U</pink>option is present and if the support for EA has been activated at compilation time. This option can be used multiple times. See also the<pink>-am</pink>and<pink>-ae</pink>options, they also apply to<pink>-U</pink>and<pink>-u</pink>options — and read below the Note concerning EA. 👑
🦋 Note concerning Extended Attributes (EA) 🦋
Support for EA must be activated at compilation time (the configure script tries to do so if your system has all the required support for that). Thus you can get two binaries of dar (of the same version), one supporting EA and another which does not (dar -V to see whether EA support is activated). The archives they produce are the same and can be read by each other. The only difference is that the binary without EA support is not able to save or restore EAs, but is still able to test them and list their presence. 🫶
In the following, when we will speak about Extended Attribute (EA) or EA entry, we will only consider a particular Extended Attribute key and its value. By opposition, the set of all EA associated to a file will be designated by "EA set". 💜
Since version 2.3.x the name of EA entries include the namespace, for dar to be able to consider any type of EA (not only "system" and "user" as previously). Thus the two previous options <pink>-u</pink> and <pink>-U</pink> have changed and now take an argument which is a mask applied to EA entry names written in the following form namespace.name where "namespace" is for example "user". Note that the mask may or may not include the dot (.) and may match arbitrary part of the EA namespace+name — just remind that masks will be applied to the "namespace.name" global string. 🎀
The <pink>-am</pink> flag here also enables the ordered method, for EA selection too. The ordered versus normal method has been explained above in the file selection note, with some examples using <pink>-X</pink> and <pink>-I</pink>. Here this is the same with <pink>-U</pink> and <pink>-u</pink>, (just replace <pink>-X</pink> by <pink>-u</pink> and <pink>-I</pink> by <pink>-U</pink>, the corresponding mask will apply to Extended Attribute selection in place of file selection). 🔥
Another point, independently of the <pink>-am</pink> option, the <pink>-ae</pink> option can be used at restoration time only. If set, when a file is about to be overwritten, all EA will be first erased before restoring those selected for restoration in the archive (according to the <pink>-U</pink> and <pink>-u</pink> options given). If not set, the EA of the existing file will be overwritten, those extra EA that are not in the archive or are not selected for restoration in regard to the <pink>-u</pink> and <pink>-U</pink> options will be preserved. If you have not used any <pink>-u</pink>/<pink>-U</pink> option at backup time and want to restore from a set of full/differential backups the EA exactly as they were, you have to use <pink>-ae</pink> for dar removes the EA before overwriting their set of EA as stored in the archive. Without <pink>-ae</pink> option dar will simply add EA to existing ones, thus get a different set of EA for a given file than those recorded at the time of the backup. 😭
Last point: the <pink>-acase</pink> and <pink>-an</pink> options alters the case sensitivity of the <pink>-U</pink> and <pink>-u</pink> masks that follow them on the command-line/included files, as they do for <pink>-I</pink>, <pink>-X</pink>, <pink>-P</pink>, <pink>-g</pink>, <pink>-[</pink> and <pink>-]</pink> as well. Very last point ;-) — if <pink>-ac</pink> option is used during backup, dar set back the atime after having read each file (see <pink>-aa</pink>/<pink>-ac</pink> options), this has as side effect to modify the ctime date of each file. But ctime change is used by dar to detect EA changes. In brief, the next time you backup a file that had to be read (thus which contents changed), its EA will be saved even if they had not changed. To avoid this side effect, don't use the <pink>-ac</pink> option if not necessary. 💀
This ends the Extended Attribute selection explication, let's continue with other options 🌈
-4 --fsa-scope <family>[,<family>[, ...]— Reduce the scope of Filesystem Specific Attribute (FSA) to be considered for the operation. FSA are grouped by family. Current available families are:extX— this family takes care of Linuxext2/3/4flag attributes set bychattr(1)and read bylsattr(1). Dar only considers flags that are possible to set or clear by users (or privileged user):append-only,compressed,no_dump(Yes, dar can save files having thenodumpflag set and restore then afterward with that flag set!),immutable,data-journaling,secure-deletion,no-tail-merging,undeletable,noatime-update,synchronous-directory,synchronous-update,top-of-directory-hierarchy. Note that"extx"and"ext"are aliases for this FSA family. In spite of its name, this family of attributes is not limited toext2/3/4filesystems. 🌸HFS+— this family takes care of Mac OS X HFS+ birth date of files, in addition of commonly found dates likeatime(last access time),ctime(last meta data change) andmtime(last data change). 🍓none—"none"is not a FSA family but can be used alone to ignore all FSA families. 🧚
By default no restriction is done and FSA of all families are considered at restoration time, but if a family has not been activated at compilation time a warning is issued for each file that cannot have its FSA restored completely (unless this family is excluded from the scope thanks to the <pink>-4</pink> option). At backup time, if an FSA family has not been activated at compilation time, no warning is issued and FSA of that family are ignored. Still at backup time, you can also ignore FSA that have compilation time support by excluding them from the operation thanks to this <pink>-4</pink> option.
Example of use: --fsa-scope extX,HFS+ ✨
-am,--alter=mask— flips on the ordered mode for mask, and bestie this one is a whole vibe shift for how your filters get read. It changes the way-Iand-Xare interpreted, and it also touches-g,-P,-[and-], plus-Zand-Y, plus-Uand-u. It can go absolutely anywhere on the command-line (main character energy, no fixed seat) and it can only be placed once. The "file selection in brief" paragraph above has the full deep-dive if you want the lore. Heads up: it also has an incidence on the--backup-hook-excludeand--backup-hook-includeoptions. 🫶-an,--alter=no-case— sets the filters to case insensitive mode. Plot twist: this only concerns masks specified after this option (peep the-acaseoption right below, you'll want it). It changes the behavior of-I,-X,-g,-P,-Z,-Y,-uand-U.
⚠️ Warning: case insensitivity requires interpreting filenames, and that depends on the locale with which dar is run (defined by theLANGenvironment variable). Example time: if you create files withLANGset tofr_FR.UTF-8and you use non plain ASCII characters in a filename, there's chances that these non ASCII characters will be stored over several bytes in that filename — the so called "wide characters". If you then run dar withLANGset to another value likeru_RU.koi8r, there is much chances that these wide characters do not correspond to the same letter, or worse, that they do not match any valid wide character for that locale. A filename is always a sequence of bytes and always saved as such, but using--alter=no-caseimplies interpreting that sequence in a way that depends on the given locale (as defined by theLANGenvironment variable). So dar cannot know if a given file has to be read withfr_FR.UTF-8locale or withit_IT.iso88591orru_RU.koi8rand so on, because this information is not stored in filenames. Consequences, fr fr: if different locales are used on your system and you are doing a system wide backup, using the--alter=no-caseoption may lead dar to detect invalid wide character, and in that case it falls back to a byte by byte case sensitivity comparison (ASCII characters), which may not be what you would expect at first sight. Most of the time, an upper case wide character (stored on several bytes) does not match the equivalent lower case wide character (several bytes too), when case sensitivity comparison is performed byte by byte. 💀
-acase,--alter=case— and we're back, sets back to case sensitive mode for filters. Every following mask is case sensitive, all the way to the end of parsing or up to the next-anoption. This changes the behavior of-I,-X,-g,-P,-Z,-Y,-uand-Uoptions. 🎀-ar,--alter=regex— switches the filters to be interpreted as regular expressions (man regex(7)) instead of the default glob expression (man glob(7)). This modifies the-I,-X,-g,-P,-Z,-Y,-uand-Uoptions that follow, up to an eventual-agoption (which is literally the next bullet, stay with me). Notable detail: for the-Poption, the given mask matches the relative path part of the files path — let's take an example, assuming you have provided/usr/localto the-Roption, the mask^foo$will be replaced internally by^/usr/local/foo$while the maskfoo$will be replaced internally by^/usr/local/.*foo$. Slay. ✨-ag,--alter=glob— this option returns to glob expressions mode (which is the default, btw 💁) after an-aroption has been used. It applies to any-I,-X,-g,-P,-Z,-Y,-uand-Uoptions that follow, up to an eventual new-aroption (see just above).-i,--input <path>— this one is available when reading from pipe (basename is-for-x,-l,-t,-dor for-Awhen-c,-Cor-+is used). Normally when reading from pipe, standard input is used, but with this option the file<path>(usually a named pipe) is used instead. This option is there to receive output from thedar_slaveprogram (seedoc/usage_notes.htmlfor examples of use). 👑 Note that when--sequential-readis used, dar uses a single pipe and does no more rely ondar_slave— the-ioption can be used to tell dar which named pipe to read the archive from, instead of the standard input.-o,--output <path>— available when reading from pipe (basename is-for-x,-l,-t,-dor for-Awhen-c,-Cor-+is used). When reading from pipe, standard output is used to send requests todar_slave, but with this option the file<path>(usually a named pipe) is used instead. When standard output is used, all messages goes to standard error (not only interactive messages, so like… everything 🌸). Seedoc/usage_notes.htmlfor examples of use. This option is not to be used in--sequential-readmode.-O,--comparison-field[=<flag>]— when comparing with the archive of reference (-c -A) during a differential backup, when extracting (-x) or when comparing (-d), do only considers certain fields. The available flags are:ignore-owner— all fields are considered except ownership. This is useful when dar is used by a non-privileged user. It will not consider a file has changed just because of a uid or gid mismatch, and at restoration dar will not even try to set the file ownership. 🫡mtime— only inode type and last modification date is considered as well as inode specific attributes like file size for plain files. Ownership is ignored, permission is ignored. During comparison, difference on ownership or permission is ignored, and at restoration time dar will not try to set the inode permission and ownership.inode-type— only the inode type is considered. Ownership, permission and dates are ignored. Inode specific attributes are still considered (like file size for plain files). So comparison will ignore differences for ownership, permission, and dates, and at restoration dar will not try to set the ownership, permission and dates.
When no flag is provided to this option, the -O option acts as if the ignore-owner flag was set, which is the behavior in older releases (< 2.3.0). 📌 Note also that for backward compatibility, the --ignore-owner option still exists and since version 2.3.0 is just an alias to the --comparison-field=ignore-owner option. Of course, if this option is not used, all fields are used for comparison or restoration.
-H[num],--hour[=num]— if-His used, two dates are considered equal if they differ from an integer number of hours, and that number is less than or equal to[num]. If not specified,numdefaults to1. This is used when making a differential backup, to compare last_modification date of inodes, at restoration or merging time if overwriting policy is based on file's data or EA being more recent and last, and when comparing an archive with a filesystem (the-doption). It's a workaround for some filesystems (like Samba filesystem) that seems to change the dates of files after having gone from or to daylight saving time (winter/summer time, the eternal struggle 😭). 🌈 Note that the-Hoption has influence on the overwriting policy (see the-/option) only if it is found before on command-line or in an included file (using the-Boption).-E,--execute <string>— the<string>is a user command-line to be launched between slices. For reading an archive (so using-t,-d,-lor-xcommands), the given string is executed before the slice is read or even asked for; for writing an archive instead (so using-c,-Cor-+commands), the given string is executed once the slice has been completed. Some substitution macros can be used in the string, and they're lowkey iconic:%%will be replaced by%%pwill be replaced by the slice path%bwill be replaced by the slice basename
%n— gets swapped out for the slice number (the one being read, or the one that just got written). Here's the drama: when dar is reading, it usually needs the last slice, but at the start it has literally no idea what number that is 😭. So it peeks in the current directory, and if the slice isn't chilling there, it calls your user command-line with%nset to0. That's the little bat-signal 🦇 telling your command "bestie, go fetch the last slice for me." If after running the string the requested slice still isn't there, dar just does what it always does — asks you on the terminal. Once the last slice is located, the user command-line gets called a second time, this time with%nequal to the actual value of the last slice number. ✨%N— same as%nbut it's the slice number with the leading zero, exactly like the--min-digitsoption defines it. If you never used--min-digits, then%Nand%nare literally the same thing. 💅%e— gets replaced by the slice extension (and it's always substituted with"dar").%c— gets replaced by the context. There are actually three possible values, and yes this is giving lore:"init","operation"and"last_slice". 🎀 When you're reading an archive (testing, extraction, diff, listing, or reading the reference archive — see the-Foption further down), the"init"context runs from the very beginning up until the catalogue is retrieved. On a multi-slice archive that lines up exactly with the last slice request. After that point you're in"operation"context. When you're creating an archive, the context is always"operation"— except once the last slice has been created, when it flips to"last_slice". so many moods 🌈%u— gets replaced by the full URL of the path where the slice is stored.
Okay so you can hand over several -E options, and the commands you give will be called in the order they show up on the command line, plus whatever -B pulled in from included files. 📋 Heads up though: -E script1 -E script2 is totally equivalent to -E "script1 ; script2". Which means if script1 fails, script2 still gets executed, and dar only ever hears about the exit status of the last -E option. Every previous -E command's exit status gets ignored. 🙈 If that's not your vibe, consider using a single -aduc option instead (that's right below, keep reading bestie). And more generally, you can use any shell construction in the argument to -E — parenthesis, ||, &&, all of it. Files you pass to -E are known as DUC files (Dar User Command). 👑 Also go check the environment variable DAR_DUC_PATH in the ENVIRONMENT section at the end of this document.
-aduc,--alter=duc— so like I said up above for-E, several-E/-F/-~options (aka DUC commands) get combined with the shell";"operator, which ignores the exit status of the first commands and only reports the last command's exit status back to dar — meaning all the commands always get executed. The--aducoption does the same but combines the different DUC commands with the shell"&&"operator instead, which only runs the next command if and only if the previous one succeeded. 💀 In other words: dar does get notified of an error in any given DUC command, but because of that error, not all the DUC commands may actually run.
--aduc changes the way the next DUC file is stuck onto the previous command, like this:
--aduc modifies the way the next DUC file is sticked to the previous
command, in other words:
dar --aduc -E script1 -E script2 ...
leads libdar to call a shell with the following line
"script1 && script2"
dar -E script1 -script2 --aduc -E script3 ...
leads libdar to call a shell with the following line
"script1 ; script2 && script3". In other words if you want
to avoid the ";" use --aduc before any -E/-F/-~ option.
-F,--ref-execute<string>— exactly like-Ebut it gets applied between slices of the reference archive (that's the-Aoption). Oh and--execute-refis a synonym. 🦋-~,--aux-execute<string>— again like-Eand-F, but this one is applied between slices of the auxiliary archive (the-@option).-K,--key [[<algo>]:]<string>-K,--key gnupg:[<algo>]:keyid/email[,keyid/email[...]]
With the first syntax, you encrypt/decrypt the archive using the <algo> cipher with <string> as the pass phrase. 🔐 An encrypted archive can only be read back if you hand over the same pass phrase (that's symmetric encryption, for the record). The available ciphers are:
"blowfish"(alias"bf")"aes""twofish""serpent""camellia"
for strong encryption, and "scrambling" (alias "scram") for a very weak encryption. ⚠️ By default, if no <algo> or no ':' is given, the aes256 cipher is assumed (it was blowfish by default up to 2.5.x). If your passwordcontains a colon ':' you need to specify the cipher to use — or at the very least use the initial ':', which is equivalent to 'aes:'. If the <string> is empty, the pass phrase will be asked at execution time. So the smallest argument -K can receive is ':', which means aes256 cipher with the pass phrase asked at execution time. 💅
WAIT. Giving the passphrase as an argument to-K(or-J, or'-$', see below) may let other users learn your pass phrase — thanks tops, ortop, for example. 😱 So it's wise to either use an empty pass, which makes dar ask for the pass phrase when it needs it, or use-K(or-J) from a Dar Command File (see the-Boption), assuming it has the appropriate permission to keep other users from reading it. And for those paranoids really concerned about their password security: having a password read from a DCF is not that secure either, because while the file gets parsed, dar makes use of "unsecured" memory — memory that can be swapped to disk under heavy memory load conditions. It's only once the passphrase has been identified that locked memory (aka secure memory) is used to store the parsed passphrase. So the most secure way to transmit a passphrase to dar, then to libdar, then to libgcrypt, is having dar ask for the passphrase at execution time — dar then makes use of secured (locked) memory from the very beginning. 🫶
Since archive format 9 (archives generated by release 2.5.0 and following), at reading time it is not necessary to provide the encryption algorithm used — just the passphrase is required, and dar will figure out which encryption algorithm had been used at archive creation time. 🕵️ You can either omit -K, in which case dar will ask for the passphrase at execution time, or you can use -K <string> in a DCF file as explained above (avoid using -K directly on the command-line).
okay so the second syntax starts with the literal word gnupg, and then a colon : right after it. In that situation, bestie, the same set of symmetric encryption algorithms as described above is available after the colon — but the passphrase is not given by the user. Instead it's randomly chosen by libdar and encrypted using the public key of the target users, whose email or keyid (keyid only since 2.7.0 💅) is given in a comma separated list. That random key gets the maximum length the cipher algorithms support, which is the whole point: maximize security. ✨
Once it's encrypted, it's placed at the beginning (unless the -at option is used) and at the end of the generated archive. Then at reading time, only the listed user(s) can read that archive, thanks to their own respective private key. 🫶
This feature implies that each user — the archive creator as well as the target users — have their GnuPG key-ring set properly. In particular:
- the archive creator must have validated the public keys of the target users, and
- the target users must own the corresponding private key in their key-ring.
Example time, because examples ate:
--key gnupg::bob@nowhere.org,joe@somewhere.com
That will generate an aes256 encrypted archive whose passphrase, randomly chosen by libdar, gets encrypted with the public keys of bob@nowhere.org and joe@somewhere.com. Wanna use blowfish in place of aes256? Say less:
--key gnupg:bf:bob@nowhere.org,joe@somewhere.com
More generally, with GPG, note that users have the duty to validate/certify that a given key-pair is really owned by the physical person you expect it to belong to. How? By checking the key fingerprint through a secure mean: face to face, a phone call if you trust that mean enough not to be intercepted and deep faked, or some other already trusted communication mean. See also the --sign option further down.
Also heads up: if you've set a passphrase on your private key, dar will ask for it dynamically, which requires dar to be run from a terminal. 🖥️ No other way has been provided to transmit a private key's passphrase to libdar. So if you want to use dar/libdar in scripts and make use of a public key algorithm, you should avoid setting a passphrase on the private key you want to use. See also GNUPGHOME in the ENVIRONMENT section at the end of this document.
Obvious but important! 🚨 To read a gnupg encrypted archive, you need your private key — not just the passphrase to activate it, if one is set. So if you plan to make a backup of your system and encrypt that backup using gnupg, you should have a copy of this private key available out of the archive (usb key, floppy, CD/DVD, ...) so you're actually able to restore your backup!
-J,--ref-key [[<algo>]:]<string>— same meaning/use as the first syntax of the-Koption, but the given key is used to decrypt the archive of reference (the one given with the-Aoption).--key-refis a synonym. Note that for archives generated using dar release 2.5.0 and above, this option is no more necessary — unless you want to give the passphrase on the command-line (not recommended 🙈) or in a DCF file (which you'd set with restricted access permissions and/or ACL).-$,--aux-key [[<algo>]:]<string>— same as-Jbut for the auxiliary archive of reference (given with the-@option). Here too, this option is no more necessary to read archives generated by dar release 2.5.0 and above.-#,--crypto-block <size>— so, to be able to randomly access data in an archive, it is not encrypted globally but block by block. You can define the encryption block size thanks to this argument, which defaults to10240bytes. Note that the syntax used for the-soption is also available here (k,M,G, etc.). Note also that crypto-block is stored as a 32 bits integer, thus a value larger than 4GB will cause an error. 🛑 And last: the block size given here must be provided when reading this resulting archive — using the-*option if the archive is the archive of reference (given to the-Aoption), using the-%options if the archive is the auxiliary archive of reference (given to the-@option), or using this-#option if it is the subject of the operation (listing, comparing, testing that archive). If the value is not the default and the given value is not correct in regard to the value given at archive creation time, the archive will not be possible to decrypt. It is thus safer to keep the default value (and not use the-#,-*,-%options at all).-*,--ref-crypto-block <size>— same as--crypto-blockbut to read the archive of reference (the-Aoption).--crypto-block-refis a synonym.-%,--aux-crypto-block <size>— same as--crypto-blockbut to read the auxiliary archive of reference (the-@option).-e,--dry-run— Do not perform any action (backup, restoration or merging), displays all messages as if it was for real (the "dry run" action). The--emptyoption is a synonym.-aSI,--alter=SI[-unit[s]]— when usingkMGTEZYprefixes to define a size, use the SI meaning: multiple of 10^3 (a Mega is 1,000,000).-abinary,--alter=binary[-unit[s]]— when usingkMGTEZYprefixes to define a size, use the historical computer science meaning: multiple of 2^10 (a Mega is 1,048,576).
The --alter=SI and --alter=binary options can be used several times on the command line. They affect all prefixes which follow — even those found in files included by the -B option — up to the next --alter=binary or --alter=SI occurrence. Note that if in a file included by the -B option an --alter=binary or --alter=SI is encountered, it affects all the following prefixes, even those outside the included files. For example, when running with the parameters -B some.dcf -s 1K, 1K may be equal to 1000 or 1024, depending on --alter=binary or --alter=SI being present in the some.dcf file. By default (before any --alter=SI/binary option is reached), binary interpretation of prefixes is done, for compatibility with older versions.
-ac,--alter=ctime— When reading a filesystem (during a backup or comparison), restores the atime of all files to what it was before the file was read. This makes it appear as if it had not been read at all. However, because there is no system call to let applications change the ctime (the last inode change) of a file, setting back the atime results in the ctime being changed (hence the namealter=ctime). Some recent unix systems allow an application to get 'furtive read mode' to the filesystem (see below). On older systems, however, for most users, having the atimes of the files changed shouldn't be a problem, since they can be changed by any other program (running by any user!) as well — like the content-index program Beagle. Ctimes, on the other hand, are the only way for security software to detect if files on your system have been replaced (by so-called root-kits, mostly). 💀
This means that, should you run dar with -ac, security software which uses ctimes to check will mark every file on your system as compromised after the backup. In short, this option should only be used by people who know what they are doing.
It's the opinion of this writer that any software susceptible to atime changes is flaky or even broken (because of the aforementioned reasons why atimes can change). But that doesn't take away that there are programs who rely on atimes remaining the same — like the Leafnode NNTP caching software. Therefore, this option exists. 💖
-aa,--alter=atime— when you pass-aa(as opposed to-ac), the atime of every single file and directory dar reads gets updated, and the ctime stays exactly the same. Basically dar itself does nothing with atimes and ctimes — it just lets the system do its thing and bump atimes whenever files get accessed for reading. Which is, like, literally what atimes and ctimes were always meant to represent. This is dar's default (since version 2.4.0), unless 'furtive read mode' (peep below 👇) is supported by your system and dar got compiled with that support switched on.
Furtive read mode is the mode where neither atime nor ctime get modified while dar reads each file and directory. Bonus: it's also faster 🏃♀️ because nothing has to be written back to disk. A known Unix kernel that supports this is Linux 2.6.8 and above (and the support has to also be in your system's standard C library for dar to be able to activate it at compilation time). When this feature is active, it becomes dar's default behavior for super user; for everybody else the default is -aa. But if you're root and you do not want furtive read mode (even though it was activated at compilation time), you can just say -aa or -ac and override it. 💅
-at,--alter=tape-marks— for archive creation and merging, the default behavior (since release2.4.0) is to add escape sequences (aka tape marks) followed by inode information all along the archive. If you give-at, dar will not add that info, which gives you a slightly smaller archive and a faster backup. When reading an archive, the default is to ignore these escape sequences and instead lean on the catalogue sitting at the end of the archive. But if--sequential-readis given on the command line (see below), dar avoids the end-of-archive catalogue and relies on those escape sequences to know what's in the archive — which means a sequential read of the archive, and that's the operation best suited for tape media.
Heads up bestie: it is not recommended to disable escape sequences (aka tape marks) with -at unless you care way more about the resulting size and execution speed of your backup (especially if you have a ton of tiny files) than about being able to recover your data when an archive is corrupted or only partially written. Without escape sequences, dar cannot sequential read an archive — and sequential reading is the only way, besides using an isolated catalogue, to use an archive whose catalogue is corrupted or that has no catalogue at all. And that whole situation happens if a system crash occurred during archive creation, or if you ran out of disk space before the archive could finish. 😭
-0,--sequential-read— this changes dar's behavior when reading an archive. By default the traditional way is used, which relies on the table of contents (aka "the catalogue") located at the end of the archive. With--sequential-readinstead, dar relies on the escape sequences inserted all along the archive with each file's inode information. That leads to a sequential reading of the archive, which is the operation suitable for tape medium. However, this feature is only available for archive format starting revision"08"(i.e.: since release2.4.0) and only if the-atoption was not used during archive creation or merging. This option works for archive testing (-t), comparison (-d), restoration (-x), listing (-l), and for reading the archive of reference (-Aoption) for isolation (-C) and archive creation (-c).
The sequential reading of an archive is always much slower than the usual reading method, so pls don't use this option unless you genuinely need it. 🐢
-9,--min-digits <num>[,<num ref>[,<num aux>]]— by default the slice number in a filename has no padded zeros, which means when you sort a directory's contents alphabetically you read all the slices starting with '1', then all the ones starting with '2'. So like: slice1,10,11,12,13, ...2,20,21,23, ... etc. Now, dar is absolutely not perturbed by this little display situation, but some users would love their slices sorted in actual order. So the--min-digitsoption lets you ask dar to prepend enough zeros in the slice number to make it as wide as the argument you passed. For example, if you give3, dar stores the slice number as001,002,003, ...999. Ok but then the next slice is1000, so the alphabetical sorting breaks again 🙃. So you're advised to pick a number big enough to cover the number of slices you expect to use.
Before release 2.7.0, when reading an archive you also had to provide this same argument, otherwise dar couldn't find the slice. Since 2.7.0 dar auto-detects the min-digits value to use — unless there's a mix of archives sharing the same basename but with different min-digits. In that conflicting scenario you must bypass the min-digits auto-detection and specify which min-digits value to retain in order to read the archive. That can optionally be followed by a comma and the number of digits to use when reading the archive of reference (the one given to the -A option), and then optionally followed by another comma and the number of digits for the auxiliary archive of reference (the one given to the -@ option).
--pipe-fd <num>— this reads further arguments from the file descriptor<num>. The arguments read through that file descriptor must follow a TLV (Type/Length/Value) list format. This option is not meant for human use, it's for other programs that launch dar, likedar_manager. It was added to get around the command line length limit. 🤖-al,--alter=lax— when reading an archive, dar will try to work around data corruption of the slice header, archive header, and catalogue. This option is meant to be your last resort when you're staring down media corruption. It is rather and still strongly encouraged to test your archives before relying on them, and also to useParchiveto make parity data for each slice so you can recover data corruption in a much more effective way with a much better chance of success. Dar also has the ability to back up a catalogue using an isolated catalogue, but that does not face slice header corruption, nor even saved file's data corruption (dar will detect such an event but it will not correct it). 💀-G,--multi-thread { <num> | <crypto>,<compression> }— when libdar is compiled againstlibthreadar, it can make use of several threads. If the argument is two numbers separated by a comma, the first defines the number of worker threads to cipher/decipher, and the second the number of threads to compress/decompress. If the argument is a single number (-G <n>), that's equivalent to giving that number as the number of compression threads and giving2for the ciphering threads (so-G 2,<n>). Using multi-threading at archive creation time leads to relying on per block compression instead of the legacy streaming compression, and if the block-size isn't specified (see the-zoption for details) it defaults to 240 KiB. Not providing any-Goption is equivalent to providing-G 2,1when libthreadar is available, else-G 1,1. And ngl, note that: if an archive was created with streaming compression, the decompression cannot use multi-threads — but the deciphering can always use multiple threads. ✨-j,--network-retry-delay <seconds>— when a temporary network error happens (no connectivity, server unavailable, and so on), dar does not give up — it waits a bit and then retries the failed operation. This option lets you change the default retry time, which is 3 seconds. If you set it to zero, libdar won't wait at all and will instead ask the user whether to retry or abort when a network error comes up. 🫶-afile-auth,--alter=file-authentication— bestie, this one is ✨the password-politeness flag✨. It only matters when you're reading or writing an archive to a remote (SFTP or FTP) repository and no password has been given. Instead of stopping to ask you interactively for a password, dar will go peek at your~/.netrcfile for credentials — but only when it's riding the FTP protocol. If it's SFTP instead, this option makes dar try public key authentication first, before it even thinks about passwords. And if the key couldn't be loaded? Then it'll ask you interactively for that key's passphrase. 🗝️-ab,--alter=blind-to-signatures— nope, we are NOT checking whether an encrypted archive with a public key that also got signed has correct signatures. Blind. Unbothered. Not looking. 🙈
💾 SAVING, ISOLATION, MERGING AND REPAIRING SPECIFIC OPTIONS (to use with -c, -C, -+ or -y) 💾
okay these ones are the backup-shaping options, the ones that only make sense when you're creating, isolating, merging or repairing. strap in. 🎀
-z,--compression={ [algo] | level | algo:level | algo:level:block-size }— this is THE compression flag, and it adds compression within slices. If you don't say-z, nothing gets compressed at all. But if you say-zwith no algorithm? Thengzipis just assumed, bestie, it's the default. 💅
Here's how the pieces work:
- algo: your options are
"gzip","bzip2","lzo","xz","zstd"or"lz4". - level: the compression level — an integer from
1to9, except for zstd which ranges from1to22. It's optional and sits at9by default. ⚠️ Be careful with thexzalgorithm: it's better to specify a compression ratio less than or equal to6, otherwise you'll have important memory requirements (translation: it will eat your RAM alive 😭). A ratio of1means less compression and faster processing, and the opposite end, a ratio of9, gives the best compression but the longest processing time. - block-size: if you set it to
0— which is also the default — you get the legacy (and performant) "streaming compression" mode, the only mode that existed up to release 2.7.0. Since then, the "block compression" mode gives you the ability to leverage multi-threading (see-Goption) by compressing per block and handing different blocks to different threads. The larger the block, the better the compression ratio will be (it tends to get as good as streaming compression mode's ratio as block size increases) — but files smaller than a block size can only be processed by a single thread. The memory requirement also increases by the product of the block size times the number of threads. Last thing: a too-small block-size will cost more CPU cycles (the multi-threading management overhead becomes important compared to the actual compression processing) and, independently, short blocks give poor compression rates. So it's advised to use values at least greater than 50 ~ 100 KiB (you can use thek,M,G,... suffixes described for the-soption). If block-size isn't specified and the-Goption leads to a number of compression threads greater or equal to 2, a block-size of240 KiBis used. And if you want the legacy streaming compression? Do not use the-Goption (or use it specifying only 1 compression thread) and do not set the compression block size (or set it to zero). easy peasy 🫶
Valid usage of -z is for example: -z, -z9, -zlzo, -zgzip, -zbzip2, -zlzo:6, -zbzip2:2, -zgzip:1, -zxz:6, -zlz4::10k, -z::12000, -zbzip2:8:10k and so on. Usage for the long option is the same: --compression, --compression=9, --compression=lzo, --compression=gzip, --compression=bzip2, --compression=lzo:6, --compression=bzip2:2, --compression=gzip:1, --compression=xz:9 and so on.
About lzo compression, here's the tea: the compression levels of dar and the lzop program do not match 🫠. If you want the behavior of compression level 1 of lzop, use the lzop-1 algorithm in place of lzo with dar/libdar. If you want the behavior of lzop compression level 3, use the lzop-3 algorithm in place of the lzo algorithm. Lzop compression levels 2, 4, 5 and 6 are the same as level 3. And last, there is no difference about compression level 7, 8 and 9 between dar and lzop. Also important: the lzop-1 and lzop-3 algorithms do not make use of any compression level (the compression level is ignored with these algorithms).
-s,--slice<number>— the size of your slices, in bytes. If the number gets ak(orK),M,G,T,P,E,Z,Y,RorQappended, then the size is in kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, zettabytes, yottabytes, ronnabytes or quettabytes respectively. Example:"20M"means 20 megabytes, which by default is the same as giving20971520as the argument (see also-aSIand-abinaryoptions). And if-sis not present at all? The backup gets written to a single slice, whatever the size of the backup may be — assuming your operating system can support arbitrarily large files. 🗂️-S,--first-slice<number>— this gives the size of the first slice, which you can choose totally independently of the size of the following slices (either bigger or smaller, your call, main character energy). This option needs the-soption. And if you don't say-S? Default behavior is that the first slice is the same size as the ones that follow it.-p [<integer>],--pause[=<integer>]— pauses before writing to a new slice (this requires-s). By default there's no pause at all: all slices are written into the same directory, up until the end of the backup or until the filesystem is full. In that latter case, the user is informed of the lack of disk space and dar stops and waits for user action. As soon as some disk space is available, you can continue the backup. 💾✨ The optional integer this option can take tells dar to only pause every 'n' slice. Giving3for 'n' makes dar pause only after slices 3, 6, 9 and so on. If this integer isn't specified, the behavior is as if'1'was given as the argument, which makes dar pause after each slice.-D,--empty-dir— at backup time only: when you're excluding directories, either explicitly with-Por-]options, or implicitly by giving-gor-[options (a directory is excluded if it does not match the mask given with-goptions or-[options), dar doesn't store anything about them. But with-D, dar stores them as empty directories. Super useful if you're excluding a mount point (like/procor/dev/pts). At restoration time, dar will then recreate these directories (if necessary). Heads up though: this option has no meaning with-Cand is ignored in that case. Independently of all that,-Dcan also be used at restoration time, but there it activates a slightly different feature (see RESTORATION SPECIFIC OPTIONS below). 🫶-Z,--exclude-compression<mask>— filenames covered by this mask do not get compressed. Only useful in conjunction with the-zoption. By default, all files are compressed (if compression is used, obviously). This option can be used several times, and in that case a file that matches one of the-Zmasks will not be compressed. The argument given to-Zmust not include any path — just the filename (eventually/probably using wildcards) 💅. Using this option while merging or repairing lets you change the compression of files.-Y,--include-compression<mask>— filenames covered by this mask (and not covered by masks given to-Zoption(s)) are the only ones to be compressed. It's only available with the-zoption. By default all files are compressed. This option can be used several times, and in that case all files matching one of the-Ymasks will be compressed, if they don't also match one of the-Zmasks. The ordered method applies here too when activated (with the-amoption) — it works exactly the same as the-Iand-Xoptions, but applies to file compression, not file selection. In other words, it matches only on the file name, not on the path of files. And like its sibling, using this option while merging or repairing lets you change the compression of files. 🌈-m,--mincompr<number>— files whose size is below this value won't be compressed. If-misn't specified it's equivalent to giving-m 100as the argument. So if you want to compress ALL files whatever their size is, you need to type-m 0on the command line. The size unit is the byte (octet), and the same number extensions used with-sor-Sare available here too, if you want to specify the size in kilobyte, megabyte, gigabyte, etc. 🍓-1,--sparse-file-min-size <number>— okay bestie this one sets the minimum run of zeroed bytes that dar is allowed to swap out for a "hole". Default vibe: this whole feature is on, and the threshold is15bytes. Wanna yeet it entirely? Set the size to0. Flipping it off gives you a noticeable speed glow-up, but your archive will probably get a lil chunky (depends on what the data's giving).
So like… what even is a sparse file?? It's a file with so-called holes in it. On a filesystem, a run of zeroed bytes just… doesn't live on disk, so a huge file that's mostly zeros might take up only a few bytes of actual storage. Iconic, honestly.
Here's the tea: dar cannot detect how a given file is allocated, because it does a filesystem abstraction (it doesn't know the internals of any particular filesystem — that's literally where its portability comes from 🫶). But when it spots a sequence of zeroed bytes bigger than your threshold, it goes "yeah that's a hole, I'm calling it" and assumes it's in the presence of one. Then instead of storing those zeroed bytes in the archive, it drops a tag next to the saved data recording the size of the hole — and thus where the next non-zeroed bytes go. Result: dar archives need way less disk space when it meets a sparse file. Slay.
At restoration time, dar restores holes by writing normal data and seeking over the hole to write the normal data after each hole. If the underlying filesystem supports sparse files, the holes get restored for real. And no cap: there's no difference for applications whether a file is sparse or not, so dar may absolutely transform normal files into sparse files and vice-versa — only the disk requirement changes. ✨
Last point, and it's a big one: even though dar can shrink the disk requirement for holes as small as 15 bytes (smaller values do work, but the overhead costs more than just storing the zeroed bytes normally 💀), it may not be the same at restoration, because filesystem allocation unit is usually several kilobytes (a page). However — promise — a restored file will never be larger than it could be without holes. The only drawback of this whole feature is the extra CPU cycles it eats.
-ak,--alter=keep-compressed— during merging and repairing, this keeps files compressed. But bestie, it comes with several restrictions:-z,-Z,-Y,-mare ignored.- If two archives have to be merged, both must use the same compression algorithm, or one of them must not use compression at all (this last restriction will probably disappear in a next version).
The advantage? Greater speed of execution, because compression is usually CPU intensive. 🔥
-ah,--alter=holes-recheck— for merging and repairing, the sparse file detection mechanism is disabled by default. But if you wanna turn it on (say you have an old archive and you wanna convert it to the current archive format while taking care of sparse files), you need-ahto reactivate the sparse file detection mechanism. Then, for merging and repairing,--sparse-file-min-sizecan be used exactly as described above for archive creation. 💅
Bonus trick: you can have files stored as sparse files in the archive of reference end up stored as normal files in the merged archive, using -ah and passing to --sparse-file-min-size a value larger than all file sizes. For example, as of today in year 2018, passing -ah --sparse-file-min-size 1E (1E for one exabyte) should be large enough. 🦋
--nodump— do not save files which have the'd'flag set (seechattr(1),lsattr(1), ext2 commands). This option may not be available if the system dar has been compiled on did not provide support for ext2 flags. 🫠
Heads up: this option does nothing with the -+ option (merging), because no filesystem is used for that operation.
-5,--exclude-by-ea[=<extended attribute name>]— excludes from backup any inodes that have been set with the EA given in argument. If no argument is given to that option, the default EA used to exclude files from backup is"user.libdar_no_backup". 🌸
To set this attribute on a given file, use:
setfattr -n user.libdar_no_backup <filename>
To remove it:
setfattr -x user.libdar_no_backup <filename>
And last, to check the presence of this EA:
getfattr <filename>
-M,--mount-points={ I:<path to fs> | X:<path to fs> }— if the argument is of theI:<path to fs>form, the filesystem that this path points to is considered for the backup operation — meaning other file filtering mechanisms get applied and some or all files of that filesystem get saved for backup. With theX:<path to fs>form, no file in that filesystem will even be considered for backup. Both theX:andI:forms must be given an absolute path. 📌
-M can be used several times on the command-line. Let's break down the vibes:
- If only
I:forms are used, the filesystem based filtering mechanism behaves as a white list (only those listed paths are included). - If only
X:forms are used, it behaves as a black list (everything is considered except those listed paths). - While a mix of
I:andX:forms are used, the filesystems considered for backup will be those given with anI:form and not also given with anX:form.
⚠️ Note that this is filesystem based filtering, not path based. If, for example, a filesystem is mounted under/vardirectory and you specifyI:/var/log, all the/varfilesystem will be considered for backup. If you'd rather only save what is in/var/log, use the-P/-g/-X/-I/-[/-]options that realise file filtering by name and path+name. 😭
You cannot exclude the filesystem which contains the path given to -R option.
The use of -M option with argument erases any previous configuration done with -M option without argument (see below), and vice versa. By default (no -M option specified), no filtering based on filesystem is performed — in other worlds, all files are considered for other file filtering mechanisms (in particular -P/-g/-X/-I/-[/-] options) and eventually backed up. ✨
Example of use:
-MI:/var -MX:/var/spool
--mount-points=I:/var --mount-points=X:/var/spool
-M,--no-mount-points— this is the legacy form of the option described just above, the one that existed before release2.7.0. 👑
When -M option is provided without argument, only files located on the filesystem pointed to by the path given to -R option will be considered for backup. Subdirectories that are mounting points for other filesystems will not be saved (or saved empty if -D option is used). This option is useless and ignored for merging operation.
The use of -M without option leads dar to ignore any previous -M I:<path> and -M X:<path> options that could have been given on command-line or -B included file so far. 💅
-,,--cache-directory-tagging— don't save contents of directories that use the Cache Directory Tagging Standard. Seehttp://www.brynosaurus.com/cachedir/spec.htmlfor details.
(this option is useless with -+ option)
-/,--overwriting-policy <policy>— this option lets the user define when or how file overwriting can occur at restoration or archive merging time. 🎀
It does not apply to slice overwriting, which are driven by the -n option — it instead applies to files during extraction, and to files inside archives when merging two of them.
When considering overwriting, a file is said to be 'in place' while another is known as 'new' or 'to be added':
- At restoration time, the
'in place'is the one present in the filesystem, while the'to be added'is the one from the archive. - At merging time, the
'in place'is the one of the-Aarchive of reference, while the'to be added'is the one from the auxiliary-@archive or reference.
This option does not apply to archive repairing.
As soon as you use -/ option, -n only applies to slice overwriting, and the -r, -k and -ae options are ignored (restoration specific options). 🙈
okay so bestie, the <policy> argument? it's literally composed of actions and, eventually, of conditional expressions. And here's the tea ☕ — those actions are the ones who decide how we solve the overwriting conflict drama between file's data on one side, and file's Attributes (Extended and Filesystem Specific, aka the whole EA + FSA situation) on the other side. So like, one action is actually a couple: one action for Data, one action for EA+FSA. Data actions are the UPPERCASE letters 🔠, EA+FSA actions are the lowercase letters 🔡, and the two are fully independent of each other — they don't text, they don't call, they're not even mutuals. 💅
P— means 'Preserve' 🫶. When you're merging two archives, the data of the resulting archive gets taken from the 'in place' file. And when you're extracting, the data of the inode in the filesystem gets preserved, which means naur, no overwriting will occur for the data. 👑O— means 'Overwrite' 🔥. When merging two archives, the data of the resulting archive gets taken from the 'to be added' file. And when extracting, the data of the inode in the filesystem gets overwritten by the data from the archive. gone, replaced, bye. 💀S— means 'mark Saved and preserve' ✨. When merging two archives, the data of the resulting archive gets marked as already saved in the archive of reference (which makes a differential archive, even if none of the original archives were differential archives, ikr 😭). All data gets dropped in the resulting archive, but the last modification date [aka mtime] — the thing used to detect change in file's data — gets taken from the 'in place' file. This action does not apply when extracting files, so in that situation it's considered equal to "Preserve" (<code>P</code>).T— means 'mark Saved and overwrite' ✨🔥. When merging two archives, the data of the resulting archive gets marked as already saved (literally same energy as the <code>S</code> action): all data gets dropped in the resulting archive, however the last modification date [aka mtime] — used to detect changes in a file's data — gets taken from the 'to be added' file this time. This action does not apply when extracting files, so it's considered equal to "Overwrite" (<code>O</code>) in that situation.R— means 'Remove' 💀. When merging two archives, the resulting archive will not contain any entry corresponding to the file that was in conflict. This also implies that no EA will be stored for that particular entry, since the entry will no more exist in the resulting archive (as if it had never yet existed, not even once, not even a little). When extracting files, this leads to file's suppression. 😭
and now the lowercase girlies, the EA+FSA squad 🎀 (all of them independent from whatever the data did, fr fr):
p— means 'Preserve', same as <code>P</code> but lowercase, and it preserves the whole EA set and FSA. When merging two archives, the Attributes set of the resulting file will be the ones of the 'in place' file (whatever the overwriting action taken for its data, like, that's a different conversation). When extracting files to the filesystem, the Attributes of the file in the filesystem will not be changed (whatever the overwriting action taken for its data — unless the file is removed using the <code>R</code> policy, which would remove the inode and thus also any Attributes it had, oop 👀).o— means 'Overwrite', same as <code>O</code> but lowercase, and it overwrites the whole EA set and FSA. When merging two archives, the Attributes set of the resulting file gets taken from the 'to be added' file. When extracting files, the Attributes set of the file in the filesystem has its Attributes erased and replaced by those of the file in the archive (still independent of what overwriting action is taken for file's data, periodt).s— means 'mark Saved and preserve', same as <code>S</code> but lowercase, for EA and FSA instead of data. When merging two archives, the EA and FSA of the resulting file are marked as already saved in the archive of reference, so they're dropped — but the date of last inode change [aka ctime] (used to detect changes in file's EA and FSA) gets taken from the 'in place' file. This action does not apply when extracting files, so it's considered equivalent to "Preserve" (<code>p</code>) in that situation.t— means 'mark Saved and overwrite', same as <code>T</code> but lowercase, for EA and FSA instead of data. When merging two archives, the EA and FSA of the resulting file are marked as already saved in the archive of reference, so they're dropped — but the date of last inode change [aka ctime] (use to track changes in EA) gets taken from the 'to be added' file. This action does not apply when extracting files, so it's considered an equivalent to "Overwrite" (<code>o</code>) in that situation.m— means 'merge Attributes and preserve' 🌸. The resulting file in the merged archive will have Attribute entries from both the 'in place' and the 'to be added' files. But if both files share a same Attribute entry (same FSA, or for EA the same key for a given association), the one of the 'in place' file is kept — which is where that whole 'preserve' notion comes from, iykyk. When extracting a file, the file in the filesystem has its EA and FSA set enriched by the ones of the file in the archive that do not exist on the filesystem, but its already existing Attributes stay untouched. no notes. 🫶n— means 'merge Attributes and overwrite' 🌸🔥. The resulting file in the merged archive will have Attribute entries from both the 'in place' and the 'to be added' files. If both files share a same Attribute entry (same FSA, or for EA the same key for a given association), the one of the 'to be added' file is kept this time — where from the 'overwrite' notion, bestie. When extracting a file, the file in the filesystem has its Attributes set enriched by ones of the file in the archive, with some of them possibly having been overwritten. 💅r— means 'remove', same as <code>R</code> but for the Attribute set (thus all EA and FSA entries) of a given file (<code>r</code> is a lowercase letter here, just to be clear 🎀). The file of the resulting archive during a merging operation will not own any EA nor any FSA, even if the 'in place' and/or the 'to be added' files did have some. For file extraction, this means the file in the filesystem will lose all its EA set. The FSA cannot be 'removed' from a filesystem and may not always have a default value, so this action does not modify FSA at all in the case of archive extraction. But in the case of merging, the FSA are removed as previously described. And as for all the previous tests, this Attribute operation is independent of the operation chosen for file's data (the uppercase letters, yes ma'am).d— means 'delete' 💀. When a same EA or FSA entry is found both in the 'in place' and 'to be added' files, such entry will be absent in the resulting archive. In other words, when merging, the EA set and FSA will only contain EA and FSA entries specific to the 'in place' and those specific to the 'to be added' file. Entries in common will not be present, they're not invited to the party. 🚫 When extracting a file from an archive, the file on filesystem has its EA set enriched by entries of the 'to be added' file that are new to the 'in place' file. The other EA entries (which are thus present in both archive and filesystem) get removed from the set, while the other FSA stay untouched (FSA cannot be "removed" from a filesystem, nor do they always have a default value — them's the rules 😤).*— lowkey the "idk yet" action, and it works for both EA and data. It's literally saying "this isn't decided at this step of the evaluation, keep going please" (thechainoperator further down is your bestie for this).A— uppercase means "Ask for user decision", and it's all about Data overwriting. An application interaction pops up and lets the user pick the action for every single file in conflict. Heads up though: if you use this bad boy on its own it can get so boring, like genuinely painful. The whole point is to drop it inside conditional statements (described below) so dar only asks about the non-obvious cases. 👑a— lowercase twin ofA, the same "ask the user" energy, but for EA and FSA instead of data. It's designed to live inside those same conditional statements.
So an action is a lil couple of two letters: first one uppercase (that's the file's data), second one lowercase (that's the file's EA and FSA). And when you don't pass a -/ option at all? The action is equivalent to -/ Pp, so dar just goes ahead and preserves file, EA and FSA. ✨
Okay history lesson bestie: before release 2.4.0 (June 2011), the only options you had to set the overwriting policy were-nand-w, and back then the default was to warn and wait for confirmation before overwriting. That behavior is what you get with the-/ Oopolicy. Apparently the default switched to-/ Ppat that time and literally nobody complained or noticed the difference until 2023. So this default is not getting reverted — twelve-plus years of silence is a vibe check it passed, fr fr.
Here's a lil sampler of actions. All of these apply to any entry found in conflict during archive merging or archive extraction — we'll get into conditional actions in a sec.
-/ Rr— makes dar remove any file from the filesystem that ought to be restored(!). Ngl the EA/FSA part of this action is useless, because the EA and FSA always get erased along with the data whenever you useR. So-/ Rpwould lead to the exact same result. 💅-/ Po— keeps the data of the 'in place' file, but takes the EA and FSA set from the 'to be added' file.-/ Ss— when you merge an archive with itself (so it's used as both archive of reference with-Aand auxiliary archive of reference with-@), this gives you the same action as an archive isolation of the archive of reference... but it uses twice the memory. So keep using the isolation operation like before! This one is purely an illustration of the possibility. 🫶
🌸 how the EA filter and the policies interact 🌸
Like we saw earlier, -u and -U filter which EA entries to consider and which to ignore. The real question is how that filtering plays with all these policies. So:
- For files that are not in conflict (found only as 'in place' or only as 'to be added'), only the EA entries matching the EA filter get kept.
- For files that are in conflict, the overwriting policy gets evaluated first, and the filtering mechanism is applied after it.
So for example, take [ -/ "Po" -u "*test" ] while merging two archives. Only EA ending with "test" are retained. And when a conflict happens, that "*test" EA comes from the 'to be added' file if it has EA of that type — every other EA entry of that file gets ignored, and all EA entries of the 'in place' file get ignored too, even the ones ending in "test". 😭
Now at restoration with those exact same options: files without conflict get restored, but only the EA entry ending with "test" gets restored. And for files with conflict (so, already present in the filesystem), the EA set of the file on the filesystem is removed and replaced by the EA entries of the file in the archive that end in "test" — if any exist.
Same situation with FSA family scope and overwriting policy: only the FSA of a family present in the scope is retained, the overwriting policy acts first, and then the FSA scope is applied. One thing though — any FSA present on the filesystem that's excluded from the FSA scope is not touched. 🙈
✨ conditional statements, aka the fun part ✨
Okay now let's bring some actual fun into all these actions using conditional statements. The structure looks like this:
{<condition>}[<action if condition is true>]
This syntax lets you drop an action (any of the ones we just looked at) inside the brackets [ and ] — like [Pp] — and it only takes effect if the <condition> evaluates to true. And since a statement like this is itself a new type of action, you've probably already guessed you can nest it recursively: {<condition1>}[{<condition2>}[<action>]). 🌀
So far it sounds useless, right? Here's the twist: instead of the "if <condition> then <action> else <action>" paradigm that programming languages use, the command line context pushed dar to use an implicit "OR" operator between actions instead. So you can stack conditional statements like this:
{<condition1>}[<action1>] {<condition2>}[<action2>] <action3>
In this example, if <condition1> is true then <action1> is used. ELSE if <condition2> is true then <action2> is used. ELSE <action3> is used. Same possibilities as programming languages, just with slightly simpler syntax. Which means the recursion thing is actually way more interesting than it looked. 🌈
For readability, you're allowed to put any spaces or tabs you want in the overwriting policy — but the resulting overwriting policy has to be given as a single argument to dar, so you will need quotes (either single ´arg´ or double "arg"). 🎀
💜 the 'chain' operator 💜
Last operator, bestie, we're almost there. Once an expression is evaluated, the resulting couple of actions may still contain a * (that's the undefined action for EA or data), and further evaluation has to happen. The chain operator, written as a semicolon ;, lets you separate several independent expressions that get evaluated in turn until the couple of actions is fully defined.
Once an action (for EA or for Data) is defined, it can be redefined by a subsequent evaluation in the chain. But if an action is defined, it cannot be set back to undefined — so * will never overwrite a previously defined action. No take-backs. 🚫
And if at the end of the policy the couple of actions still isn't fully defined? The preserve action kicks in (P or p, depending on whether it's EA or Data that's left undefined). Here's an example of the syntax:
-/ "{<condition1>}[P*] O* ; {<condition2>[*p] *o} ; Rr"
So the first expression evaluates to either P* or O*. At this step the action isn't completely defined, so the second part of the chain gets evaluated, ending with either *p or *o. In any case, after that second statement of the chain we've got a fully defined action for both data and EA (either Pp, Po, Op or Oo). So the evaluation stops right there and the "Rr" policy never gets evaluated. Slay. 💅✨
okay so now we get to the very last thing you need to know, bestie: the available conditions. Like, the stuff you drop between braces { and }. 💅 Each condition is defined by a letter, and sometimes that letter is followed by an argument tucked inside parenthesis. Simple as that.
And because conditions gotta be combined, you get the usual logical operators:
!— negation&— conjunction|— disjunction
Now listen, this part is important: these characters must be escaped or quoted so your shell doesn't go feral and interpret them when you're using them on the command-line. And lowkey the ! is the worst offender — under most shells it has to be quoted and escaped, like '{\!R}[..]..'. 💀 The escape character \ is not necessary inside DCF files though (those are the ones you hand over to the -B option), because no shell is being used to interpret those files. no cap, the file just reads them as-is. 🫶
And to the usual operators, one more has been added: the "inversion" operator, written ~. Like negation it's a unary operator, but unlike negation it inverses the roles of 'in place' and 'to be added' for the evaluation, which is slightly different from just taking the negation of the result of the evaluation. ikyk. 🌸
All of these operators follow the usual precedence:
- unary operators (
!and~) get evaluated first - then conjunction
& - then disjunction
|
To override that, you can use parenthesis ( and ) inside the condition. 🎀
Over and above these logical operators, the conditions are based on atomic operators that compare the 'in place' file to the 'to be added' file. Here they are, bestie, all of them, no skips:
I— true only if the 'in place' entry is an inode. This condition has zero consideration toward the to be added object. Note that~Ican be used to check the nature of the 'to be added' object. A 'detruit' entry — which records the fact that a file has been removed since the archive of reference — is not an inode, for example, and the only type of entry that is not an inode is a 'detruit'. So you can define an action on 'detruit' objects using the"!I"expression for the 'in place' entry and"!~I"for the 'to be added' entry. 👑D— true only if the 'in place' entry is a directory. And to find out whether the 'to be added' is a directory or not, you'd use the "inversion" operator:~D. 🌈F— true only if the 'in place' entry is a plain file (also true if this plain file is a 'hard link', that's it if its inode is linked several times to the directory tree). ✨H— true only if the 'in place' entry is an inode linked several times to the directory tree (= hard link). It may be a plain file, a Unix socket, a pipe, char device, a block device for example. 🦋A— same asH, but the current 'in place' entry is the first link we meet pointing to that hard linked inode.R— true if the 'in place' entry is more recent than or of the same date as the 'to be added' entry. The last modification date (aka mtime) is what gets used for this comparison. If the 'to be added' entry is not an inode (and thus has no mtime), then the 'in place' is considered to be more recent than the 'to be added' entry. Same thing the other way around: if the 'in place' entry is not an inode (and has no mtime available for comparison), it's here too assumed to be more recent. 🎀R(<date>)— true if the 'in place' entry is more recent than or of the same date as the fixed <date> given in argument. No consideration is done toward the 'to be added' element. The <date> format is the same as the one used with the-afoption. If an entry has no mtime (it's not an inode, for example) it is assumed a virtual mtime of zero. 💜B— true only if both 'in place' and 'to be added' are plain files (hard linked or not) and the 'in place' file's data is larger or equal to the 'to be added' file's data. If one or both entries are not plain files (or hard links to a plain file), and thus the file size comparison isn't possible, the 'in place' entry is assumed to be 'bigger' than the 'to be added' entry. 🍓S— true only if the 'in place' data is saved in the archive (not marked as unchanged, nor marked as only inode metadata changed, since the archive of reference). Note that while extracting files from an archive, the 'in place' file is the one in the filesystem, which always has its data 'saved' (from libdar's point of view). The 'inversion' of this atomic operator,~S, may still be interesting in the context of restoration. 🌟Y— true only if the 'in place' data is saved but dirty (a plain file having its data changed at the time it was read for backup). Note that restoring in sequential read mode, it is not possible to know whether a file is dirty (it is possible to know it once having read its data, but sequential reading does not allow you then to skip forward to get the dirty state of the file and skip backward to eventually restore that file, depending on the overwriting policy result). 😭X— true only if the 'in place' data is a sparse file. 🧚T— true only if the 'in place' and 'to be added' entries are of the same type (plain file, Unix socket, named pipe, block device, char device, symlink, directory, 'detruit' (which stands for a file deleted since the archive of reference was done), and so on). Note that the number of links to the inode (i.e. whether this is a hard link or not) is not taken into account. 💖L— true only if the 'in place' entry has a delta signature associated with it. 🔥P— true only if the 'in place' entry is a binary patch. ⭐E— true only if 'in place' and 'to be added' are of the same type and have the same inode data information:uid,gid, permission, modification date are taken into account;atimeandctimeare ignored in this comparison. If both are plain files, the file sizes must be the same for this condition to succeed. For char and block devices, both major and minor numbers must match. Last, for symlinks, the target (the file path they point to) must be the same. 👑e— true if the 'in place' entry has EA (may they be saved or just recorded as existing). 🌸r— true if the 'in place' entry has more recent or equal dated EA to the 'to be added' entry. If 'to be added' has no EA or is even not an inode, true is returned. If 'in place' has no EA or is even not an inode, true is returned unless 'to be added' has some EA. The comparison is done onctimedates. 🦋r(<date>)— true if the 'in place' entry has more recent or equal dated EA to the fixed <date> given in argument. No consideration is done toward the 'to be added' element. The <date> format is the same as the one used with the-afoption. If an entry has no date (ctimedate) (when it is not an inode, for example) it is assumed a virtualctimeof value zero. 💜m— true only if 'in place' has a more or equal number of EA entries in its set of EA than 'to be added' has. If an entry has no EA or is not even an inode, it is assumed it has zero entries. The comparison is done on this number. Note that the number of EA entries is not the size used to store these entries. For example, the EA entry"user.test"counts for 1, whatever is the length of the value associated to it. 🎀b— true if the 'in place' entry has a bigger EA set, or an EA set of equal size, than the 'to be added' entry. Like, if an entry has no EA at all, or isn't even an inode, bestie, we just assume it's rockin' a zero-byte-length EA set and run the comparison on that number instead. And heads up: the comparison is done on the number of bytes used to store the whole EA set attached to that file. That's the metric. That's the vibe. 💅s— true if the 'in place' entry is an inode (or a hard linked inode) and has its EA saved in the archive of reference — not just marked present, but unchanged since last backup. Note that this test literally does not look at the 'to be added' entry at all. It's a solo act. Main character energy. 👑
So yeah — you've clocked it by now, right? Uppercase letters get kept when the comparison is based on the inode or the data, while lowercase letters are for atomics based on EA. That's the whole system. 🎀 Now that we've finished our lil tour of this feature, let's look at some examples, because honestly examples >> theory:
✨ examples, bestie ✨
-/ Pp
As we saw earlier, this is exactly what the -n option does for files when no overwriting policy is defined — it avoids any overwriting for Data as well as for EA. No takebacks, no overwrites, periodt.
-/ "{!T}[Pp] {R}[{r}[Pp]Po] {r}[Op] Oo"
Spaces and tabs are allowed here, purely to make it readable for your eyes. 👀 So what does this policy actually mean? Here's the tea: if the files in conflict are not of the same type, then keep the Data and EA of the entry 'in place'. Else, if 'in place' has more recent data, then: if 'in place' has more recent EA, keep both its Data and EA; otherwise keep only its Data and overwrite its EA. Else (meaning 'in place' does not have the more recent data): if it has the more recent EA, overwrite the data but keep its EA; otherwise overwrite both its data and EA. This policy lowkey tries to preserve the most recent data or EA — but ngl, it does not take into account whether EA or Data is actually saved into the archive, vs. just marked as unchanged since the archive of reference. 😬
-/ "{!T}[{~D}[Oo] Pp]"
If the entries are not of the same type, and if the 'to be added' entry is a directory, then we keep it and overwrite the 'in place' entry. Otherwise we keep the 'in place' entry. And if the entries are of the same type? The policy provides no action, so the default action gets used: Pp. Cute, right? And you can change that default action super easily with a chain operator: ✨
-/ "{!T}[{~D}[Oo] Pp] ; Aa"
In this case instead, if the entries are of the same type, the user will be asked what to do. Interactive era. 🙈
-/ "{!T|!I}[{R}[Pp] Oo] {I&~I}[{S}[{~S}[{R}[P*] O*]
P*] {~S}[O*] {R}[P*] O* ; {s}[{~s}[{r}[*p] *o] *p]
{~s}[*o] ] {r}[*p] *o"
Okay so this one might seem a bit much 💀 but just read it as an illustration of what's actually possible to do: If both 'in place' and 'to be added' are not of the same type, we keep the data and EA of the most recent file (that's the last modification date, iykyk). Else, both are of the same type. If both are inodes, we evaluate a two-expression chain (expressions are separated by a semicolon ;) that we'll dig into in detail further on. Else, if they're of the same type but not inodes, we take the EA and data of the most recent entry (that's the last 10 chars of the string, bestie — look at it, it's right there).
And now the inode case: the first expression in the chain sets the action for data and leaves the action for EA undefined. The second one is the exact equivalent but instead it leaves the action for data undefined with * and sets the action for EA. These two expressions follow the same principle: if both entries are saved in the archives (as opposed to being marked as unchanged since the archive of reference), the most recent EA/Data is kept. Else, the one belonging to the inode that is saved gets kept. But if none of them is saved in the archive, then the most recent entry (mtime/ctime) wins. 👑
-^,--slice-mode perm[:user[:group]]— this defines the permission and ownership to use for created slices. Default behavior? dar creates slices with read and write available for anyone, and lets theumaskvariable disable some privileges according to the user's preferences. If you need something more restricted, you can hand over the permission as an octal value (so it starts with a zero, like0600) to only grant read and write access to the user. But bestie, be careful not to accidentally stop dar from being able to write to its own slices — for example, if you pass a permission like0400. 💀 Also note that theumaskis always applied on top, so specifying-^ 0777will not give you world-wide read-write access unless yourumaskis0000. No cap.-_,--retry-on-change count[:max-byte]— when a file has changed at the time it was read for backup, you can ask dar to retry saving it again. By default a file can be re-saved up to 3 times (that's thecountfield), and you can set it to zero to disable this feature entirely. Optionally, the overall maximum amount of bytes allowed to be wasted due to retrying a changing file's backup can be given after a colon character (:), and that's themax-bytefield. By default (so, when no--retry-on-changeoption is specified at all) a limit of 1 wasted byte is allowed, which is the minimum. Specifying zero formax-bytesets no limit at all on the amount of wasted bytes (same as if nomax-bytewas specified) — in that case each changing file gets saved up tocounttimes if necessary. 🦋
A file is considered as changed when the last modification time has changed between the time the file was opened for backup and the time it was completely read. In some situations it's not possible to replace the already saved data for a file (writing the archive to a pipe, for example) — and in that situation only, a second copy of the file is added right after the first previous try, which leads that previous try to become inaccessible. However, it still holds some space in the archive, which is where the whole designation of "wasted bytes" comes from. And you can remove all wasted bytes from an archive using the merging/filtering feature:
dar -+ new_arch -A old_arch -ak
Note: since release2.5.0, in normal conditions no byte is wasted when a file changed at the time it was read for backup — except when doing a backup to a pipe (using the-c -option), except if the beginning of the modified file is located in a previous slice, and except if slice hashing or strong encryption is used. So like, three excepts. Read them again. 💀
-ad,--alter=decremental— this flag is meant to be used only when merging two archives. Instead of the usual merging, where each file of both archives is added to the resulting archive (with, eventually, a tie decided by the overwriting policy — see the-/option), here the merging builds an archive that corresponds to the decremental backup done based on two full backups. The-Abackup is expected to receive the older archive, while-@is expected to point to the more recent one. If this option is used, the eventual overwriting policy is ignored and replaced internally by:
-/ "{E&R&~R&(A|!H)}[S*] P* ; {(e&~e&r&~r)|(!e&!~e)}[*s] *p"
Additionally, files found in the newer archive that did not exist in the older one are replaced by a detruit entry, which marks them to be removed at restoration time. 🧚 For more info on decremental backups, go read the usage_notes.html file in the documentation. And obvi: note that decremental backup is not compatible with delta binary. ⭐
-asecu,--alter=secu— okay so bestie, listen, this one turns OFF the ctime check that dar does by default during a differential backup. Here's the tea: if the ctime of a plain file has changed since the archive of reference was done, while all other values stay unchanged (inode type, ownership, permission, last modification date), dar will throw a "SECURITY WARNING" at you, because that could be the sign of a rootkit hanging around. 😱
You should reach for the -asecu option to disable this type of warning globally if you're doing a differential backup of just restored data (so: a differential backup where the archive you used for restoration is taken as reference). Because fr fr, in that exact situation, since it's not possible to restore ctime, the restored data's ctime will have changed while every other parameter is unchanged for all the restored files — which makes dar issue a warning for basically every single restored file, and like, that's just noise at that point. 🙈
Oh and this security check is also disabled (implicitly!) if dar is run with the -ac option, no cap. Last thing, and this one's important: if a file has only its EA changed since the archive of reference was done (new EA, removed EA, modified EA), the security warning will still show up — that's a false positive. 💀
-.,--user-comment "<message>"— this option lets you drop an arbitrary message into the archive header. 🎀
Warning!! ⚠️ This message is always stored in clear text, even if the archive is encrypted. Like, evil little gremlin energy, it does not care about your encryption.
You can see the message you inserted in an archive by displaying the archive summary with dar -l <archive> -q. And some macros can be used inside that <message>, bestie, get into it:
%c— gets replaced by the command line used. Note that for security, any option related to archive encryption is removed (-K,-J,-$,-#,-*,-%). The commands included from a DCF file (see the-Boption) are never added by this macro. As a consequence, if you don't want to see--user-commentstored in user comments, you can add the--user-commentdefinition in an included file, like~/.darrcfor example. 👑%d— this is the current date and time 🕰️%u— this is the uid under which dar has been run%g— this is the gid under which dar has been run%h— the hostname on which the archive has been created 🖥️%%— the%character. slay
-3,--hash <algo>— with this option set, when you're creating, isolating, merging or repairing an archive, beside each generated slice an on-fly hash file of the slice is created using the specified algorithm. ✨ Available algorithms are"md5","sha1","sha512"and"whirlpool". By default no hash file is generated, periodt.
The hash file generated is named based on the name of the slice, with the .md5, .sha1, .sha512 or .whirlpool extension added to it at the end. These hash files can be processed by the md5sum, sha1sum, sha512sum and rhash (for the whirlpool algorithm) usual commands (md5sum -c <hash file>) to verify that the slice has not been corrupted. ��р
Note that the result is different than generating the hash file using md5sum or sha1sum once the slice is created — in particular if the media is faulty: calling md5sum or sha1sum on the written slice will make you compute the hash result on a possibly already corrupted file, so the corruption will not be seen when testing the file against the hash at a later time. 😭
Note also that the creation of a hash file is not available when producing the archive on a pipe (dar -c -). 💔
-7,--sign email[,email[,...email]]— when creating, isolating, merging or repairing an archive with public key encryption (read the-Koption), it is also possible to sign it with one or more of your private key(s). 🔐 At the difference of the hash feature above, only the randomly generated key used to cipher the archive — the key that is dropped at the beginning and at the end of the archive — is signed. If the archive is modified at some place, that part will not be possible to decipher, but the signature verification will stay quick and valid, unless the part that has been tampered is the key inside the archive, in which case the signature check will report a failure and the archive will not be readable at all. If the signature is valid and the archive could be extracted without error, the whole archive could be assumed to be signed by the gnupg key owners — but read below the security note. 👀 See alsoGNUPGHOMEin the ENVIRONMENT section at the end of this document.
A summary information about the signature information is displayed while listing an archive in summary mode dar -l <archive> -q. For any operation involving a signed archive, a short message only shows if the archive is signed and one or more signature checks failed — no message is displayed in case of a successful signature check. 🫶
This warning may be disabled using the --alter=blind-to-signatures command.
-<,--backup-hook-include <mask>— the mask is applied to path+filename during backup operation only. If a given file matches the mask, a user command (see the-=option below) will be run just before proceeding to the backup of that file, and a second time right after it has completed. 👯 See also the->option below.
IMPORTANT: if using the short option, you need to enclose it between quotes:'-<'so the shell doesn't interpret the<as a redirection. 🐚
This option can be used several times on the command-line.
->,--backup-hook-exclude <mask>— the mask is applied to path+filename during backup operation only. If a given file matches the mask, even if it matches a mask given after a-<option, no user command will be executed before and after its backup. 🙅♀️ The-<and->options act like the-gand-Poptions (but for a different purpose, bestie), they can receive wildcard expressions and thus have their comportment driven by the--alter=globeand--alter=regexexpressions seen above, as well as the--alter=maskoption. Last, the--alter=caseand--alter=no-casealso modify the way case sensitivity is considered for these masks. By default, with no->or-<option, no file gets selected for a backup hook. 💅
IMPORTANT: if using the short option, you need to enclose it between quotes:'->'so the shell doesn't interpret the>as a redirection. 🐚
This option can be used several times on the command-line.
-=,--backup-hook-execute <string>— for files covered by the mask provided thanks to the-<and->options, the given string is executed just before the backup of that file starts and right after it has completed. ⚡
Pay attention: when the action applies to a directory, it does not apply to any file and subdirectory located inside that directory. 🚨
Several macros can be used that are substituted at run time, and honestly, these are giving main character energy:
%%— will be replaced by a literal%%p— will be replaced by the full path under backup 🌈%f— will be replaced by the filename (without the path)%u— will be replaced by the UID of the file%g— will be replaced by the GID of the file%t— will be replaced by a letter corresponding to the type of inode:'f'for plain file,'l'for symlink,'d'for directory,'c'for char devices,'b'for block devices,'s'for sockets,'p'for pipes,'o'for doors. 🚪%c— and most interesting,%c(c for context 💭), will be replaced by"start"or by"end"when the command is executed before or after the backup respectively.
For example, this feature lets one dump a database just before its backup starts, and remove the dumped file(s) once the backup of that part has completed. obsessed. 🍓
Note: bestie, when a directory gets selected for this feature, the user command runs before dar starts backing up any file located in that directory and its subdirectories — and it runs with the context "start" (that's the %c vibe from above 👆). Then, as expected, it runs again after all files in that directory and subdirectories have been saved, this time with the context "end". But here's the tea ☕: between those two executions, even if a file does match the backup-hook masks (so yeah, it's located inside this directory), no command will be executed for it! The assumption is that when a directory has been asked for a backup-hook to be executed, that hook (or user command) is preparing all data located in that directory. 💅
Okay so, performance check 📉 — because of the creation of a shell process to interpret the user command-line and then the execution of the user command itself (and this once before and once after a file to backup), it is not advised to use this feature for a large number of files under backup (or worse 😭, all of them). The purpose of this feature is to prepare the backup of some particular structures that need coherence between files in order to be saved properly. If all data under backup is concerned by such coherent structure, better act before and after running the dar command itself (for example stopping/suspending and restarting/resuming the concerned service/process). And if many of such structures are under backup, or are nested in each other, saving them independently (eventually using this backup-hook feature for some or all of them 🎀) and merging the resulting dar backups afterward, or feeding a dar_manager database with them, are also options to consider. ✨
Also!! The environment variable DAR_DUC_PATH applies to these user commands too (peep -E above, or the ENVIRONMENT paragraph below). 🫶
-ai,--alter=ignore-unknown-inode-type— So when dar meets an inode type it is not aware about, it issues a warning about its inability to handle such inode (some times ago, it was the case for Door inode on Solaris, for example — though Door inodes are handled by dar since release 2.4.0, iconic 👑). The thing is, that warning occurs even if that entry is filtered out by mean of-X,-I,-P,-g,-[or-]options, as soon as some other entry in that same directory has to be considered for backup, which leads dar to read that directory's contents and fail on that unknown inode type (filtering is done based on the result of the directory listing, periodt). This option exists to avoid dar issuing such warning in that situation. 🌸-8,--delta sig— This option can be used for archive backup, isolation and merging. Important: go read the best practice paragraph below too, fr fr.
Called during a backup operation, it leads dar to create a delta signature for each file: if the file is new or has changed, a signature is computed and stored beside the file's data, which increases the archive size. 💀 If the file is not new and has not changed (differential backup context) and a delta signature is found in the archive of reference (or isolated catalogue), this signature is copied to the resulting archive, but not the file's data. ✨ If the reference archive does not hold a delta signature, a new delta signature is computed based on the current data found on the filesystem for that file and then stored in the resulting archive. But in any case, without --delta sig the resulting archive will hold no delta signature. Note that delta signature transfer is not possible when the archive of reference is read in sequential mode (still here for backup operation), thus delta signature is disabled when the archive of reference is read in sequential mode. 🙈
For isolation and merging operations, the behavior is slightly different: the --delta sig option lets dar transfer existing delta signatures from the original archive to the isolated/merged one, but does not lead dar to compute delta signatures for files that do not have one — unless one of the --include-delta-sig or --exclude-delta-sig option is specified. In that case the delta signatures are transfered/dropped and, if not present, calculated accordingly to these mask options. 🎀 However, note that it is not possible to calculate a delta signature for unsaved files in the archive of reference (because the archive of reference does not hold their data), as well as for fully saved files when merging is performed keeping files compressed (see -ak option). Another restriction while merging concerns sparse files: it is not possible to calculate binary signature for files stored as sparse files, but if the sparse file detection mechanism is activated at merging time, delta signature can be calculated for sparse files too, even if it is missing in the reference archive. 💅
In short: if you want recalculation of delta signature while merging, do not keep files compressed (do not use the -ak option), and if you want to avoid having sparse files excluded from the delta signature recalculation, activate sparse file detection (use the -ah option). Also: delta signature transfer is not possible for on-fly isolation — you need to do normal archive isolation to obtain an isolated catalogue with delta signatures. ⭐
-8,--delta sig:<function>:<multiplier>[:<divisor>[:<min>[:<max>]]]— this variant of the--delta sigoption lets you specify the block length used to build delta signatures. 💖
Larger values reduce the CPU load required to build the delta signature, but they also lead to less accuracy when computing the delta binary — which means a larger delta patch and more data saved when a file has changed. 😮
The block len is calculated following this formula:
block_len = function(filesize)*multiplier/divisor
If this calculated value is lower than "min", it is set to min. If the calculated value is greater than "max" it is set to max, unless max is set to zero, in which case the value is kept as is. And of course "divisor" cannot be null. 🚫
The available functions are:
fixed— always returns 1. In other terms, the block size is independent from the file size used to build the delta signature for. ✨linear— returns the filesize. Here, you will most of the time use 1 for multiplier and increase divisor to at least 10 for it makes sense. 🦋log2— returns the upper rounded power of 2 closest to the file size (base 2 logarithm).root2— returns the approximated value of the square root of the file size. Note that for better performance, and as accuracy is not important here, this function is implemented asexp2(log2(filesize)/2)whereexp2andlog2are based on the integer left and right bit shift operations. 💜root3— returns the approximated value of the cube root of filesize, implemented asexp2(log2(filesize)/3).
All numerical fields can receive multiplier suffix (k, M, ...) — for more details about these suffixes, see the -s option description. If not specified, "max" defaults to zero (no maximum value defined). If not specified, "min" defaults to RS_DEFAULT_BLOCK_LEN (see below for details on this symbol). If not specified, "divisor" defaults to 1.
Using --delta sig without additional fields is equivalent to using --delta sig:fixed:RS_DEFAULT_BLOCK_LEN up to dar/libdar version 2.7.10. Starting release 2.7.11, the default is equivalent to use --delta sig:root2:1:1:RS_DEFAULT_BLOCK_LEN:64*DEFAULT_BLOCK_LEN, which is almost what is used by the rsync command line tool (rsync uses rather 700 bytes as minimum block size), where "RS_DEFAULT_BLOCK_LEN" is taken from librsync and is today equal to 2048 bytes (which may well change in the future, by the way, if librsync maintainers decide to do so 😭).
-{,--include-delta-sig <mask>— okay so by default, when you pass--delta sig, dar computes delta signatures for every single file in the backup (peep--delta-sig-min-sizetoo 👀). This option and its bestie--exclude-delta-sigare the vibe-check that narrows down which files actually get those signatures calculated. The mask applies to the whole path, same energy as the-P/-goptions do. ✨
For merging or isolation ops, when --delta sig is used, no delta signature gets computed — only the existing ones get transferred as-is, no restriction whatsoever. To switch that up and either drop or add delta signatures to files that didn't have one in the archive of reference, you specify a combo of --include-delta-sig or --exclude-delta-sig together with --delta sig. This option and --exclude-delta-sig can both be used multiple times on the command-line, but ngl they're useless/ignored without --delta sig. Also check out the -am, -ag and -ar options. 💖
-},--exclude-delta-sig <mask>— files matching this mask will never have their delta signatures calculated, whether--delta sigis specified or not. Periodt. See also--include-delta-sigup there ⬆️ and--delta-sig-min-sizedown there ⬇️.-6,--delta-sig-min-size <number>— for archive merging, isolation and creation, when dar has to (re-)calculate delta signatures, this option changes the minimum file size (in bytes) below which dar never calculates delta signatures. This one acts independently from--include-delta-sigand--exclude-delta-sig, BUT it can't re-activate delta signature recalculation all by itself while merging/isolating an archive — it needs either--exclude-delta-sigor--include-delta-sigto be active in that situation, bestie. For archive backup though? It doesn't need--exclude-delta-sigor--include-delta-sigto act, it just needs--delta sigto be set. By default this minimum size is10 kio. And the same option suffixes (kfor kilo,Mfor mega,Gfor giga,T, ...) that you can use with the--sliceoption work here too. Usingzeroas the argument gives the same result as not specifying this option at all (default size). 🎀-8,--delta no-patch— in the context of differential backup, this option makes dar never consider files for delta binary even if delta signatures are present. By default, delta binary (rsync-like) operation happens when a file has changed since the archive of reference was made and if a delta signature could be found in the archive of reference for that file (or in the isolated catalogue used as reference for the incremental/differential backup). If no delta signature could be found, or if--delta no-patchis used, the normal behavior kicks in — which is saving that whole file in the archive. Heads up though: if the archive of reference is read in sequential mode,--delta no patchis required, dar will straight up refuse to execute the operation. Sequential read and binary delta are not compatible, fr fr, because reading an archive in sequential mode doesn't let dar skip backward to fetch the delta signature needed to set up a delta patch. 💀
🦋 Binary delta options usage and best practices 🦋
First things first bestie, you gotta understand that binary delta has advantages (less storage requirement, slay) and drawbacks: data corruption has a wider impact on your ability to restore a given file, and restoration of an incrementally backed up file may ask for way more than one archive to be used. To limit the impact of that first drawback, dar binary delta is done per file, not globally on the total amount of saved data. You are also strongly encouraged to protect your backups with parity data using par2 (see the dar_par.dcf file in the examples section of the documentation). Adding par2 data will increase storage requirement by a little, but usually much less than the amount gained using binary delta. 🌈
Last drawback: binary delta relies on checksum (contained in the delta signature) and not on the real data to build the binary delta. There's a chance that two different files provide the same checksum — even if the chances are very low, probability is not null. The consequence is that using binary delta, the risk exists that the restored data does not match the original data, and this will not be noticed by the librsync library on which libdar relies for that feature. Dar adds a second level of checksum, to detect data corruption inside the archive and to check that the file the delta patch is about to be applied to is the expected base file — this reduces the risk of "collision" but does not remove it completely. 😭
After these warnings, let's now see the best practices about binary delta:
Once a full backup has been done using --delta sig, any differential backup made based on this archive will use binary diff for files having a delta signature present in the full backup. If you always make differential (not incremental) backups based on such a full backup, you have nothing more specific to do in regard to binary delta, dar will handle it transparently. In particular you do not need to invoke --delta sig at subsequent backups — this saves space in differential archives as well as CPU cycles. ✨
However, when doing incremental (not differential) backups this time, if you want dar using binary delta at each subsequent incremental backup, delta signatures must be present in the successive incremental backups. This is done by using --delta sig for each new incremental backup created.
If you were used to using isolated catalogues before release 2.6.0, you can add --delta sig while isolating a catalogue from an archive containing delta signatures. Such an isolated catalogue will be much larger than what it can be without this option, but it can be used as reference for a new differential/incremental backup letting dar rely on binary delta. Isolated catalogues generated without --delta sig do not contain delta signatures and cannot lead to binary delta operation when used as reference for an incremental or decremental backup. 👑
Another way of doing differential backup is to make a normal full backup without --delta sig, and only add delta signatures at archive isolation time using --delta sig --include-delta-sig "*". Binary delta signature will then be calculated based on the saved files. Then, using the resulting isolated catalogue as reference, dar will be able to proceed to binary delta for the differential backup. If this works pretty well for differential backup (or the first incremental backup) which is based on a full backup — for incremental backup this is less adapted, as a file that has not changed since the archive of reference was made does not hold any data and calculating the delta signature is not possible. The first method explained two paragraphs above is better, since the incremental backup fetches the already calculated delta signature from the reference to keep it in the resulting incremental backup, so even without data, binary delta is still possible. 🫶
Isolated catalogues using the --delta sig option can still be used as backup of the internal catalogues they have been isolated from. However, as they hold their own delta signatures, such an isolated catalogue can only have access to its own ones, not to those of the archive of reference. In particular, when testing an archive (-t option), using -A option to rescue the archive internal catalogue using an isolated catalogue containing delta signatures, dar will not be able to check that there is no corruption in the delta signatures fields of the archive under test. For that type of testing, either use the internal catalogue of the archive or rescue it using an isolated catalogue built without --delta sig. 💅
-az,--alter=zeroing-negative-dates— sodar/libdarsaves dates as a number of seconds since the beginning of year1970, the well known "Unix time" (plus a positive fraction for sub-second time-stamping). Some systems may return a negative number as the Unix time of a given file (files having dates before1970). In that situation, by default and since release2.5.12, dar pauses and asks the user whether to assume the date as being zero. But with the-azoption,dar/libdarautomatically assumes such negative dates to be zero and just issues a warning about the problem met. 🌸-,,--ignored-as-symlink <absolute path>[:<absolute path>[:...]]— bestie, this is the "treat it like the real thing" button. When dar bumps into an inode that's on this colon-separated list: if that inode isn't a symlink, literally nothing happens, no effect, we move on. But if it is a symlink, dar saves the file the symlink points to instead of the symlink itself (which is what dar does by default, for the record). And extra slay: if the thing being pointed to is a directory, dar recurses into that directory. You can also hand this list to theDAR_IGNORED_AS_SYMLINKenvironment variable instead of using--ignored-as-symlink— and heads up, the option takes precedence over the environment variable.-',--modified-data-detection=any-inode-change,--modified-data-detection=mtime-and-size— okay so storytime 🫶. Before release 2.6.0, during a differential/incremental backup, if any part of a file's inode metadata changed (ownership, permission, ...) — even when themtime(last modification time) and the file size stayed exactly the same — dar had no choice but to re-save the whole entire file just to record those metadata changes. Which is, like, so wasteful. Backup time and backup space, gone, because someone touched the ownership. 💀
You can still live that historical life if you want, by invoking --modified-data-detection=any-inode-change.
But since release 2.6.0 there's a new entry status called "inode-only", and now dar can re-save only the metadata when the inode change doesn't concern the data itself. To figure out whether the data actually changed, by default (aka when you give no --modified-data-detection option at all) dar looks at mtime and at the file's size only. Specifying --modified-data-detection=mtime-and-size (which is the default behavior) is how you revert the action of --modified-data-detection=any-inode-change — for example when you're playing with included files (DCF files): the latest one met takes precedence.
-T,--kdf-param <integer>[:<hash algo>]— and here's a plot twist ✨. Unlike the listing context (peep below), in the context of archive creation, merging, isolation and repair,-Tlets you define the iteration count used to derive the archive key from the passphrase you gave (that's the archive encryption context) plus the hash algorithm used for that derivation. But-Thas another, older meaning when you're doing archive listing. And because there were no free characters left to make a brand new CLI option, there was literally no other choice than to recycle an existing option that isn't used in the archive creation/merging/isolation context. 🙈
The consequence of that mess: the -T option must appear after the -+/-c/-C/-y options, so the operational context is known by the time the -T option is met and its --kdf-param meaning gets taken into account. And since --kdf-param is an alias to -T, this long form of the option must also be found after the use of either -c, -C or -+.
Without --kdf-param the KDF fonction uses 200,000 iterations for md5, sha1 and sha512 (PBKDF2 from PKCS#5 v2) but only 10,000 for argon2. If libargon2 is present, this is the default hash algorithm, else sha1 is used with PBKDF2. Valid parameters are "sha1", "sha512", "md5" and "argon2" for the hash algorithms, and a value greater than 1 for the iteration count. However, it is advise to use a value equal or greater to the default values mentionned previously. The suffixes described for the -s option are also available here (k, M, G, T, P, ...) — but pay attention to the -aSI/-abinary mode which default to binary, in which case -T 1k is equivalent to -T 1024. Example of use: --kdf-param 20k:argon2
-anru,--alter=never-resave-uncompressed— at creation time, or when re-compressing data at merging time (so, whenever-akis not used), dar by default tries to re-save a file uncompressed if the compression result takes more space than the uncompressed original data. Iconic intent, annoying side effect: it makes dar skip back in the archive that's about to be created. The upside? No wasted storage space. This option disables that whole feature: dar then won't skip back and will keep files compressed even if their compressed data takes more space than what they'd take uncompressed. 🔥-arep,--alter=repair— for isolation operation only, this option makes dar able to isolate a catalog from a truncated backup. It transparently implies--sequential-readand--alter=force-first-slice, so that it can read the content of the truncated archive. Then that isolated catalog can be used to read the archive in direct mode for better efficiency (see the-Aoption used with-x/-l/-tcommands) — which avoids repairing entirely, saving you time (and non-rewritable media 😭) when the volume of data is huge.
🛁 RESTORATION SPECIFIC OPTIONS (to use with -x) 🛁
-k[{ignored|only}],--deleted[={ignore|only}]— no argument, or the"ignore"argument, and this option leads dar at restoration time to not delete files that have been deleted since the backup of reference (file overwriting can still occur though, don't get it twisted). By default, files that have been destroyed since the backup of reference are deleted during restoration — but a warning gets issued before proceeding, except if-wis used. If-nis used, no file will be deleted (nor overwritten), so-kis useless when using-n. And if the-/option is used, this option without argument is ignored! 🚫
With the "only" argument, this option only considers files marked as to be removed in the archive to restore — no files are restored, but some files are removed. When -konly (or --deleted=only) is used, the -/ option is ignored (at the opposition of the --deleted=ignore option, which is ignored when the -/ is used). Of course --deleted=ignore and --deleted=only are mutually exclusive, because if both of them were available at the same time dar would do, like, nothing at all. 💀
-r,--recent— only restore files that are absent or more recent than those present in the filesystem. If the-/option is used, this option is ignored!-f,--flat— do not restore directory structure. All files will be restored in the directory given to-R. If two files of the same name have to be restored, the usual scheme for warning (-woption) and overwriting (-noption) is used. No rename scheme is planned actually. When this option is set, dar does not remove files that have been stored as deleted since last backup. (-fimplicitly implies-k). 🧚-ae,--alter=erase_ea— [DEPRECATED use-/instead] Drop all existing EA of files present in the filesystem that will have to be restored. This way, the restored files will have the exact set of EA they had at the time of the backup. If this option is not given, a file to restore will have its EA overwritten by those present in the backup, and if some extra EAs are present they will remain untouched. See the Note concerning Extended Attributes (EA) above for a detailed explanation about this behavior. If the-/option is used, this option is ignored!-D,--empty-dir— at restoration time, if-Dis not specified (default) any file and directory is restored in regard to the filtering mechanism specified (see-I,-X,-P,-g,-[and-]options). But if the-Doption is provided, the restoration skips directory trees that do not contain saved files. This avoids having a huge empty tree with just a few restored files, especially when restoring a differential archive into an empty place. 🌸
Note: this feature cannot work when --sequential-read is used, because it is not possible to know whether a directory contains or not some saved files at the time the directory inode is read from the archive in sequential reading mode.
-2,--dirty-behavior { ignore | no-warn }— at restoration time, if a file in the archive is flagged as"dirty"(meaning that it had changed at the time it was saved), the user is asked for confirmation before restoring it. Specifying"ignore"will skip those dirty files, while"no-warn"will restore them without user confirmation. This feature is incompatible with sequential reading mode — in this mode dar cannot know whether a file is dirty before having restored it. In consequences, in--sequential-read, once a file has been restored, if it is found to be dirty it will be removed unless dirty-behavior is set to"no-warn". 😭-/,--overwriting-policy <policy>— bestie this one is the when-and-how-do-we-clobber-stuff knob 🫶 it's for archive restoration, and it tells dar when and how it's allowed to overwrite files. Full deets live up above in the description of this option, so go peek there.-A,--ref [[<URL>]<path>]/<basename>— okay so--refis your rescue-arc 🦸 it works together with an isolated catalogue to save an archive that's got a corruption sitting in its catalogue part. More details are up in GENERAL OPTIONS, iykyk.-au,--alter=unix-sockets— do not restore unix sockets. By default, saved unix sockets do get recreated at restoration time, so this is the "actually, no thank you" switch.-ap,--alter=place— so since version 2.7.1 libdar stores the filesystem root path (that's the-Roption you gave) that was used when the backup was created — this is what we call the 'in-place' path ✨ At restoration time, by default dar uses the-Roption you provide, or if you didn't give one it just uses the current directory as the root directory for the restoration. Passing-apinstead makes dar read the in-place path straight out of the backup and restore the data using that path. Which means: this option is exclusive with the-Roption, and it can make dar throw an error if the archive never stored any in-place path at all (older archive format, or a backup that came out of merging two backups that had different in-place paths). Not me warning you twice 💀-affs,--alter=force-first-slice— so this one's original whole point was restoration time with an isolated catalogue. In that context dar still has to read the archive format from the backup in order to restore. In sequential read mode that info always gets fetched from the beginning of the archive, but in direct access mode it may be fetched by reading the end of the last slice (the default behaviour) or by reading at the beginning of the first slice (that's when-affsis set). The goal? Avoiding fetching that last slice when you're dealing with very large backups. You can define a first slice (see the-Soption) of, say, 1 kB, while the other slices (the-soption) can be specified arbitrarily large. Then with the help of an isolated catalogue built on this archive plus that first (tiny) slice, reading some data out of this giant backup only needs the few (big) slices where that data actually lives — nothing more 🎀-aefd,--alter=extract-from-database— in this mode of data restoration, the argument you hand to-xshould point at a dar_manager database. This is almost the same as using dar_manager's-roption, except that there's only one process and all the dar options you give on the command line are available to every backup/archive referred to in the database that gets used for this restoration. dar_manager was designed to restore a few files and then got extended to a whole directory tree, but passing the fileset scope to restore between processes just isn't that efficient. With-aefdyou get better performance to restore the whole dataset referred to by a set of full, incremental and/or differential backups listed in a dar_manager database. Also see the"-af -A <date>"option to limit the restoration to the status the data had before a given date.
with -aefd restoration mode, it's possible to restore in the state at a given date by means of the -af and -A options. By default, the most recent state available gets restored for all entries. The file filtering mechanism can also be used to restore only certain files and directories instead of everything that was present at the latest state or the given-date state 💅
🔥 TESTING AND DIFFERENCE SPECIFIC OPTIONS (to use with -t or -d) 🔥
-ado-not-compare-symlink-mtime,--alter=do-not-compare-symlink-mtime— with this one set, when a symlink gets compared, no message shows up if the symlink in the archive and the symlink on the filesystem differ only by their mtime. See also the-Ooption ✨-ap,--alter=place— yep, it's also available here, exactly as described just above for the restoration options.-az,--alter=zeroing-negative-dates— okay so dar/libdar saves dates as a number of seconds since the beginning of year 1970, aka the well-known "Unix time" (plus a positive fraction for sub-second time-stamping 🕰️). Some systems may return a negative number as the Unix time of a given file (files with dates before 1970), and in that situation, by default and since release 2.5.12, dar pauses and asks you whether to assume the date is zero. But with-az, dar/libdar just automatically assumes those negative dates are zero and merely issues a warning about the problem it met. No more being interrogated mid-run 💀
No other specific option, but all general options are available — except for example -w, which is useless here, since testing and comparing only read data. The -A option is available as described in GENERAL OPTIONS for the backup of the internal catalogue of the archive (assuming you have a previously isolated catalogue available).
Doing a difference in sequential read mode is possible, but hard linked inodes can only be compared to the filesystem the first time they're met. The next hard links to that same inode can't get the corresponding data, because skipping backward in sequential read mode is forbidden 🚫 In that situation the hard links get reported as skipped, meaning the data comparison could not be performed. Fr fr, that's just how it is.
-affs,--alter=force-first-slice— this option also applies to testing and difference operations (see details above 👆).
🌈 LISTING OPTIONS (to use with -l) 🌈
-T,--list-format=<normal | tree | xml | slicing>— by default, listing gives you a tar-like output (the'normal'output). But you can also get a tree-like output, an XML structured output, or an output focused on the slice(s) where each file's data, EA and FSA is located 🦋 The option--tree-formatis an alias to--list-format=tree(kept for backward compatibility). Note that the filesdoc/dar-catalog-*.dtddefine the format of the XML output listing (this file is also installed under$PREFIX/share/doc).
the -Tslicing option can also be used with an isolated catalogue generated with dar 2.5.0 or above, since isolated catalogues now contain a copy of the slicing layout of the archive of reference. However, if the archive of reference has been re-sliced (using dar_xform) after the isolated catalogue was built, the slicing information would not be correct 😭 For that corner case, you can use the -s and -S options together with -Tslicing to specify what the new slice sizes of the archive of reference are. Last thing: -Tslicing and --sequential-read options are not compatible, except for isolated catalogues.
-as,--alter=saved— list only saved files 👑-alist-ea,--alter=list-ea— list the Extended Attributes name for every file that has some.-ay,--alter=byte,--alter=bytes— by default, file size is displayed using the shortest number of characters, by picking the largest unit possible (KiB, MiB, GiB, and so on). With this option instead, the size is displayed with maximum precision, using the exact number of bytes used for each file 🔢-I,-X,-P,-g,-[,-]— these can all be used to filter the files to list, based on their name or path ✨-aheader— displays the header (when--sequential-readis used) or the trailer of the archive, then stops. This archive header/trailer is always in clear text, even when the archive is ciphered 🔓 This option exists so you can access those fields without providing the encryption key. Iconic.-afdd,--alter=fully-detailed-dates— show the sub-second fraction value of dates, according to the time precision that was available on the system where the backup was created ⏱️
From the general options, it seems only -vm and -b stay useful here. Note that -vm displays an archive summary first, where a detailed bit of information about the archive can be obtained. If you want to display only this summary, use -q together with the -l option 💅
📋 displayed fields
💖
[Data]— the tea on whether the actual file data got saved. Possible values are[ ],[Saved],[InRef],[DIRTY],[Inode]or[Delta]. Let's break it down bestie:[ ]— nothing got saved because literally nothing changed since the backup of reference.[Saved]— the data is fully saved, so this archive can restore the file all on its own, no backup needed. 💅[InRef]— a throwback value used in archives made by dar version 2.3.x and before, when isolating a catalogue from an archive. It means the file was saved over in the reference archive.[DIRTY]— data is saved (like[Saved]) but it changed while dar was reading it for backup, which means dar may have stored the file in a state it literally never had. 😭 Iconic chaos.[Inode]— only permission, ownership and ctime data changed since the archive of reference was made, and that's what's recorded in the archive. The data itself didn't change according to the--comparison-fieldset (or not set).[Delta]— the file's data is saved as a binary delta (aka a delta patch), which is way shorter than the full data you'd get with[Saved]. The catch: you can only restore the file if it exists on the filesystem in the exact state it had when the archive of reference was done, because the patch has to apply onto it. Which is the case, for example, if you just restored this file from the archive of reference. No cap.
[D]— possible values are[-],[ ]or[D].[D]means a delta signature associated with this file is present in the archive.[ ]means the file has no associated delta signature, so binary diff won't be possible for it.[-]is used for non plain files inodes, where delta signature just doesn't apply.[EA]— possible values are" "(empty string),[ ],[InRef],[Saved]or[Suppr]. It shows whether Extended Attributes are present and saved ([Saved]), present but not saved ([ ], meaning there's no change since the backup of reference), whether there's no EA saved for this file at all (empty string), or whether some EA were present in the archive of reference but none is currently available ([Suppr]).[InRef]was used when isolating a catalogue (release 2.3.x and before) from an archive, and means the file was saved in the reference archive.[FSA]— every character here represents an FSA Family, slay:"L"— the first character (L/l/-) representing the ext2/3/4 FSA family"H"— the second character (H/h/-) representing the HFS+ FSA family"-"— the third character is reserved for a future FSA family and is always a dash for now
Uppercase means the FSA set is saved, lowercase means the FSA is present in the archive of reference and hasn't changed since that time. And a dash (-) means no FSA of that family has been saved for that file.
[compr]— possible values are[....%],[-----],[ ]or[worse]. Shows if the file has been compressed ([...%]) and the compression ratio reached,(uncompressed-compressed)/uncompressed. For example[ 33%]means the compressed data uses only 66% of the space required to store uncompressed data (33% of space saved thanks to compression). Or it shows the file is stored without compression ([ ], see-m,-Yand-Zoptions), or that the file isn't subject to compression because it's not a saved regular file ([----]), or that the file takes more space compressed than its original size ([worse]), due to compression overhead. NGL, a 1% compression ratio brings quite no data reduction, while obviously 98% is a very performant compression (the compressed file takes only 2% of the size required by the uncompressed data). 💖[S]— possible values are[ ]or[X].[X]only applies to saved plain files, and tells you the file is stored using a sparse file data structure: not all data is stored, and long sequences of zeros are skipped. This also means that at restoration time, if the filesystem supports it, holes will be restored. To store hole information libdar uses an escape sequence (a special sequence of bytes), but to avoid real data being mistaken for such an escape sequence, a special escape sequence is used when data looks like an escape sequence. So if data contains such an escape sequence, it must be read as if it contains holes, to be able to restore the data back in its original form. For that reason, in some rare circumstances (saving a dar archive inside a dar archive without compression or encryption, for example) a file without holes may be marked[X]as if it had holes, and will be longer by one byte for each data sequence looking like an escape sequence.permission— see thelsman page. Heads up: a star (*) is prepended to the permission string if the corresponding inode is linked several times to the directory structure (hard link).user— owner of the filegroup— group owner of the filesize— size in bytes of the file (if compression is enabled, the real size in the archive is "compression rate" times smaller).date— the last modification date of the file. The last access time is also saved and restored, but it's not displayed.filename— the name of the file.Extended Attributes— when using the-alist-eaoption, for hard linked inode, the filename is followed by an integer between braces: entries with the same number point to the same inode.Slice(s)— in-Tslicemode, each file is given the range of slices it's located in. If slice size is chosen particularly small, some slices may contain no file, EA or FSA data but only tape marks or the internal catalogue, which leads the aggregation of reported slices to not cover all available slices of the archive.
✨ EXPLICIT OPTIONAL ARGUMENTS ✨
Okay so here's the situation, and it's giving ✨portability chaos✨. When dar hasn't been compiled with GNU getopt — which, fun fact, isn't present by default on some systems like FreeBSD — you might be missing that optional-arguments syntax entirely. Like -z will throw a parse error on the command line, or inside -B configuration files. The fix? Just give the argument explicitly, bestie. Here's the whole list of explicit arguments to use in place of the optional ones:
-zmust be replaced by-z 9-wmust be replaced by-w dor-w default-Hmust be replaced by-H 1-0must be replaced by-0 ref-5must be replaced by-5 ""-pmust be replaced by-p 1-vmust be replaced by-v all-kmust be replaced by-k ignore-5must be replaced by-5 user.libdar_no_backup-Mmust be replaced by-M I:/
important ! Okay listen up because this part is the whole plot twist. 👑 When using GNUgetopt(), optional arguments are available by sticking the argument to the short option:-zfor example is available as well as-z9. But-z 9is wrong — it'll be read as the-zoption plus9, a command line argument (not an argument to the-zoption). On the other side, when using a non-GNU getopt this time,-zbecomes an option that always requires an argument, so-z 9is read as the-zoption with9as its argument, while-z9will be rejected as an unknown option, and-zalone will generate an error because no argument was provided. In consequence, you need a space between the option (like-z) and its argument (like9) when dar doesn't rely on a GNUgetopt()call — which also implies you have to explicitly use arguments to the options listed just above. 💀
✨ USAGE MADE OF STDIN/STDOUT/STDERR BY DAR ✨
okay bestie so dar is a Unix command-line tool and that means the shell hands it a standard input (stdin), a standard output (stdout) and a standard error (stderr) to vibe with the user through. basics.
But plot twist: on the other side, dar has a non-interactive output and an interactive output. The whole point is that you get in-band messages showing what step the process is on right now (those are the normal messages that go to the non-interactive output) and out-of-band messages that can influence the whole process or give you diagnostic tea on how the current dar operation is doing (that's the interactive output and its matching input). 💅
🌸 At startup
In the very early phase — before dar has interpreted the argc/argv arguments it got from the shell (aka those options and commands you hand over to dar) — both outputs are bound to stderr. Why? Because dar might be set to read an archive on stdin (--sequential-read option, or dar used with dar_slave) or to output an archive on stdout (-c - option, for example). 🙈
A very basic lookup is performed on the argv arguments list to see if a -Q option is hiding in there. Right after that, if no controlling terminal is found (and unless the -Q option was found earlier) a warning message gets sent to the non-interactive output (stderr at that time) and all questions will assume a negative answer. Else, a new file-descriptor is opened on this controlling terminal and it'll be the one used to fetch the future answers from the user when interaction is needed — which preserves stdin this way. iykyk. ✨
🌈 During command-line parsing
Once the command line option parsing has completed, if no archive or backup is expected to be output on stdout (no -i and -o options, and also no "-c -" "-C -" or "-+ -" configuration requested, for example), the non-interactive output gets changed from stderr to stdout. Otherwise it stays chillin' on stderr.
🦋 Running phase
So during the archive or backup processing, any information message goes to the non-interactive output (either stderr or stdout as described above) while questions to the user go to the interactive output, that's to say on stderr. If a controlling terminal was found, the user answer is fetched from that terminal through the additional file-descriptor opened at the startup phase (stdin is kept either for dar_slave or sequential-read mode, or it's just not used at all). 🎀
💀 Exception phase
In case an exception (= an error) that could not be handled by dar succeeds, both outputs are set back to stderr and the error message embedded in the exception is displayed before dar terminates. no cap.
👑 EXIT CODES
dar exits with the following code:
0— Operation successful. slay.1— Syntax error on command-line or DCF included file2— Error due to a hardware problem or a lack of memory.3— Detection of a condition that should never happen, and which is considered as a bug of the application.4— Code issued when the user has aborted the program answering a question from dar. This also happens when dar is not run from a terminal (for example launched fromcrontab) and dar has a question for the user. In that case, dar aborts the exact same way as if the user pressed the escape key at the question prompt.5— is returned when an error concerning the treated data has been detected. While saving, this is the case when a file could not be opened or read. While restoring, it is the case when a file could not be created or replaced. While comparing, it is the case when a file in the archive does not match the one in the filesystem. While testing, it is the case when a file is corrupted in the archive.6— an error occurred while executing user command (given with-Eor-Foption). Mainly because the creation of a new process is not possible (process table is full) or the user command returned an error code (exit status different from zero).7— an error has occurred when calling alibdarroutine. This means the caller (dar program), did not respect the specification of the API (and this can be considered as a particular case of bug).8— the version of dar used is based on finite length integers (it has been compiled with the option--enable-mode=...). This code is returned when an integer overflow occurred. use the full version (based in the so called"infinint"class) to avoid this error.9— this code indicates an unknown error. The exception caching code to take care of new exceptions has probably been forgotten to be update ... this is a minor bug you are welcome to report. 😭10— you have tried to use a feature that has been disabled at compilation time.11— some saved files have changed while dar was reading them, this may lead the data saved for this file to not correspond to a valid state for this file. For example, if the beginning and the end of the file have been modified at the same time (while dar is reading it), only the change at the end will be saved (the beginning has already been read), the resulting state of the file as recorded by dar has never existed and may cause problem to the application using it. This is known as a"dirty"file in the archive. 💀
🌈 SIGNALS
If dar receives a signal (see kill(2) man page) it will take the default behavior which most of the time will abruptly abort the program, except for the following signals:
SIGINT— This signal is generated by the terminal when hitting Ctrl+C (CTRL-C) (with the terminal's default settings), it can also be generated with thekillcommandSIGTERM— This signal is generated by the system when changing of run-level, in particular when doing a shutdown, it can also be generated with thekillcommandSIGHUP— Depending on the system, this signal may be sent before theSIGTERMsignal at shutdown time, it can also be generated with thekillcommandSIGQUIT— This signal is generated by the terminal when hitting Ctrl+\ (CTRL-\) (with the terminal's default settings), it can also be generated with thekillcommandSIGUSR1— This signal can be generated by thekillcommandSIGUSR2— This signal can be generated by thekillcommand
For those previous signals, two behaviors exist. For SIGHUP, SIGINT, SIGQUIT, SIGTERM and SIGUSR1, a delayed termination is done: the backup or isolation operation is stopped, the catalogue is appended to the archive and the archive is properly completed with the correct terminator string — this way the generated archive is usable, and can be used as reference for a differential backup at a later time. Note that if an on-fly isolation had been asked, it will not be performed, and no user command will be launched even if dar has been configured for (-E option). For SIGUSR2 instead a fast termination is done: in case of backup or isolation, the archive is not completed at all, only memory and mutex are released properly.
For both type of termination and other operations than backup or isolation, dar's behavior is the same: For restoration, all opened directories are closed and permissions are set back to their original values (if they had to be changed for restoration). For listing, comparison, testing, the program aborts immediately.
Another point: when using one of the previous signals, dar will return with the exit status 4 meaning that the user has aborted the operation. Note that answering "no" to a question from dar may also lead dar to exit this way. Last, if before the end of the program the same signal is received a second time, dar will abort immediately. 🔥
🎀 FILES
$HOME/.darrc and /etc/darrc, if present, are read for configuration option. They share the same syntax as file given to -B option. If $HOME/.darrc is not present and only in that case, /etc/darrc is consulted. You can still launch /etc/darrc from .darrc using a statement like -B /etc/darrc. None of these file need to be present, but if they are they are parsed AFTER any option on the command line and AFTER included files from the command line (files given to the -B option).
NOTE: if$HOMEis not defined$HOME/.darrcdefaults to/.darrc(at the root of the filesystem).
Else you can see conditional syntax below, and -N option above that leads dar to ignore the /etc/darrc and $HOME/.darrc files. 💖
🎀 CONDITIONAL SYNTAX 🎀
okay bestie so config files (the ones you get with the -B option, plus $HOME/.darrc and /etc/darrc) are usually just a lil list of command-line arguments — sometimes all on one line, sometimes split over a bunch, sometimes mixed in with comments (peep the -B option for the deets). But plot twist: you can ALSO do make-like targets to ask for a specific set of commands to be used under certain conditions. it's giving Makefile, it's giving conditional slay 💅
A condition looks like a reserved word immediately followed by a colon ':'. That word plus colon has to stand alone on its line, spaces or tabs chillin' beside it is fine. The conditions available are:
extract:— everything listed after this condition gets used if, earlier on the command line or in the file, the-xcommand was usedcreate:— everything listed after this gets used if earlier on the command line or in the file (the-Boption) the-ccommand was usedlist:(orlisting:) — used if the-lcommand was usedtest:— used if the-tcommand was useddiff:— used if the-dcommand was usedisolate:— used if the-Ccommand was usedmerge:— used if the-+command was usedrepair:— used if the-ycommand was usedreference:— used if the-Aoption was used (except when-Ais used for the snapshot feature or in conjunction with-af)auxiliary:— used if the-@option was usedall:— in any case, periodtdefault:— used if no-c,-d,-x,-t,-C,-lor-+option has been used at this point of the parsing
The condition stops when the next condition starts, or at End of File. Anything you drop in before any condition is equivalent to stuff you'd put after the "all:" condition. and obligatory remark bestie: -c -d -x -t -C and -l are mutual exclusive — only ONE of them can be used while calling dar. no polyamory for those 💀
Here's an example of the conditional syntax, look how cute:
create:
# upon creation exclude the
# following files from compression
-Z "*.mp3" -Z "*.mpg"
all:
-b
-p
default:
# this will get read if not
# command has been set yet
-V
# thus by default dar shows its version
all:
-v
# for any command we also ask to be verbose
# this is added to the previous all: condition
Last point (fr fr): you can have the same condition show up several times (like several all: blocks for example) and they will just be concatenated together. stacking ✨
🌈 USER TARGETS 🌈
User targets are arbitrary words found on the command line that do not start with a dash '-'. On most systems you should place them after the command and options. They get collected from the command line first, then comes the parsing of the command and optional arguments. Their whole thing is extending the conditional syntax we just talked about — now you get a whole set of options activated by the user just adding a single word on the command line. iconic.
Ofc, user targets must not be equal to one of the reserved words of the conditional syntax (extract, create, ... all, default). A valid target is a word (so, no spaces) made of lowercase or uppercase letters (case is sensitive, so watch urself) with eventually digits, dashes '-' or underscores '_' characters.
Let's see an example of use. first, a DCF file named 'example.dcf' that will be given on the command line:
# normal set of files considered for backup
create:
-R /
-P proc
-P sys
-P mnt
-D
# if the "home" user target is applied on command line the following command get added
home:
-g home
# if the "verbose" user target is used, we will have some more verbosity ...
verbose:
-v
-vs
Then we could run dar in the following ways:
dar -c test -B example.dcf— in that case only the command in the"create:"section ofexample.dcfwould be used.dar -c test -B example.dcf verbose— here over the"create:"target, the commands under the"verbose:"target (-vand-vs) would be also useddar -c test -B example.dcf verbose home— last we use two user targets"verbose:"and"home:"in addition to the"create:"target of the usual conditional syntax.
Note that if the last option may receive an argument, the first user target that follows it will be assumed an argument to that option. To avoid this, either change the order of options on the command line so the last option is one that never or always uses an argument (for example -b never has an argument while -s always has one). Or separate the options from the user targets with the -- word. And of course you can also use the explicit argument of the last option (see the EXPLICIT OPTIONAL ARGUMENT section, above). pick your fighter 🫶
Second point: it IS allowed to have user targets inside a DCF file. Note however that targets are collected in a first phase, which leads some part of the file to be hidden (because the corresponding conditional syntax or user target is not present). Then, the remaining part of the file is parsed and actions for each option found are taken. At that time, new user targets found are just recorded — they do not modify the current DCF file layout. In particular, hidden parts of the file stay hidden even if the corresponding user target is read in this same file. The next DCF parsing (which may be triggered by a second -B option on the command line, or by a -B option inside the currently parsed DCF file) will thus be done with the additional targets found in that first DCF file. So in a way you may have user targets that activate other user targets, but they'll be activated starting the next -B file. no cap. here follows an example of two DCF files, first.dcf and second.dcf:
# cat first.dcf
target3:
-K toto
target1:
target2
-B second.dcf
target3
target2:
#never reached
-s 10k
# cat second.dcf
target2:
-v
target3:
-b
In that example, target1 activates both target2 and target3, but at the time of the parsing of first.dcf, neither target2 nor target3 were yet activated, thus '-K toto' and '-s 10k' will never be given to dar (unless activated beside target1 before first.dcf gets parsed). However, when comes the time to parse second.dcf, target2 and target3 are activated, thus both '-v' and '-b' will be passed to dar — even if 'target3' is located after '-B second.dcf' in the file first.dcf. the way that works is so unserious but it works 💖
🦋 ENVIRONMENT 🦋
DAR_DCF_PATH— if set, dar looks for Dar Configuration File (DCF files, see the-Boption) that do not have a fully qualified path, in the directories listed in theDAR_DCF_PATHenvironment variable. This variable receives a colon (:) separated list of paths, and dar looks in each of them in turn, up to the first file found under the requested name.DAR_DUC_PATH— if set, dar looks for Dar User Command (DUC files, see the-E,-F,-~,-=options) that do not have a fully qualified path, in the directories listed inDAR_DUC_PATH. This variable receives a colon (:) separated list of paths, and dar looks in each of them in turn, up to the first file found under the requested name.DAR_SFTP_KNOWNHOSTS_FILE— if set, dar will not use the$HOME/.ssh/known_hostsfile to check sftp remote server authenticity, but the file given as the value for this environment variable instead. Note that setting this variable to an empty string completely disables host validation, which is not recommended!!!
bestie. do NOT set that to an empty string. turning off host validation is giving "I trust every stranger on the internet" energy and we are NOT doing that 🙈
DAR_SFTP_PUBLIC_KEYFILE— by default dar will fetch the public key file in$HOME/.ssh/id_rsa.pub. If you use the formerid_dsa.pubor more recent key types you need to set this environment variable to point to the appropriated filenameDAR_SFTP_PRIVATE_KEYFILE— by default dar will fetch the public key file in$HOME/.ssh/id_rsa. If you use the formerid_dsa.pubor more recent key types you need to set this environment variable to point to the appropriated filenameDAR_IGNORED_AS_SYMLINK— receives a colon separated list of absolute paths, which if they are symlinks are not saved as symlink but as the inode they point to. For more details see the--ignored-as-symlinkoption above.GNUPGHOME— for asymmetric encryption and signature, the keyring used is$HOME/.gnupgby default. You can change this default by settingGNUPGHOMEto the directory containing the keyring. For example, if you are running dar as root and want to use your unprivileged account keyring, use the following:
export GNUPGHOME=~myaccount/.gnupg
dar -K gnupg:...@...,...@... --sign:...@... etc.
DAR_SECURED_MEMORY_SIZE_BYTES— lets the user specify the amount of secured memory dar/libdar should allocate. The provided value must be an integer number defining the secured memory size in byte. By default262144bytes are allocated.
💜 CAPABILITIES 💜
dar fully supports the cap_chown capability, but by design, dar only uses this capability to restore files at their original ownership. Dar will thus not use this capability to access files and directories the caller would normally not have access to. In other words, it should be ok to set the cap_chown capability to the dar executable (setcap cap_chown+p dar). Calling dar from a process having the cap_chown in the inheritable set would lead the system to grant this capability to the dar process, while other users would not be granted this capability and would not be able to modify ownership of files at restoration time. This can be used for the system account that has the role of restoring data upon user requests, without giving root privilege to this restoration process. slay, least privilege, we love to see it 👑
✨ EXAMPLES ✨
You can find some more examples of use in the tutorial, mini-howto, sample scripts, and other related documentation. All these are available in dar's source package, and are also installed beside dar in the <--prefix>/share/dar directory. This documentation is also available on-line at http://dar.linux.free.fr/doc/index.html — go read it bestie, it's a whole vibe 📚
👑 SEE ALSO 👑
dar_xform(1), dar_slave(1), dar_manager(1), dar_cp(1), dar_split(1), TUTORIAL and NOTES included in the source package and also available at http://dar.linux.free.fr/doc/index.html
💀 KNOWN LIMITATIONS 💀
ok so bestie, listen, dar is iconic but even icons have limits, and we're gonna be honest about them because that's what real ones do 🫶
darsaves and restoresatime,mtime,birthtime… but it cannot restorectime(that's the last inode change time, fyi). and why? because there does not seems to be a standard call to do that under UNIX. like, the syscall just isn't there. blame the OS, not dar. sorry bestie, that's the vibe 💅- an up to date list of known limitation is at
http://dar.linux.free.fr/doc/Limitations.html— go check it out if you want the full tea ☕
🐛 KNOWN BUGS 🐛
the bug tracker lives right here and it's giving very much "we keep receipts":
https://github.com/Edrusb/DAR/issues
so if something's acting up, that's where you go. lowkey the most organized way to snoop on what's broken 👑
👑 AUTHOR 👑
look at the main character energy of this whole thing:
Denis Corbin
France
Europe
no cap, one person, one archive format, one entire continent's worth of credit 🇫🇷✨ obsessed.
and that's a wrap on DAR(1) bestie!! 🎀 this whole page came from the 3rd Berkeley Distribution, dated May 1st, 2026 — so go forth, back up ur stuff, and remember: dar ate and left no crumbs 💅🦋💖
📦 where this page comes from
- ubuntu stonking: dar-static 2.8.5-1 · GPL-2.0-only
- 💖 girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms