About Adam Patridge

patridgedev.com is my writing outlet for all things nerdy. You can read more on the About Me page.

Copy command line output to the clipboard on macOS, Windows, and Linux

You’ve just figured out the exact piece of information you need from a command line call. Now, how do you get it out of your terminal and take it somewhere else, like an email, chat, or document?

Fortunately, there are already programs out there to make this easy. You can send the output from any command to one of these applications, and the output will be available in your clipboard. From there, you can paste it anywhere you please. In the case of Windows and macOS, there are programs to do this that come with the OS. On Linux, you can install a tool to have the same functionality.

Windows

Whether you are in Command Prompt or PowerShell (old-school or Core), you can use the Windows clip application to get output to the clipboard. Should it matter to you, clip will append an extra line break to whatever you feed it.

command {some command} | clip

For example, to dump your file listing to the clipboard, you would run dir | clip or Get-ChildItem . | clip, with dir working in both cmd and all flavors of PowerShell and the later only working in PowerShell.

Windows (non-Core) PowerShell also offers its own command: Set-Clipboard that won’t append the line break. You can also pass it the -Append parameter to keep building a result in the clipboard.

powershell {some command} | Set-Clipboard

Unfortunately, the Set-Clipboard command isn’t available on PowerShell Core. For PowerShell Core, you’ll have to pass your output to the OS-specific version like clip or pbcopy, which is the magic program to use on macOS.

macOS

Whether you are in Terminal or PowerShell Core, you can use the macOS pbcopy application to get output to the clipboard. Should it matter to you, pbcopy will append an extra line break to whatever you feed it.

bash {some command} | pbcopy

So, for example, if you want to dump the current directory’s file listing to the clipboard, you would run ls | pbcopy or Get-ChildItem . | pbcopy.

Linux (probably not all variants)

To do the same magic on Linux, you need to install a program to do the work for you. One option is xclip. You can install it with apt-get.

bash sudo apt-get install xclip

From there, you can start passing things to the clipboard using xclip as your destination.

bash {some command} | xclip

Determine SHA hash of file on Windows, Linux, and macOS

While it doesn’t guarantee a download hasn’t been compromised, sometimes you feel better knowing the file you downloaded matches the expected SHA hash.

Full disclosure here: while I haven’t been paid or provided anything for this blog post, I am only creating this post for me. If it helps you, great! I just keep looking this up every time I need it. Instead of wading through a bunch of Stack Overflow answers to find the exact magic command I need, I’m hoping I’ll start finding my own blog post in my search results.

SHA-256 hash commands

Here’s what I use most days. There are bound to be other ways to do this, and on more operating systems or command line shells. As well, there may be ways that are better suited for certain tasks like scripting or other automation steps. For the occasional one-off hash needs, though, they get the job done.

macOS

bash shasum --algorithm 256 ~/Downloads/some-file.zip

Windows (cmd.exe)

bash CertUtil -hashfile ~/Downloads/some-file.zip SHA256

Windows (PowerShell)

Confirmed in v6.1.3 [Core], but it probably works in several earlier versions.

powershell Get-FileHash -Path ~/Downloads/some-file.zip -Algorithm SHA256

Linux

I’ve only confirmed this on a few flavors of Ubuntu and Debian/Raspbian.

bash sha256sum ~/Downloads/some-file.zip

Background

If you want to learn a little more about the use of hashing files, feel free to read on for some context. Otherwise, I hope these commands find us all when you need them.

Why would I need a file hash?

As I mentioned, I usually do this to confirm a file I downloaded matches what the site said it should be when I clicked the download link. In an ideal world, this means I have downloaded the expected file exactly, and I didn’t end up downloading some compromised file or malware instead.

For example, if some software is made available from a download site to reduce their own bandwidth costs, they might build new releases to a ZIP file and upload them there for users to download. If someone were to compromise that download site and upload a malicious version of the software, unsuspecting users might click a download link and get the compromised download. If, instead, the software developers determined a cryptographic hash of the file and posted it to their own site, I could verify the same cryptographic hash of the file I downloaded from the external download site. If the hashes match, I can be reasonably sure the hash the developer generated was from the same file I downloaded.

In the real world, if someone has compromised a project, they might have compromised the project’s website as well. In that case, they could create a malicious download, determine the hash of the compromised file, and post that to the project site so that it matches the compromised file on the download site.

There is also potential for a hash to match but with different files, referred to as a hash collision. If someone could create a compromised download that had the same hash, all bets are off. The better the hashing algorithm, the less likely this can happen, but it’s something that could theoretically happen. This potential risk is why I am using SHA-256 instead of something like MD5 hashes in the above commands, because collisions are less likely in the more advanced hashing algorithm.

When should I worry?

I don’t have a good answer here. Open source projects have been compromised in ways that would have never shown up in a file hash. If a project’s source code or release pipeline is compromised, you are likely getting the hash they tell you to expect, but the files within that download are not trustworthy. There’s not a lot you could do at this point, and you may not even know there is an issue.

Most of the time, I only concern myself with this when I trust a project but I don’t trust the provider where the project hosts their downloads. For instance, I would trust a download from a project on GitHub more than a project that linked out to SourceForge or similar

I might also find a project where it’s hard to tell whether I’m downloading the latest release. If they provide hashes of the various versions, I can verify I have the one I wanted.

Similarly, when I’m working with legacy projects where downloads are now scattered across various download services, I may read from someone who trusts a particular download and they list the hash they found. I would possibly have more faith in a download I found with the same hash as well.

A healthy dose of paranoia is good, but it only goes so far in this realm. Stay safe out there!

Workaround: Xamarin.Android long paths on Windows

Quick answer (TL;DR)

Create a symbolic link from your deeply-nested folder to a shorter path using one of the following commands in an Administrator prompt.

Command Prompt

mklink /D {desired-path-location} {actual-path-location}

PowerShell [Core]

New-Item -ItemType SymbolicLink -Path {desired-path-location} -Value {actual-path-location}

After you create the symbolic link, drag the desired solution into Visual Studio rather than navigating through the link in the Open dialog, which will override to the original path.

Background

If you like to keep all your code in a user directory on Windows, there’s a very good chance you’ve cloned a repo or started a new Xamarin.Android project that ran into issues on the first build. Most likely you have run into a path length issue. Sometimes a project is just so nested, even putting the repo in a low-level folder will still have trouble.

If you read the error messages, sometimes they explicitly say there is a path length issue. Sometimes, though, it will be something unusual like this JavaTypeInfo error. I don’t know enough of the Android build process to explain the issue here, but it’s definitely looking for a file at a path location that is 269 characters long.

Failed to create JavaTypeInfo for class: Android.Support.V4.View.Accessibility.AccessibilityManagerCompat/IAccessibilityStateChangeListenerImplementor due to System.IO.DirectoryNotFoundException: Could not find a part of the path ‘C:\Users\patridge\source\repos\mslearn-create-a-mobile-app-with-xamarin-forms\src\exercise1\final\Phoneword\Phoneword.Android\obj\Debug\81\android\src\mono\android\support\v4\view\accessibility\AccessibilityManagerCompat_AccessibilityStateChangeListenerImplementor.java’. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize) at Xamarin.Android.Tools.Files.CopyIfStreamChanged(Stream stream, String destination) at Xamarin.Android.Tasks.Generator.CreateJavaSources(TaskLoggingHelper log, IEnumerable`1 javaTypes, String outputPath, String applicationJavaClass, Boolean useSharedRuntime, Boolean generateOnCreateOverrides, Boolean hasExportReference)

You can definitely run into this issues in a number of situations. Even the Xamarin modules we recently launched on Microsoft Learn have a path like this: {descriptive-module-name}/src/exercise#/{start|final}/{SolutionName}. That’s enough to to get too long for Windows without being in a deeply-nested folder to start.

On Windows, when you start nesting files really deep, you run into a maximum length of 260 characters (drive letter, like “C:\”, plus 256-characters of path from there). While there are ways of circumventing the path length restriction in newer versions of Windows, I haven’t been willing to try them yet. (I doubt I still use any 32-bit applications, but if I did, they wouldn’t be compatible with the long paths.)

Fake a shorter path

I used to copy entire repos to a shallower folder location like C:\dev, or **C:\d** when I got desperate. But sometimes I would forget which location I was working in and leave uncommitted Git changes in the wrong location. Ideally, I would keep all my code in a single location but not have those issues. If you also run into Android build issues that are caused by path lengths, we can trick Windows and Visual Studio into thinking our path is shorter without moving the files from our desired location.

The magic here comes from symbolic links or junctions in the Windows file system. These two tools are a bit like a shortcut, but it steps in the way of the path resolution as you use files and folders it points to. Regardless of the approach, this is how we can make a file at C:\Users\awesomeuser\source\repos\AndroidProjectOfAwesomeness (for Visual Studio 2019; C:\users\awesomeuser\Documents\Visual Studio 2017\Project\AndroidProjectOfAwesomeness) appear like it’s being used from C:\dev\Awesomeness.

The difference a symbolic link and a junction in Windows is subtle, and really only seems to become an issue when dealing with remote connections. Just know that if you are linking from a local path and to a local path, you can probably use either one without seeing any differences.

Create a symbolic link in Windows

Enter the mklink Windows console command. It’s been around for a while, and there was a similar junction command in Windows versions before Windows 8, but it doesn’t get much attention. Open a command or PowerShell prompt from the Start Menu. (Creating a symbolic link requires running this prompt as an administrator unless you have Developer Mode enabled.) Run a command like the following to link from {desired-path-location} (the shortened path) to a location where the code currently exists in {actual-path-location} (the longer path where the Android project isn’t building).

For the Windows Command Prompt, the command looks like this:

mklink /D {desired-path-location} {actual-path-location}

For PowerShell, the command looks like this:

New-Item -ItemType SymbolicLink -Path {desired-path-location} -Value {actual-path-location}

So, if I cloned the intro Xamarin.Forms module exercises from Microsoft Learn to the default location, but I wanted to make sure my path wasn’t too crazy, I could run a command similar to this, where “someuser” is your Windows username.

mklink /D C:\dev\learn-forms C:\Users\someuser\Documents\source\repos\mslearn-create-a-mobile-app-with-xamarin-forms\src\

Or, if you are using PowerShell, the right parameters to New-Item will create a symbolic link as well.

New-Item -ItemType SymbolicLink -Path C:\dev\learn-forms -Value C:\Users\someuser\Documents\source\repos\mslearn-create-a-mobile-app-with-xamarin-forms\src\

From there, I would have access to all the exercise folders, such as the final exercise at C:\dev\learn-forms\exercise1\final\Phoneword.

Using the symbolic link in Visual Studio

For some reason, Visual Studio won’t just play along with the illusion of symbolic links when you navigate through one in the normal open dialog. It will navigate to the original path location, defeating the whole point of all this.

However, if you find the solution file you want in Explorer first and drag it into Visual Studio, it will play along just fine. At this point, you should be happily building your Android projects without issue!

When you’re done with a symbolic link

If a symbolic link ever outlives its usefulness, just delete it like it’s any other shortcut. The original directory will stay where it is. The flip side is also true, tough. If you delete the source directory, the link won’t know any better.

Bonus tip

This can also be a good way to move location-required files from a drive that is running low on space to an external location. Some notable examples include migrating your iTunes music to a different drive, or moving your installed Steam games to another drive. You create a symbolic link from where iTunes or Steam is looking for those file to where you are planning to store them. The app doesn’t know any different, but your C drive can be much less bloated. If you are running Windows from a must-faster-but-smaller SSD, this can be a life saver.