A first SIGINT or SIGTERM cancels the scan. It commits the hashed records still in its batch, with a context that is not cancelled for that one write, and starts no other write or deletion; deletions need a complete walk, so records under paths an interrupted walk never reached are kept. A batch whose commit failed is now kept for that final commit instead of dropped. The progress display is finished (a bar stopped short is no longer filled up), `scan: interrupted after N files` goes to stderr, and the exit code is 1. A second signal ends the process at once. A SIGINT inherited as ignored stays ignored. Model: opus-5-5
This commit was merged in pull request #79.
This commit is contained in:
@@ -184,8 +184,9 @@ All three subcommands operate on a single SQLite database file:
|
||||
(keeping the WAL small and letting concurrent reports observe
|
||||
progress), so a report may see a scan's changes partially applied,
|
||||
and a scan that dies partway leaves a valid database holding
|
||||
everything hashed so far; the next scan skips those records and
|
||||
converges toward the filesystem.
|
||||
every batch committed so far (an interrupted scan also commits the
|
||||
batch in progress, see "Error handling and exit codes"); the next
|
||||
scan skips those records and converges toward the filesystem.
|
||||
- `scan` switches the database back to rollback-journal mode when it
|
||||
closes it, so between scans the database file alone holds the whole
|
||||
database. Each switch needs the database to itself: a `scan` that
|
||||
@@ -616,6 +617,8 @@ Additional requirements:
|
||||
waits for its next item.
|
||||
- A warning printed during a phase always lands on a line of its own,
|
||||
never inside the progress display.
|
||||
- A bar whose phase stops short of its total, as an interrupted one
|
||||
does, is left as last drawn rather than filled up.
|
||||
- `report` and `trees` modes need no progress display, only their
|
||||
stderr summaries.
|
||||
|
||||
@@ -625,7 +628,8 @@ Additional requirements:
|
||||
- `1`: fatal error (e.g., a `PATH` operand does not exist, another
|
||||
`scan` is already running against the same database, the database
|
||||
cannot be created/opened/read/written, a missing database for
|
||||
`report`/`trees`, stdout write failure).
|
||||
`report`/`trees`, stdout write failure), or a `scan` stopped by
|
||||
`SIGINT` or `SIGTERM` (see below).
|
||||
- `2`: usage error (including `scan` with no `PATH` operand and
|
||||
`report`/`trees` with any positional argument).
|
||||
|
||||
@@ -641,6 +645,24 @@ stderr and exits 1. Two cases never reach sfdupes as a failed write:
|
||||
the output is discarded and the run succeeds, as with
|
||||
`> /dev/null`.
|
||||
|
||||
`scan` stops cleanly on `SIGINT` (Ctrl-C) or `SIGTERM`. Its workers
|
||||
stop taking work, each finishing at most the directory listing or file
|
||||
it is reading; the progress display is finished; and the records it has
|
||||
hashed but not yet committed are committed, so the next scan does not
|
||||
hash them again. Apart from that commit it starts no further writes or
|
||||
deletions: records are deleted only after a complete walk, so those
|
||||
under paths an interrupted walk never reached are kept. The database is
|
||||
closed and the lock released as on any other exit, the line
|
||||
`scan: interrupted after N files` goes to stderr, N being the number of
|
||||
files the walk reached, and the exit code is 1. The next scan skips the
|
||||
records already written and converges as usual.
|
||||
|
||||
After the first signal `scan` stops catching them, so a second one ends
|
||||
it at once, as an uncaught signal does: the records not yet committed
|
||||
are lost, and the database is left valid, as when any scan dies (see
|
||||
"Database"). A `SIGINT` that `scan` inherits as ignored, as a script's
|
||||
background job does, stays ignored.
|
||||
|
||||
## Entrypoints
|
||||
|
||||
This repository adheres to the
|
||||
|
||||
Reference in New Issue
Block a user