2

I'm looking for how to recursively copy a directory structure and then fill the copy with symlinks to the corresponding files from the source directory. This has a simple solution in Linux in the form of cp -as, but cp seems to lack the s option on macOS Mojave.

The underlying goal is to automate the process of making applications that do not reside in /Applications show up in Launchpad.

What would be an elegant, preferrably future proof, alternative to this on macOS?

From doing brew search cp I get the impression that Homebrew does not have an alternative version of cp.


Update

Additional information

I'm currently running this regularly, but I want to improve it by making it recursive:

ln -s /<Source app directory>/*.app /Applications

It also has to preserve the directory structure because:

  1. Subdirectories are used to manage sets of applications that are to be excluded from backup, without having to manually change Time Machine settings every time I add a new application. For instance, games are large and do not need to be backed up. Same goes for versions of Xcode.

  2. A mere symlink to a subdirectory does not include its linked target's applications in Launchpad.

  3. A symlinked directory would prevent creating a real directory with the same name. That prevents the source and destination directories from being organised identically.

  • Why would you do this on macOS rather than use hard links? This feels more like an XY question, but I think you’ll get the cp you want from homebrew and I’ll add a “use ditto” answer to review things like notarization, xattr, ACL and quarantine which are all relevant for /Applications and macOS changes coming past the initial Catalina release. – bmike Nov 24 '19 at 19:29
  • @bmike You can't use hard links over file system boundaries. I don't really see a point in not placing apps in /Applications unless they're on a separate volume. Not familiar with ditto -- I'll check it out, thanks. No plans to update to Catalina within the forseeable future though, since I have games that I want to be able to run. – Andreas Nov 24 '19 at 20:01
  • Perfect - sounds good Andreas - you’ve got time then to suss out APFS / HFS+ and the tools – bmike Nov 24 '19 at 20:17
2

The GNU version of cp is part of coreutils

brew install coreutils

It gets installed as gcp to avoid conflicts with the BSD version of cp (which behaves differently for some arguments).

| improve this answer | |
  • Nice detective work! I was wrong. I'll try it out. – Andreas Nov 24 '19 at 14:48
  • This worked as advertised. Some advice to others trying this: don't do what I did and forget that .apps are directories 🤦‍♀️🤦‍♂️ Back to the drawing board... – Andreas Nov 24 '19 at 15:25
  • @Andreas You might get some ideas on how to accomplish what you want by posting a new question describing the problem you want to solve and any constraints a solutions needs to consider. – nohillside Nov 24 '19 at 15:34
  • Thanks. I'm considering it, just have to research existing options. I think unix.stackexchange.com/a/343601/109837 might hold the answer. – Andreas Nov 24 '19 at 15:38
  • 1
    This answers the question asked - how to use cp however, there’s more at stake specifically with /Applications in terms of quarantine bits, notarization, etc. I strongly recommend people use ditto if they know they are on macOS for things that gatekeeper and code signing / notarization will validate. Over time, cp surely will handle things like making APFS clones rather than just copying the data a second time, working harmoniously with APFS transparent compression, working harmoniously with APFS snapshots and per file based encryption, etc.. But today, ditto is the tool for this job – bmike Nov 24 '19 at 18:44
1

If you are on APFS - I would use ditto which preserves all the metadata, understands APFS transparent compression and handles all of the native items as well as POSIX items like suid/sgid

This will save you headaches with tools that don’t preserve code signing, notarization, quarantine bits and more when those all become mandatory in future releases.

| improve this answer | |
  • The links reside on APFS and point to HFS+. Does ditto create symlinks? – Andreas Nov 24 '19 at 20:05
  • @Andreas It handles sym links well for my needs, but I don’t run as cp -as so test that first, but I’m not sure if you’re crossing disks and mixing / matching APFS with HFS+ - I’d be surprised if you couldn’t use ditto, but might not need to. – bmike Nov 24 '19 at 20:18
  • 1
    ditto doesn't create symlinks instead of copying, so I'm not sure it behaves the same way as (GNU)cp -as. But then I also not fully sure I understand the intention of the whole operation, so it might be just right for the job after all :-) – nohillside Nov 24 '19 at 21:13
  • Thanks for the clarifications. @nohillside The intention was to make apps not in /Applications, but in another identically organised Application directory, show up in Launchpad. But since .apps are directories, which I stupidly forgot about, this one gcp operation is not enough. I think I'm looking at first duplicating the directory structure with something similar to rsync --exclude '*.app/' --include '*/' --exclude '*' and then symlink all *.app directories as a second phase. – Andreas Nov 25 '19 at 2:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .