
Overlooked Linux Mv Option Replaces Three Commands with One
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.
以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。
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 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.
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:
mv nginx.conf nginx.conf.tmp mv nginx.conf.new nginx.conf mv nginx.conf.tmp nginx.conf.new
There are two problems here:
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() system call with the RENAME_EXCHANGE flag, so the swap is atomic: at any moment, both names exist and point to a file.
mv --version
On my machine, running NixOS, 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.
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.
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.
Here are a few situations where I find mv --exchange useful:
mv --exchange is not magic, and a few things can trip you up.
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 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.
The underlying system call needs filesystem support. Common Linux filesystems such as ext4, Btrfs, XFS and tmpfs support it.
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.
If this helped you, consider supporting It's FOSS
It's FOSS has been helping people use Linux for the past 14 years. Help us stay independent from big tech. Become a Plus member, enjoy ad-free reading and get 5 eBooks.
Skip the AI slop and SEO spam in your Google results
Tell Google you prefer It's FOSS, and it will show our Linux news and tutorials, created by experienced Linux users, more often when you search. It takes just a click.
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。