How to copy multiple files to macOS’s clipboard programmatically

applescriptbashcopy/pasteterminal

I ultimately want to have a bash function to-clipboard which gets file paths and copies the files to the clipboard. Using other scripting languages as helpers is okay. I currently have this for copying a single file:

file-to-clipboard() {
    osascript \
        -e 'on run args' \
        -e 'set the clipboard to POSIX file (first item of args)' \
        -e end \
        "$@"
}

There is this Applescript that supposedly can copy multiple files, but I don't like it at all:

set f to {(POSIX file "/path/to/a/folder/a.png"), (POSIX file "/path/to/another/folder/b.png")}
tell application "Finder"
    try -- to delete any old temp folder
        delete folder "AS_mailCopy" of (path to temporary items)
    end try
    set tmp to make new folder at (path to temporary items) with properties {name:"AS_mailCopy"}
    duplicate f to tmp
    select files of tmp
    activate
    tell application "System Events" to keystroke "c" using command down
    delete tmp
end tell

Related question:

Copying files to the clipboard using applescript

Best Answer

You can use the AppleScript below to create a bash function that will let you add multiple file objects to the clipboard by supplying their file paths as command-line arguments. It returns true upon success and false upon failure.

You won't be able to paste the items inside the terminal, but if you navigate to a location in Finder, you can paste the items there. I hope this is along the lines of what you were after.

use framework "Appkit"
use Finder : application "Finder"

property this : a reference to current application
property NSFileManager : a reference to NSFileManager of this
property NSImage : a reference to NSImage of this
property NSMutableArray : a reference to NSMutableArray of this
property NSPasteboard : a reference to NSPasteboard of this
property NSString : a reference to NSString of this
property NSURL : a reference to NSURL of this

property pb : missing value

on run input
    if input's class = script then set input to ¬
        Finder's selection as alias list

    init()
    clearClipboard()
    addToClipboard(input)
end run


to init()
    set pb to NSPasteboard's generalPasteboard()
end init

to clearClipboard()
    if pb = missing value then init()
    pb's clearContents()
end clearClipboard

to addToClipboard(fs)
    local fs

    set fURLs to NSMutableArray's array()
    set FileManager to NSFileManager's defaultManager()

    repeat with f in fs
        if f's class = alias then set f to f's POSIX path
        set fp to (NSString's stringWithString:f)'s ¬
            stringByStandardizingPath()
        if (FileManager's fileExistsAtPath:fp) then ¬
            (fURLs's addObject:(NSURL's fileURLWithPath:fp))
    end repeat

    if pb = missing value then init()
    pb's writeObjects:fURLs
end addToClipboard

I'd advise saving this script as an .applescript or .scpt file somewhere on your machine using Script Editor. Then, in your terminal, create your bash function:

pbadd() {
    osascript "/Path/To/Saved AppleScript.scpt" "$@"
}

Then, to use:

pbadd ~/Pictures/*.jpg
pbadd ~/Documents/Some\ file.pdf ~/Music/A\ Random\ Song.mp3