Rendered at 13:26:36 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
bariumbitmap 2 days ago [-]
This blog post is odd because it keeps on hinting about a difference between `-r' and `-R' and links to the source code but never actually says what it is. I'll quote the OpenBSD manual that the post mentions but does not link to for some reason:
> Historic versions of the cp utility had an -r option. This implementation supports that option; however, its use is strongly discouraged, as it does not correctly copy special files, symbolic links or FIFOs.
You can see it in the code, lstat vs stat and copy_special, copy_fifo vs copy_file. They're all in utils.c.
from the lstat man page:
The lstat() function is identical to stat() except when the named file is
a symbolic link, in which case lstat() returns information about the link
itself, not the file the link references.
> links to the source code but never actually says what it is.
The snippet of code makes it very clear what the difference is, no?
flag_copy_as_regular = 1 VS flag_copy_as_regular = 0, where regular would be a "regular" and not "special" file.
rezonant 16 hours ago [-]
Only clear to those with a heavy UNIX background-- I understood and correctly interpreted it on first read, but the concept of a "regular file" is a bit in the wonk territory for most users, though the implication on symbolic links is a very practical one that surely lead to the removal (in the implementations where it was removed) of this option, since its very surprising that copying a directory heirarchy would cause symbolic links to become copies of what they linked to, instead of remaining symbolic links in the resulting directory.
Modified3019 16 hours ago [-]
I have no idea what that means, or what the consequences would be for choosing one or the other.
wodenokoto 10 hours ago [-]
That’s for gnu implementation. For the BSD implementation author just links to the source code.
maxlin 17 hours ago [-]
Nope. That variable name could mean anything
unrented7977 1 hours ago [-]
No, "special" and "regular" have very specific meaning when next to "file"
ddosmax556 14 hours ago [-]
For those that don't know what 'copy as regular file' means, it means the copy command opens any file as though it was a regular file. If you have a FIFO queue sitting around it will read the content of the FIFO queue - if nothing writes to it, the command will hang. If you do cp -r /dev/zero foo, it will write zeroes into foo until the disk is full. -R otoh will copy a fifo queue as a fifo queue.
chasil 15 hours ago [-]
The POSIX standard does not appear to support -r lowercase (so don't use it!):
Hey, I perfectly understand if not. But do you have the sources that were used to build those binaries?
The oldest version on the GNU ftp server is fileutils-3.13 [1]. I vaguely remember having some links to older versions, probably somewhere in my archived mail. But I don't remember if it was fileutils-3.9 or earlier.
I co-maintain GNU coreutils, so I am interested in reading them. If you have them, you can email me privately or on the public mailing list. Both are listed on the homepage [2].
When you get to packages that are old enough, DiscMaster[0] is helpful for this since these packages were often on magazine cover CD-ROMs! There are several files matching "fileutils-3.9.tar.gz"[1]; the two variants seem to be the original GNU release (182.9KiB, the one you're looking for), and what looks like the result of a "make install" (57.4KiB).
The original GNU release of fileutils-3.6 is there too (but be careful; one of the two files appears to include Makefiles from a ./configure run, while the other doesn't), though 3.7 and 3.8 don't appear to be. You'll need to sift through to find what you need in some cases, but it's an incredibly valuable research tool.
Note: To download a file, you'll need to click on the filename, and then click the small arrow at the top that looks like a red arrow pointing down to a white box with red/green lights. (Which I assume is their representation of a desktop computer.)
You should have run that command as the `nobody` user.
tosti 2 days ago [-]
But nobody doesn't have a valid shell.
kijin 1 days ago [-]
Nothing you can't fix if you have root. :)
laxd 17 hours ago [-]
Use toor for good measure.
mkl 2 days ago [-]
-a
Not sure why you wouldn't want to preserve timestamps, links, etc. by default.
JdeBP 2 days ago [-]
This is rather missing the point. The headlined article isn't really about how to achieve a goal, but about the weird history and evolution of a tool that leads us to the rather odd situation that we are in today. And it's far from being the only tool that has a weird history, that looks rather nutty if one looks at it from the point of view of a novice having to learn this stuff.
It's also not even completely covering the weird case of -r and -R for the cp command. On HP-UX, for example, the twain were different, but not in the way that they were in old GNU Core Utilities. That would be too easy. (-:
The AIX manual for cp explains its difference between -r and -R:
That's why, just as fork(2) is a primitive for the process creation, copy(2) should've been the primitive for the file creation — creates an exact copy of the file under a new name, but with the exact same content and all of the metadata (except for the name, obviously), including its kind, permissions, timestamps, etc. And no, it wouldn't be prohibitively expensive because all filesystems can quite easily support CoW; after all, most of the created files will be truncate(2)d almost immediately, so there is no point to eagerly duplicate the file contents.
The "metadata is atomically copied" part would support very nicely the usual text editor's idiom of rename(2)ing a temporary file over the source after fully writing it out — you still need to accurately replicate the permissions and extended attributes. And just as shells are important enough programs to have fork(2) almost exactly suited for them, it would make sense to have copy(2), suited for the text editors.
JdeBP 2 days ago [-]
When cp was invented, 'most filesystems' did not have the first clue about copy on write.
However, I should note that possibly the first company to invent what you describe was Microsoft.
Novell Netware 386 had an NCOPY command which invoked a Netware extension to the DOS API that told the server to perform the entire copy on the server.
But even earlier, OS/2 1.x had a proper DosCopy() system call. Since it could be passed down to the installable filesystem drivers for intra-volume copies, something like the Netware client for OS/2 could in theory turn it into the same protocol call that did server-side copies. There was a NET COPY command in LAN Manager (and LAN Server, if memory serves) that did the same optimization.
> When cp was invented, 'most filesystems' did not have the first clue about copy on write.
Eh, when fork was invented, most (virtual) memory systems did not have the first clue about copy-on-write either. And honestly, it's really not that difficult to support — it's essentially hard links, just with slightly different semantics.
collinfunk 1 days ago [-]
In theory, I agree that it shouldn't be tricky. However, in practice, it is a bit tricky since all the different implementations have different ways to perform reflinks.
Linux has FICLONE [1], which I prefer because it operates on two file descriptors, allowing you to safely modify file metadata after the fact. macOS has clonefile, clonefileat, and fclonefileat [2]. Sadly, there is no way to operate on two file descriptors. The best you get is fclonefileat, which operates on a source file descriptor. Solaris has reflink and reflinkat, which operate on two paths, the latter relative to file descriptors [3]. In that case, one needs to be careful opening the destination to make changes to the metadata.
GNU coreutils has support for reflinks on Linux and macOS. But I've been thinking about adding support for Solaris as of late [4]. Sadly, I don't use it enough to test it as much as I would like.
Hopefully, a few years down the line the interfaces converge, and it is as simple as hard linking.
You still need to specify --archive (or --times for the individual option) to preserve mtime in the target copy.
But yeah, I tend to rsync more than I cp.
BobMontgomeryJr 2 days ago [-]
-h perhaps the only useful comment here.
-R just looks baroque, but ls(1) might think it fine.
I once read an article about the inconsistencies in *nix CLI commands,
but the picture's much better than hot-key and shortcut conflicts-
<which get silently absorbed by whatever's running,
no way to tell what they might've done or where they went..>
I hestitate to consult documentation, because of course there is non anymore.
Why not Google it?
throwaway2046 2 days ago [-]
I'm more inclined to use the uppercase -R as it's standardized by POSIX and will generally behave the same on any POSIX compliant system.
WhyNotHugo 2 days ago [-]
It's also the only option shown in the -h output and in man pages for some versions of cp.
I didn't even know -r was a thing until today.
dataflow 18 hours ago [-]
Kind of off topic, but why in the world in 2026 do POSIX utilities still rely on global variables to pass around state? Is it too complicated to pass around a struct address in C or something?
turtledragonfly 17 hours ago [-]
I think there is a class of programs where globals are not so terrible. In particular, one-shot programs that do a task and then exit (like `ls`, `cp`, etc).
You may also notice that some of these utilities will allocate memory, then never free it. They just let the OS handle that on program shutdown. That is also generally not recommended in arbitrary code. But again, it's fine for a one-and-done sort of program.
For these cases, the whole program is essentially one function call, and the global namespace is essentially the "body" of that function (hand waving a bit).
It's all a bit subjective, of course (:
Bjartr 17 hours ago [-]
Reminds me of the story of the memory leak in a missile guidance computer. It was determined that in the worst case scenario not enough memory could leak fast enough for it to be a problem between missile launch and impact. So they just let the explosion handle the garbage collection
comex 5 hours ago [-]
Many of those utilities, if you inspect the source code, are recognizably the same programs as their original versions written 30+ years ago. They’ve been maintained and changed over the years, sure, but they’ve rarely needed big changes. After all, they’re simple programs that do basically the same job today as they did then, using basically the same API surface.
The main issue with this is that the programs are usually still single-threaded. For some key utilities like find and grep, this has allowed more modern alternatives to leapfrog them in performance. (To be fair, it’s hard to add parallelism without breaking compatibility somewhat.)
But in most other respects, there’s nothing wrong with being a little old-fashioned. Using global variables is an example of that. It’s a problem in larger programs but at this scale it’s fine.
kelnos 14 hours ago [-]
Because there's nothing inherently wrong with global variables. In small utilities like these, I would argue it would be less readable to do as you describe.
Sure, in anything larger, or anything that needs to be reentrant, global variables are going to hurt. But this is not that.
chasil 15 hours ago [-]
It really doesn't make any difference if the source for a utility exhibits terrible coding practices. If it passes the tests, then the OS can be certified.
We'd prefer Rust versions with great forethought, but it's irrelevant to the testing.
There is no current version of Linux [uswrland] that maintains certified POSIX compliance. Only Apple, IBM, HP, and SCO are current?
Because why not? "Globals bad"? goto is still being used where it makes sense as well.
It's a good rule of thumb to avoid them both, especially when you're inexperienced yet, but they still have their uses - as implied by it being a "rule of thumb".
drhagen 2 days ago [-]
It always seemed like the recursive flag of cp was an implementation detail leaking into the UI. Like, I get that copying a file requires creating more than one inode, but...so? Eventually, graphical OSes agree with me—copy/paste works the same on folders as it does on files.
seoulbigchris 2 hours ago [-]
This was back in the early 90s. Our company used DOS and Windows machines for the most part, but we had a brand new Sun workstation for an advanced PCB layout tool (Cadence?). One day my buddy was working on the Sun, and wanted to make a backup before starting a new task. He did something like `mkdir backup` and `cp -r * backup`. It started churning away, and we went to lunch. Came back from lunch, and the machine was frozen. It took us a few moments before we realized what went wrong. He had copied recursively forever, or rather, until there was no more free disk space. In our defense, we were new to Unix and still learning.
It seems that recursive by default would have been much more intuitive.
JdeBP 2 days ago [-]
It's rather sad that none of the answers were that the cp command simply did not gain a recursive option until the 1980s, well into the 1980s if you were on one side of the Unix wars.
Yes, seriously. When you read about the supposed evils of cat -v from the Unix nostalgia people, remember that it was the same people who gave cat its -v option who also gave cp its -r option, in 4.2BSD.
It took over half a decade to percolate out of the BSD world, too. AT&T Unix System 5 did not have an -r option to cp. Here's Brandon S. Allbery explaining in 1987 how one copies directories on AT&T Unix System 5 Releases 2/3 by combining find and cpio -p:
Originally we read directories as raw byte streams and liked it, you know. (-:
Joker_vD 2 days ago [-]
> When you read about the supposed evils of cat -v from the Unix nostalgia people, remember that it was the same people who gave cat its -v option who also gave cp its -r option, in 4.2BSD.
Then the people who complained about cat -v went ahead and made better Unix, called Plan 9, in which moving (as opposed to merely renaming) a directory is impossible: instead, you're supposed to do mkdir && dircp && rm -r. Which is quite a choice, if I say so myself: there is simply no low-level primitive (syscall or 9p message) for moving files across directories, even on the same file server. Their version of mv can move files across the directories, but it's still done with internal equivalent of cp+rm.
pjmlp 4 hours ago [-]
They also ignored what was happening with C outside Bell Labs, and thus the Plan 9 C compiler is rather special versus a ISO C compiler of the time, in how files are organised and available features.
Afterwards they made a better Plan 9, called Inferno, with a safer userspace programming language, leaving their C creation only for kernel code, and DisVM implementation.
ButlerianJihad 15 hours ago [-]
You know, when I came into Unix in the 1990s we still didn't care about recursive copy, because all admins learned the standard idiom to copy over a hierarchy:
tar cf - . | ( cd /new/path; tar xpf - )
or thereabouts, because at the time, `tar` was more than capable of doing all the filesystem tricks that `cp` was clumsy with, and we understood this idiom well. You could also `dump` an entire block device.
I believe that my motivation was that the Unix wars were still raging hotly; as a sysadmin I needed portable skills and I wasn't tied or certified to one vendor's Unix, and therefore I sought out idioms that worked on SunOS, HP/UX, AIX, BSD, you name it. "cp -r" didn't enjoy that stable support at the time.
JdeBP 9 hours ago [-]
I don't care all that much even today. (-:
I use pax -r -w most of the time.
alwillis 2 days ago [-]
ditto is an option on macOS for copying files and directories [1].
I really wish there was a way to know if LLMs hallucinate these switches incorrectly, like I do.
Feels like this would be exactly the kind of thing they would get wrong. Fur exactly, the training set isn't trained to know the context of execution (FreeBSD vs macos vs Linux), right?
saidnooneever 2 days ago [-]
its trained to read both tekst and code which is enough to know the difference.
appearently i am not :') never knew there was -r
hirvi74 11 hours ago [-]
I never knew there was a -R. =')
bdavbdav 2 days ago [-]
This always get me. I instinctively -r, until chown which of course doesn’t take it.
jwrallie 14 hours ago [-]
The worst is that I can never remember if it’s chown or chmod that is the odd one.
However, some tools like cp starting using both -r and -R to mean recursive, and I imagine there are many newer tools where the author chose -r for recursive only.
Things change over time.
krn1p4n1c 2 days ago [-]
tar cf - . | tar xf - -C <dest>
jhallenworld 16 hours ago [-]
I never bothered to learn -C, instead I use:
tar -cf - . | (cd <dest>; tar -xf -)
For doing something like duplicating root of a filesystem you may want --one-file-system.
Rygian 2 days ago [-]
with a sandwiched `| pv |` for fun stats
dspillett 2 days ago [-]
And `| ssh <target> ` for a remote copy.
(or ssh <target> prepended rather than sandwiched, to copy from remote)
Rygian 2 days ago [-]
At some point it starts very much looking like zfs send | pv | ssh <target> zfs receive
krn1p4n1c 2 days ago [-]
Seriously. I do wish ZFS was everywhere.
krn1p4n1c 2 days ago [-]
I usually sandwich zstd and base64 encode/decode in with the ssh pipe. Used when I need root permissions to pull the remote dirs.
dspillett 2 days ago [-]
You shouldn't need to B64 encode for transfer - piping over SSH is binary safe. Verifying with 100Mbyte of random data:
When using zstd (or anything else) make sure you don't have something in your .sss/config that would make ssh use a compression as you'll waste a bit of CPU to send a little more data as a less efficient compression method is applied on top. Though TBH I think that unless I'm on a very slow link, if I'm sending something big enough to need compression it is probably in a pre-compressed or otherwise uncompressable format anyway (video, photos, …) so zstd does little, the one exception I can think of being if I'm throwing an unencrypted VM image from place to place.
bitwize 15 hours ago [-]
Slumming Pooh: cp -r
Sophisticated Pooh: cp -a
bsoqk 2 days ago [-]
It's "ditto", not "dito"
Waterluvian 2 days ago [-]
As in the Pokémon, not the Philippines telecom company.
Yaqub_W 2 days ago [-]
Much easier to press a key twice than to hunt for é for most people.
I get your point though
greatgib 2 days ago [-]
I never noticed but indeed in France the official name is "Pokémon" and not "Pokemon".
So that the pronunciation in French is correct.
Is it the case in another country to have a localized name for that?
jolmg 17 hours ago [-]
In Spanish, it's there but it's a bit wrong/redundant. The phonic/prosodic accent would've been on the "e" regardless because of the "n" ending, so it's a bit wrong to add it graphically as if it would've been elsewhere.
Bit curious what the pronunciation difference would've been in French.
On another note, looking at the Wikipedia article:
> When the franchise was released internationally, the short form of the title was used, with an acute accent (´) over the e to aid in pronunciation.
I'm realizing that didn't do anything for English since the syllable stressed in English is "Po".
Dylan16807 13 hours ago [-]
English doesn't really use acute accents for stress though. Especially on an e it's usually there to change the vowel sound.
amenghra 2 days ago [-]
Pokémon is the trademark (see e.g. https://en.wikipedia.org/wiki/Pok%C3%A9mon). Pokemon is common spelling in countries where keyboards don't have é and/or where people aren't used to inputting é.
It is common for brands to localize their names. E.g. Axe (the deodorant) in some countries is branded as Lynx.
Lucky that the other modern OSes have all decided to make this as trivial as it is on MacOS /sarcasm
Waterluvian 2 days ago [-]
Apparently Pokémon is in my phone’s word book.
2 days ago [-]
NaiveBayesian 2 days ago [-]
Huh, TIL. In German, "dito" is the correct spelling, so I always figured it would be the same in English as well.
andrewshadura 18 hours ago [-]
In Slovak, it’s detto :)
5555watch 2 days ago [-]
On a somewhat related note, I really hate that in scp -r and -R mean entirely different things.
pluc 2 days ago [-]
The worst is when things behave different when you give them `~/somedir` vs `~/somedir/`. I think it's rsync that does that
GrantMoyer 2 days ago [-]
I really like this feature of rsync (trailing "/" means copy the directory contents to the dest, no trailing "/" means copy the directory itself). Other tools, like cp, don't have any way at all to say copy the directory contents to the dest, and for those tools the result depends on whether or not the destination already exists and is a directory (you might end up with a duplicate nested directory). Rsync produces the same result whether the destination already exists or not.
0xpgm 8 hours ago [-]
Why not let the shell do the expansion of `somedir/*` to refer to the content of the directory instead?
GrantMoyer 56 minutes ago [-]
Depending on the shell, `somedir/*` excludes files whose names start with "." and may expand to a literal "*" if there are no file names to expand to. Basically, globbing has more edge cases to deal with.
1718627440 5 hours ago [-]
Because then you don't have two parameters anymore and need a marker between source and target arguments.
3 hours ago [-]
0xpgm 4 hours ago [-]
Makes sense.
mjmas 2 days ago [-]
rsync, or at least the version I had would behave differently for 'rsync a b' vs 'rsync a/ b/', even though I added the slash for both sides.
IshKebab 2 days ago [-]
And `cp`.
brewmarche 2 days ago [-]
I remember that macOS/FreeBSD’s cp -R behaves differently depending on the trailing slash (it’s pointed out in the man page). But when I compared with GNU coreutils and busybox they did not, so it’s something to look out for.
amelius 2 days ago [-]
Yes, into versus onto. Luckily we have AI to write our command lines.
aulin 2 days ago [-]
How about port that is lowercase in ssh and uppercase in scp?
wanick 2 days ago [-]
scp took -p from rcp/cp, where it already meant preserve times. So port got -P.
mqus 2 days ago [-]
would you be safe in using --recursive always? (e.g. shell scripts)
hnfong 2 days ago [-]
Double dash long options are basically a GNU extension. BSD utilities generally don't support them. Apparently macOS does not either (since it's based off of FreeBSD)
JdeBP 2 days ago [-]
macOS was based off NeXTSTEP, not FreeBSD.
And the received wisdom about long options in the BSDs is a quarter of a century out of date. When the BSDs gained a getopt_long() in their C libraries thanks to Klausner and Baron, long options quietly started appearing. This process has been gradually and quietly on-going for the whole of the 21st century.
Over a decade after macOS/Mac OS X was initially released:
> macOS (previously OS X and originally Mac OS X) is a proprietary Unix[7][8] operating system, derived from OPENSTEP for Mach and FreeBSD, which has been marketed and developed by Apple since 2001.
> Darwin is the core Unix-like operating system of macOS, iOS, watchOS, tvOS, iPadOS, audioOS, visionOS, and bridgeOS. It previously existed as an independent open-source operating system, first released by Apple in 2000. It is composed of code derived from NeXTSTEP, FreeBSD[3] and other BSD operating systems,[7] Mach, and […]
Bah! Thought NeXTSTEP. Typed NextBSD. Fixed. I've been typing lots of names ending in 'BSD' today. (-:
hnfong 2 days ago [-]
I posted my original comment based off my pre-existing knowledge, but here's a more in-depth explanation of the macOS and FreeBSD situation (which aligns with my understanding):
Essentially, macOS was indeed based on NeXTSTEP originally, but over the years they copied quite a bit of BSD code over (mostly FreeBSD I think). I don't think the Unixy parts of the original NeXTSTEP survives much in modern macOS.
toast0 13 hours ago [-]
Much of the macos Unix userland is from FreeBSD as are some parts of the kernel, such as the ip stack. Check the man pages for cp and friends in mac and I believe they still reference FreeBSD.
> And the received wisdom about long options in the BSDs is a quarter of a century out of date.
Incidentally, so is much of the FreeBSD code. Many things were taken once, never updated from upstream again. I think a lot of the userland did get an update somewhere around 2014... all of a sudden, cal would highlight the current date, years after that happened upstream. But the IP stack hasn't gotten any updates from upstream AFAIK, probably because Apple customized it and it's too much work to merge in improvements that probably won't be noticed on client systems (things like syncookies).
my123 7 minutes ago [-]
[dead]
olowe 2 days ago [-]
There are implementations of cp out in the wild that do not recognise the --recursive flag. OpenBSD was mentioned in the article and there’s also busybox cp https://busybox.net/downloads/BusyBox.html
dotancohen 2 days ago [-]
I believe that -R is the safe works-as-expected-everywhere option.
pasc1878 2 days ago [-]
Use rsync instead
5555watch 2 days ago [-]
In my minimal attempts to use rsync, I always find examples where they always use a ton of flags alongside the locations. I'm not gonna learn those flags if cp can do it intuitively and with minimal extra commands. Maybe it's just me.
CoastalCoder 2 days ago [-]
Not just you.
Also, I always have this vague fear that I'll rsync in the wrong direction, or accidentally blow away unrelated files in rsync's efforts to fully synchronize two directories (can't remember if this is a valid concern).
I'm sure these concerns would go away if I used it regularly, but I just don't. ‘cp' or ’scp’ almost always meet my needs.
Kinda like the way people are probably right that I should learn to use ’awk’, but I just can't muster the motivation.
toast0 13 hours ago [-]
> Also, I always have this vague fear that I'll rsync in the wrong direction
It's the same direction as cp/scp ... You could easily do it wrong, but you must be afraid to do anything other than maybe cat < source > dest because that's clear?
> or accidentally blow away unrelated files in rsync's efforts to fully synchronize two directories (can't remember if this is a valid concern).
I think you need --delete for this. As I recall, it's sometimes more tricky to get it to delete the files you wanted it to delete and you're more likely to end up with extra files than removing files you didn't intend to.
groestl 2 days ago [-]
Do it once, make it your muscle memory - it's really hard for me to learn things by heart, but even I could do it :), and then you can forget about scp as well
trucks-refinish 2 days ago [-]
rsync unfortunately doesn't do relinking at all, so I can't use it as a generic replacement for cp.
groestl 2 days ago [-]
Relinking?
rincebrain 2 days ago [-]
I assume they typoed reflinking, a way of doing CoW-based copying of file contents.
groestl 2 days ago [-]
I was under the impression it could do that, I think I build a snapshotting mechanism using this.
Flimm 2 days ago [-]
rsync does not have the ability to copy a file using the filesystem's copy-on-write feature. This is unlike cp, which has the --reflink flag. Here's the bug report on GitHub which the developers closed as "won't fix for now":
> Historic versions of the cp utility had an -r option. This implementation supports that option; however, its use is strongly discouraged, as it does not correctly copy special files, symbolic links or FIFOs.
https://man.openbsd.org/cp
from the lstat man page:
symbolic link example: For posterity, -R with added -LThe snippet of code makes it very clear what the difference is, no?
flag_copy_as_regular = 1 VS flag_copy_as_regular = 0, where regular would be a "regular" and not "special" file.
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/c...
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/
Edit: adjusted to the latest version of the standard.
The oldest version on the GNU ftp server is fileutils-3.13 [1]. I vaguely remember having some links to older versions, probably somewhere in my archived mail. But I don't remember if it was fileutils-3.9 or earlier.
I co-maintain GNU coreutils, so I am interested in reading them. If you have them, you can email me privately or on the public mailing list. Both are listed on the homepage [2].
[1] https://ftp.gnu.org/old-gnu/fileutils/ [2] https://www.gnu.org/software/coreutils/
The original GNU release of fileutils-3.6 is there too (but be careful; one of the two files appears to include Makefiles from a ./configure run, while the other doesn't), though 3.7 and 3.8 don't appear to be. You'll need to sift through to find what you need in some cases, but it's an incredibly valuable research tool.
Note: To download a file, you'll need to click on the filename, and then click the small arrow at the top that looks like a red arrow pointing down to a white box with red/green lights. (Which I assume is their representation of a desktop computer.)
[0] https://discmaster.textfiles.com/
[1] https://discmaster.textfiles.com/search?q=fileutils-3.9.tar....
Not sure why you wouldn't want to preserve timestamps, links, etc. by default.
It's also not even completely covering the weird case of -r and -R for the cp command. On HP-UX, for example, the twain were different, but not in the way that they were in old GNU Core Utilities. That would be too easy. (-:
The AIX manual for cp explains its difference between -r and -R:
* https://ibm.com/docs/en/aix/7.1.0?topic=c-cp-command
Illumos also treats the two differently, but in a subtly different way:
* https://illumos.org/man/1/cp
The "metadata is atomically copied" part would support very nicely the usual text editor's idiom of rename(2)ing a temporary file over the source after fully writing it out — you still need to accurately replicate the permissions and extended attributes. And just as shells are important enough programs to have fork(2) almost exactly suited for them, it would make sense to have copy(2), suited for the text editors.
However, I should note that possibly the first company to invent what you describe was Microsoft.
Novell Netware 386 had an NCOPY command which invoked a Netware extension to the DOS API that told the server to perform the entire copy on the server.
But even earlier, OS/2 1.x had a proper DosCopy() system call. Since it could be passed down to the installable filesystem drivers for intra-volume copies, something like the Netware client for OS/2 could in theory turn it into the same protocol call that did server-side copies. There was a NET COPY command in LAN Manager (and LAN Server, if memory serves) that did the same optimization.
* https://www.edm2.com/index.php/DosCopy_(OS/2_1.x)
* https://www.edm2.com/index.php/FS_COPY
Eh, when fork was invented, most (virtual) memory systems did not have the first clue about copy-on-write either. And honestly, it's really not that difficult to support — it's essentially hard links, just with slightly different semantics.
Linux has FICLONE [1], which I prefer because it operates on two file descriptors, allowing you to safely modify file metadata after the fact. macOS has clonefile, clonefileat, and fclonefileat [2]. Sadly, there is no way to operate on two file descriptors. The best you get is fclonefileat, which operates on a source file descriptor. Solaris has reflink and reflinkat, which operate on two paths, the latter relative to file descriptors [3]. In that case, one needs to be careful opening the destination to make changes to the metadata.
GNU coreutils has support for reflinks on Linux and macOS. But I've been thinking about adding support for Solaris as of late [4]. Sadly, I don't use it enough to test it as much as I would like.
Hopefully, a few years down the line the interfaces converge, and it is as simple as hard linking.
[1] https://man7.org/linux/man-pages/man2/FICLONE.2const.html [2] https://www.manpagez.com/man/2/clonefile/ [3] https://docs.oracle.com/cd/E86824_01/html/E54766/reflinkat-3... [4] https://lists.gnu.org/archive/html/coreutils/2026-09/msg0012...
Anyway, just use rsync.
You still need to specify --archive (or --times for the individual option) to preserve mtime in the target copy.
But yeah, I tend to rsync more than I cp.
I didn't even know -r was a thing until today.
You may also notice that some of these utilities will allocate memory, then never free it. They just let the OS handle that on program shutdown. That is also generally not recommended in arbitrary code. But again, it's fine for a one-and-done sort of program.
For these cases, the whole program is essentially one function call, and the global namespace is essentially the "body" of that function (hand waving a bit).
It's all a bit subjective, of course (:
The main issue with this is that the programs are usually still single-threaded. For some key utilities like find and grep, this has allowed more modern alternatives to leapfrog them in performance. (To be fair, it’s hard to add parallelism without breaking compatibility somewhat.)
But in most other respects, there’s nothing wrong with being a little old-fashioned. Using global variables is an example of that. It’s a problem in larger programs but at this scale it’s fine.
Sure, in anything larger, or anything that needs to be reentrant, global variables are going to hurt. But this is not that.
We'd prefer Rust versions with great forethought, but it's irrelevant to the testing.
There is no current version of Linux [uswrland] that maintains certified POSIX compliance. Only Apple, IBM, HP, and SCO are current?
https://www.opengroup.org/openbrand/register/
It's a good rule of thumb to avoid them both, especially when you're inexperienced yet, but they still have their uses - as implied by it being a "rule of thumb".
https://unix.stackexchange.com/questions/82485/when-wouldnt-...
It seems that recursive by default would have been much more intuitive.
Yes, seriously. When you read about the supposed evils of cat -v from the Unix nostalgia people, remember that it was the same people who gave cat its -v option who also gave cp its -r option, in 4.2BSD.
It took over half a decade to percolate out of the BSD world, too. AT&T Unix System 5 did not have an -r option to cp. Here's Brandon S. Allbery explaining in 1987 how one copies directories on AT&T Unix System 5 Releases 2/3 by combining find and cpio -p:
* https://groups.google.com/g/comp.unix.questions/c/XiumTgkcYR...
Originally we read directories as raw byte streams and liked it, you know. (-:
Then the people who complained about cat -v went ahead and made better Unix, called Plan 9, in which moving (as opposed to merely renaming) a directory is impossible: instead, you're supposed to do mkdir && dircp && rm -r. Which is quite a choice, if I say so myself: there is simply no low-level primitive (syscall or 9p message) for moving files across directories, even on the same file server. Their version of mv can move files across the directories, but it's still done with internal equivalent of cp+rm.
Afterwards they made a better Plan 9, called Inferno, with a safer userspace programming language, leaving their C creation only for kernel code, and DisVM implementation.
I believe that my motivation was that the Unix wars were still raging hotly; as a sysadmin I needed portable skills and I wasn't tied or certified to one vendor's Unix, and therefore I sought out idioms that worked on SunOS, HP/UX, AIX, BSD, you name it. "cp -r" didn't enjoy that stable support at the time.
I use pax -r -w most of the time.
[1]: https://keith.github.io/xcode-man-pages/ditto.1.html
Feels like this would be exactly the kind of thing they would get wrong. Fur exactly, the training set isn't trained to know the context of execution (FreeBSD vs macos vs Linux), right?
appearently i am not :') never knew there was -r
However, some tools like cp starting using both -r and -R to mean recursive, and I imagine there are many newer tools where the author chose -r for recursive only.
Things change over time.
(or ssh <target> prepended rather than sandwiched, to copy from remote)
Sophisticated Pooh: cp -a
Is it the case in another country to have a localized name for that?
Bit curious what the pronunciation difference would've been in French.
On another note, looking at the Wikipedia article:
> When the franchise was released internationally, the short form of the title was used, with an acute accent (´) over the e to aid in pronunciation.
I'm realizing that didn't do anything for English since the syllable stressed in English is "Po".
It is common for brands to localize their names. E.g. Axe (the deodorant) in some countries is branded as Lynx.
And the received wisdom about long options in the BSDs is a quarter of a century out of date. When the BSDs gained a getopt_long() in their C libraries thanks to Klausner and Baron, long options quietly started appearing. This process has been gradually and quietly on-going for the whole of the 21st century.
"NextBSD" was first released in 2015:
* https://en.wikipedia.org/wiki/NextBSD
Over a decade after macOS/Mac OS X was initially released:
> macOS (previously OS X and originally Mac OS X) is a proprietary Unix[7][8] operating system, derived from OPENSTEP for Mach and FreeBSD, which has been marketed and developed by Apple since 2001.
* https://en.wikipedia.org/wiki/MacOS
> Darwin is the core Unix-like operating system of macOS, iOS, watchOS, tvOS, iPadOS, audioOS, visionOS, and bridgeOS. It previously existed as an independent open-source operating system, first released by Apple in 2000. It is composed of code derived from NeXTSTEP, FreeBSD[3] and other BSD operating systems,[7] Mach, and […]
* https://en.wikipedia.org/wiki/Darwin_(operating_system)
I remember reading release notes for FreeBSD in the '00s and seeing the exact same lines in the release notes for earlier versions of OS X.
macOS isn't "Unix-like"; it's an Open Group certified UNIX™ [1].
[1]: https://www.opengroup.org/openbrand/register/brand3725.htm
https://www.reddit.com/r/freebsd/comments/1g07sdm/comment/lr...
Essentially, macOS was indeed based on NeXTSTEP originally, but over the years they copied quite a bit of BSD code over (mostly FreeBSD I think). I don't think the Unixy parts of the original NeXTSTEP survives much in modern macOS.
> And the received wisdom about long options in the BSDs is a quarter of a century out of date.
Incidentally, so is much of the FreeBSD code. Many things were taken once, never updated from upstream again. I think a lot of the userland did get an update somewhere around 2014... all of a sudden, cal would highlight the current date, years after that happened upstream. But the IP stack hasn't gotten any updates from upstream AFAIK, probably because Apple customized it and it's too much work to merge in improvements that probably won't be noticed on client systems (things like syncookies).
Also, I always have this vague fear that I'll rsync in the wrong direction, or accidentally blow away unrelated files in rsync's efforts to fully synchronize two directories (can't remember if this is a valid concern).
I'm sure these concerns would go away if I used it regularly, but I just don't. ‘cp' or ’scp’ almost always meet my needs.
Kinda like the way people are probably right that I should learn to use ’awk’, but I just can't muster the motivation.
It's the same direction as cp/scp ... You could easily do it wrong, but you must be afraid to do anything other than maybe cat < source > dest because that's clear?
> or accidentally blow away unrelated files in rsync's efforts to fully synchronize two directories (can't remember if this is a valid concern).
I think you need --delete for this. As I recall, it's sometimes more tricky to get it to delete the files you wanted it to delete and you're more likely to end up with extra files than removing files you didn't intend to.
https://github.com/RsyncProject/rsync/issues/119#issuecommen...