> ## Content Index
> Fetch the complete content index at: https://itsfoss.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# This Overlooked Linux mv Option Replaces Three Commands With One
- URL: https://itsfoss.com/mv-exchange/
- Published: 2026-11-05T10:40:11.000Z
- Updated: 2026-11-05T10:40:11.000Z
- Description: Still swapping Linux files with three commands and a temporary filename? The mv command has an option that does it in one step. It works for directories too, with one detail you need to get right.
- Author: Community
- Tags: Terminal

Every Linux user has done the three-step dance at least once. You want to swap two files, so you move the first one to a temporary name, move the second one into its place, and then move the temporary file back.

Ever felt that this is a bit... clumsy? And for a moment, one of your files simply doesn't exist. That doesn't feel right!

Since version 9.5, [GNU coreutils](https://www.gnu.org/software/coreutils/?ref=itsfoss.com) has a better way: `mv --exchange`. 

In this article, I'll show you what it does, how to check if your system has it, where it actually helps, and the mistake I made the first time I used it on directories.

## The old way: three moves and a temporary name

Let's say you have two configuration files, `nginx.conf` and `nginx.conf.new`, and you want the new one to take the place of the old one while keeping the old one around.

The classic approach looks like this with the [mv command](https://itsfoss.com/mv-command/):

```
mv nginx.conf nginx.conf.tmp
mv nginx.conf.new nginx.conf
mv nginx.conf.tmp nginx.conf.new

```

There are two problems here:

- **There is a gap.** Between the first and second command, `nginx.conf` doesn't exist. If a service reads it at that exact moment, it finds nothing (and trust me, one day that will happen).
- **It can fail halfway.** If the second command fails, you are left with a temporary file and a half-finished swap to clean up by hand.

The `exchange` option does this in a single command:

```
mv --exchange nginx.conf nginx.conf.new
```

## Swap files with mv --exchange

The `--exchange` option tells `mv` to swap the two paths in a single operation. On Linux, it uses the kernel's [renameat2()](https://man7.org/linux/man-pages/man2/rename.2.html?ref=itsfoss.com) system call with the `RENAME_EXCHANGE` flag, so the swap is atomic: at any moment, both names exist and point to a file.

### Check if your mv supports it

First, check your coreutils version:

```
mv --version

```

On my machine, running [NixOS](https://nixos.org/?ref=itsfoss.com), I get:

```
mv (GNU coreutils) 9.11

```

You need version 9.5 or newer. Careful here: version numbers are not decimals. They are compared part by part, so 9.11 (nine point eleven) is newer than 9.5\. You can also check whether the option is listed in the help:

```
mv --help | grep exchange

```

If this prints nothing, your `mv` doesn't have the option yet. I'll talk about which distributions ship it later in this article.

### Swap two files

Let's create two small files to test:

```
echo "config A" > a.conf
echo "config B" > b.conf

```

Now swap them:

```
mv --exchange a.conf b.conf

```

Check the result:

```
cat a.conf b.conf

```

```
config B
config A

```

That's it. The contents traded places in one command, and no temporary file was involved.

![Swapping two files with mv --exchange in the terminal](https://itsfoss.com/content/images/2026/11/mv-exchange-files.png)

### Swap two directories (and the mistake I made)

It works for directories too, which is where it really shines. But the first time I tried it, it failed:

```
mkdir release-old release-new
touch release-old/v1 release-new/v2
mv --exchange release-old release-new

```

```
mv: cannot exchange 'release-old' and 'release-new/release-old': Unknown error -1

```

Look at the second path in the error: `release-new/release-old`. When the last argument is an existing directory, `mv` assumes you want to move things *into* it, just like a regular `mv`. So it tried to swap `release-old` with a path inside `release-new` that doesn't exist.

The fix is the `-T` (`--no-target-directory`) option, which tells `mv` to treat the last argument as a plain name instead of a destination folder:

```
mv -T --exchange release-old release-new
ls release-old release-new

```

```
release-new:
v1

release-old:
v2

```

Now the whole directory trees were swapped, no matter how many files they contain, because only the names changed.

## Where it actually helps

Here are a few situations where I find `mv --exchange` useful:

- **Rolling out a new configuration.** Swap the new config into place and keep the old one under the other name, ready for a quick rollback with the same command.
- **Switching release directories.** If you deploy a new version of a site into a separate folder, you can swap it with the live folder in one step (remember the `-T`).
- **Undoing a swap.** Running the same command again swaps the files back.

## Limitations you should know

`mv --exchange` is not magic, and a few things can trip you up.

### Both paths must be on the same filesystem

The swap only works when both files live on the same filesystem. If you try to exchange a file on one filesystem with a file in a [tmpfs](https://docs.kernel.org/filesystems/tmpfs.html?ref=itsfoss.com) mount like `/dev/shm`, the kernel refuses the operation:

```
mv --exchange b.conf /dev/shm/x.conf

```

```
mv: cannot exchange 'b.conf' and '/dev/shm/x.conf': Unknown error -1

```

The message is not very helpful (it is the same "Unknown error -1" we saw in the directory mistake above), so it's worth knowing the real reason: the kernel can't swap names across two different filesystems.

Regular `mv` gets around this by copying the file and deleting the original, but that can't be done atomically, so `--exchange` doesn't even try.

![mv --exchange failing when the files are on different filesystems](https://itsfoss.com/content/images/2026/11/mv-exchange-cross-fs-error.png)

### The filesystem must support it

The underlying system call needs filesystem support. Common Linux filesystems such as ext4, Btrfs, XFS and tmpfs support it.

## Conclusion

`mv --exchange` is one of those small additions that removes a whole category of fiddly, error-prone shell work. If you are on a recent distribution like NixOS, Fedora or Debian 13, it is already on your system.

Next time you reach for a temporary file name to swap two things, try `mv --exchange` instead. Just remember to add `-T` when you swap directories.

✍️

Igor Giamoniano is a developer and teacher from São Paulo, Brazil. He contributes to the Brazilian Portuguese translation of the Linux kernel documentation and runs Coisa de Dev, where he teaches Linux and programming to a Brazilian audience. You can find his open source work on [GitHub](https://github.com/igorgbr?ref=itsfoss.com).