Opening a specific page on Mac Preview from Terminal

itermterminal

How I can modify the open filename.pdf command so that I can open a desired page number directly without having to scroll down.

Best Answer

Unfortunately the open command does not have an option to pass to Preview to tell it to go to a given page. Additionally, Preview does not have an AppleScript Dictionary to make scripting a solution easier, however it's not impossible. The bash script below takes two arguments, the filename of the document to open and the page number to go to. Note that if the target file to open is not in the working directory in Terminal then the fully qualified pathname must be used.

You'll need to create a file to place this code into and make it executable. It should be in a directory that is in the $PATH, otherwise, to use it, you'll have to provide the fully qualified pathname to the executable or use ./executable if at the working directory of the executable in Terminal.

For this example, using the default Terminal, which opens to one's Home Directory:

touch OpenToPage
open OpenToPage

Now copy and paste the code, from the Code: section below, into the opened document and save it, then close it.

While still in Terminal, make the file executable:

chmod u+x OpenToPage

To use OpenToPage:

./opentopage /path/name/to/filename.pdf 3

Or:

./opentopage '/path/name/to/file name.pdf' 3

./opentopage /path/name/to/file\ name.pdf 3

Code:

#!/bin/bash

if [[ -z $2 ]]; then
    [[ -z $1 ]] && printf "\n Missing Filename..."
    printf "\n Missing Page Number...\n\n"
    printf "   Syntax: OpenToPage Filename Page_Number\n"
    printf "   Example: OpenToPage Filename.pdf 3\n\n"
    exit 1
else
    open -a Preview "$1"
    sleep .5
    osascript -e 'tell application "Preview" to activate' \
              -e 'delay 0.25' \
              -e 'tell application "System Events" to tell process "Preview" to click menu item "Go to Page…" of menu "Go" of menu bar 1' \
              -e 'delay 0.25' \
              -e "tell application \"System Events\" to keystroke \"$2\"" \
              -e 'delay 0.25' \
              -e 'tell application "System Events" to key code 36'
fi
exit 0

Notes: If the target filename and or pathname has spaces, the spaces must be escaped with a \ (backslash) or the target filename and or pathname must be quoted, but not both.

The sleep and delay times can be adjusted if/as necessary. As the script is presently written the timings adds 1.25 seconds total to the whole process and should probably be fine as is. If I had to adjust anything I'd change the value of sleep, to .75 or 1, before modifying the values of delay.

The naming of the bash script file in this answer is arbitrary, name it whatever you like, e.g. otp or o2p for open to page, etc.