#fs #file #filesystem #cli

bin+lib xch

A CLI utility and rust crate to atomically swap the content of two paths

7 releases (2 stable)

1.1.0 Oct 18, 2019
1.0.0 Oct 17, 2019
0.2.1 Sep 10, 2017
0.1.2 Sep 9, 2017

#379 in Filesystem

Download history 13/week @ 2022-11-27 8/week @ 2022-12-04 35/week @ 2022-12-11 14/week @ 2022-12-18 8/week @ 2022-12-25 18/week @ 2023-01-01 17/week @ 2023-01-08 45/week @ 2023-01-15 32/week @ 2023-01-22 31/week @ 2023-01-29 23/week @ 2023-02-05 23/week @ 2023-02-12 50/week @ 2023-02-19 14/week @ 2023-02-26 20/week @ 2023-03-05 7/week @ 2023-03-12

92 downloads per month
Used in spotify-launcher

MIT license

500 lines


A Rust library and CLI program to exchange the content of paths. If possible, this try to change contents atomically.

Current release: 1.1.0

Note: Currently only supports atomic exchange on Windows or on Linux using nightly rust


The program xch can be used to eXCHange the content of two paths.


cargo install xch


    xch [FLAGS] <PATH1> <PATH2>

    -h, --help          Prints help information
    -n, --non-atomic    Use non atomic exchange if atomic is not available
    -V, --version       Prints version information

    <PATH1>    One path to exchange
    <PATH2>    The other path to exchange

After the program call, first/path will point to the previous content of second/path and vice versa. This not only works for files but also for directories or one file and a directory.

By default all changes are made atomically, you can never observe one change without the other (e.g. if first/path points to the old content of second/path, second/path also points to the old content of first/path). This only works on Windows and Linux.

On other platforms such as any BSD or MacOS, you always need to specify --non-atomic to get results.

platform atomic xch non-atomic xch
windows ✔️ ✔️
linux ✔️ ✔️
others ✔️


The functionality is also available as a crate. Add xch = "1.1.0" to your Cargo.toml. Then you need to import the crate to your code

use libxch;

Then you can start exchanging the content of files

if let Err(e) = libxch::xch("file1", "path/to/file2") {
    // Error handling here

This is is the equivalent of running xch in default mode, i.e. it only works on Windows and Linux. use libxch::xch_non_atomic("file1", "path/to/file2") to get a portable, but non-atomic exchange.



Licensed under MIT license


Here are some missing features that will hopefully be added in the future:

  • MacOS atomic exchange using the ExchangeData syscall.
  • Better error messages
  • More options.

Please feel free to open an issue if you have a specific request