This question already has an answer here:

I work on the command line quite a bit and often have to take a screenshot a region of the screen and save it to directory I am currently working in.

(let's assume I've already taken the screenshot and clipboard has it).

This is how I have to do it right now (after have the screenshot in clipboard):

  1. launch Preview.
  2. in Preview, ⌘ + N (File, New from Clipboard) creates a new file with the clipboard contents.
  3. go back to command line and copy the directory name (copy the results of pwd)
  4. go to Preview, ⌘ + S for Save. Type / gets me a directory navigation prompt where I can paste my directory name from step 3.
  5. Finally, give the actual file name, this_is_where_I_get_the_error.png in my example.

I'd like to do this instead:

$savemyscreenshot ./this_is_where_I_get_the_error.png

How would I go about writing that savemyscreenshot command? In bash? As an Automator script (which has to be callable from the Terminal, else that defeats the purpose somewhat)?

All things being equal, would slightly prefer a javascript flavor of the Automator script over AppleScript.

env: MacOS Sierra

marked as duplicate by nohillside Dec 31 '17 at 10:04

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


screencapture is a CLI tool built into macOS for taking screenshots, in /usr/sbin/screencapture.

To take a screenshot and save it to screenshot.png:

screencapture -x screenshot.png

To screenshot a region, you can use -R, where x,y are the coordinates of the top-left and w,h is width and height of the capture.

screencapture -x -Rx,y,w,h /path/to/capture.png

To interactively choose a region, use -i

screencapture -i screenshot.png
  • Did you mean: screencapture -x -R x,y,w,h ? – jmh Dec 13 '17 at 21:17
  • sorry, I don't want to "pilot " the screenshot's x,y from the command line. assume clipboard is already populated and I am just dealing with putting it into a file. – JL Peyret Dec 13 '17 at 22:07
  • @JLPeyret You can use -i for interactive, see edit – grg Dec 13 '17 at 22:11
  • Ah, I like it. Not exactly what I wanted to start with, because I was assuming I had the capture done already, but very simple and pretty close - the only limitation is you can pick a window to capture, but not a tab. i.e. you can navigate to your browser and choose a region on its active tab, but you can't pick a tab. Close enough, if no one comes with something as simple that matches already-in-clipboard, your answer gets accepted ;-) I checked man screencapture for a from-clipboard mode, doesn't exist. – JL Peyret Dec 13 '17 at 22:20

Edit: Per comments, this answer didn’t work. Looks like the last time someone asked this someone else wrote a utility for it: What's the quickest way to get a graphic on the clipboard saved to disk? specifically this answer

Original answer follows

There should be a terminal command "pbpaste" which you can redirect to a file. So if you have image data in your clipboard pbpaste > my_img.png should do the trick.

  • didn't work, and I believe people have stated before that pbpaste is text-only - doing pbpaste without redirection showed absolutely nothing in terminal and I did another command-New in Preview to confirm image clipboard data. good suggestion though, if it worked it would be simplest. – JL Peyret Dec 13 '17 at 22:04
  • @JLPeyret So it seems, sorry wasn’t in front of a Mac to check it out. See my edit for a link to a question and answer that might help instead – moneyt Dec 13 '17 at 22:11
  • Your link tells how to put it in a new window with preview. OP wants to put it in a file with bash. – WGroleau Dec 20 '17 at 5:55
  • @WGroleau I was specifically referring to the second answer at the linked question. But fair enough I didn't specify. Answer edited. – moneyt Dec 21 '17 at 15:59
  • (sheepish grin) I scrolled all the way through that and somehow only saw the ones using preview. – WGroleau Dec 21 '17 at 17:33

Before I continue, allow me to apologise: I know you expressed a slight preference for Javascript over AppleScript. However, my Javascript is pants, whilst I already know how to accomplish it using the latter, and it definitely provides one way to obtain image data from the clipboard straight from the command-line.

The following one-liner (spread over four lines just for ease of reading) will take the image from the clipboard and save it to a file with the name set as the current date and time, located in your present working directory:

    osascript -e "tell application \"System Events\" to ¬
        write (the clipboard as JPEG picture) to ¬
        (make new file at folder \"$(pwd)\" with properties ¬
        {name:\"$(date +%Y-%m-%d\ at\ %H.%M.%S).jpg\"})"

If you choose to use this method of mine, I suggest creating an alias/function to wrap it up inside of, which you can then just call by typing the function name +/- a parameter if you wanted to specify the filename manually (with a small tweak to the final part of the above command where the filename is declared).

EDIT: I went ahead and wrote a shell script that does all this for you:

    # Filename: SaveMyScreenshot (executable)
    # Author: CK 2017
    # ----------------------------------------------------
    # Takes a screenshot to the clipboard then saves the
    # clipboard image to a file in jpeg format.
    # Usage: SaveMyScreenshot [[path/]filename]
    # If no filename is specified, the image will be saved
    # to the present working directory and named using the
    # current date and time.  If more than one argument is
    # given, all but the first argument are ignored.
    # e.g.
    # SaveMyScreenshot
    # SaveMyScreenshot ~/Desktop
    # SaveMyScreenshot ~/Desktop/foo.jpg
    # ----------------------------------------------------

    screencapture -c

    filename=$(date +%Y-%m-%d\ at\ %H.%M.%S).jpg

    if [ $# -ne 0 ]; then
        if [[ -d $1 ]]; then
            if [ "$1" != "." ]; then folder=$1; fi
            a=$(dirname "$1")    
            b=$(basename "$1" .jpg)

            if [ "$b" != "" ]; then filename=$b.jpg; fi

            if [ "$a" != "." ]; then folder=$a; fi

    osascript -e "tell application \"System Events\" to ¬
            write (the clipboard as JPEG picture) to ¬
            (make new file at folder \"$folder\" ¬
            with properties {name:\"$filename\"})"

This can be copied and pasted into a plain text file called "SaveMyScreenshot", made executable by running the command chmod +x /path/to/SaveMyScreenshot in Terminal, then moved to one of the directories specified in $PATH (I use /usr/local/bin).

From then on, you can simply type SaveMyScreenshot as you would any other command in Terminal.

P.S. Don't forget to comment out or delete the line in the script that takes the screenshot (screencapture -c). I believe you have your own, preferred method of obtaining your screenshot, and I only put this in for my own testing purposes and for completeness in case anyone else might find this answer useful in a more general context.

  • 1
    The OP showed saving the clipboard image as a PNG file, so the clipboard as JPEG picture should be the clipboard as «class PNGf» and change .jpg to .png. Also, you should run your shell code through ShellCheck and double quote as shown at ShellCheck to prevent globbing and word splitting. – user3439894 Dec 22 '17 at 6:25
  • @user3439894 Thank you very much for the ShellCheck recommendation. I've performed the check and amended as appropriate. Regarding the image file format, the OP didn't specify he needed any one particular file format over another (PNG is simply the default format for screencaptures in MacOS). I specifically elected to use JPG here because it works faster with AppleScript and results in a smaller file size. Of course, it is OP's preference, and I'm happy you've explained how to make the change should he wish to. – CJK Dec 22 '17 at 6:39

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