MacOS vs Linux — the cp command will trip you up!

While building I was recently confronted with more than a hundred failing unit tests when running the test suite locally on my MacOS machine, rather than in a Linux Docker container the platform is configured to run tests in.

I use a MacBook Pro for software development, primarily because the BSD based MacOS provides a development experience that’s very similar to other Linux distros. All of my most frequently used navigation commands — cd, cp, mv, mkdir, touch, with 1:1 parity across both flavors of operating systems, or at least that’s what I thought. As I discovered after spending a good hour debugging these failures, there’s a subtle difference between the BSD and GNU implementations of the cp -R command, which I got hit with when running my tests on different environments.

Here’s the difference, illustrated with an example run in both MacOS and Linux:

# Creates "source_directory" in the current working directory
$ mkdir source_directory
# Creates 2 new empty files within "source_directory"
$ touch source_directory/{file1,file2}
# Creates "destination_directory" in the current working directory
$ mkdir destination_directory
# Intended to copy the contents of "source_directory" to "destination_directory", hence the trailing slashes
$ cp -R source_directory/ destination_directory/
# Lists the contents of "destination_directory"
$ ls destination_directory

So what would you expect to be printed with ls? Turns out the Linux GNU implementation of cp copies the source_directory directory to destination_directory, whereas on BSD MacOS the contents are unpacked and copied, as I’d expected it to behave on both environments:

GNU (Linux):

$ ls destination_directory

BSD (MacOS):

$ ls destination_directory
file1 file2

The trailing slash is significant in BSD, whereas the GNU implementation treats both source_directory/ and source_directory the same. The workaround, thankfully, is really simple — append a period when you intend for the contents to be copied and you’ll see the same behavior on both BSD and GNU : cp -R source_directory/. destination_directory/.

I hope this tidbit helps you write better cross environment code on MacOS and helps you save some time debugging unexpected results.




Ads Engineering @Twitter, part time entrepreneur — built, options and algorithmic trading enthusiast

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Stranger danger — Prevent the leaking of secrets when committing code

#1 Building a JavaScript & HTML browser RPG : Mark-Up

Our young developers complete stage 1, first prototype of new app

[No Action Required] Operational Changes to App Uploads

Best themes for VS Code in 2021!

How critical is Continuous Testing for Implementing Digital Transformation Strategies

Project Quality Management

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ackshaey Singh

Ackshaey Singh

Ads Engineering @Twitter, part time entrepreneur — built, options and algorithmic trading enthusiast

More from Medium

Command line arguments in Bash Scripting

My experience with Windows Terminal

Stupid Bash Tricks: Pretty Path

Bash aliases

Bash shell