How to programmatically get the Terminal scrollback text

terminal

I ran across this comment which stated that it is possible to access the text in the macOS Terminal scrollback:

Finding text in scrollback is a weakness of most terminal emulators; the only ones I know of that provide it are OS X Terminal and Terminator.

I've done some searching, but I have not had any luck finding anything online saying how this can be done.

The reason I ask is that I'm looking for possible solutions to this Stack Overflow question, and am investigating whether there is a way to get text from the most recently run command in the macOS Terminal.

For this specific use case, I'm hoping to find the line(s) that match a particular pattern, so I can extract the matching text and pass it to the open command.

There were failing tests. See the report at: file:///path/to/parent-project/child-project-1/build/reports/tests/test/index.html

open file:///path/to/parent-project/child-project-1/build/reports/tests/test/index.html

In short, how can I get the text of the Terminal scrollback? Bonus points if it's limited to just the ouptut of the last command, but I can make a workable solution to my problem if I can get the entire Terminal scrollback text.

Best Answer

Assuming there is only one instance of the file:///.../index.html URL in the contents of the entire scrolling buffer of the tab, then the following example AppleScript code can do that:

tell application "Terminal" to ¬
    set tabHistory to ¬
        history of tab of ¬
        front window as text

set fileURL to ¬
    do shell script ¬
        "grep -o 'file:///.*\\.html' <<< " & ¬
        tabHistory's quoted form & "; exit 0"

if fileURL is not "" then ¬
    do shell script ¬
        "open " & fileURL's quoted form

Notes:

The example AppleScript code above acts on the selected tab of the front window in Terminal.

If there is a file:///.../index.html URL in the contents of the entire scrolling buffer it will be opened by the open command.

If there is more than one instance of the file:///.../index.html URL in the contents of the entire scrolling buffer of the tab, then make the following change in the example AppleScript code above to open the last instance of the file:///.../index.html URL:

Change:

set fileURL to ¬
    do shell script ¬
        "grep -o 'file:///.*\\.html' <<< " & ¬
        tabHistory's quoted form & "; exit 0"

To:

set fileURL to ¬
    last paragraph of ¬
    (do shell script ¬
        "grep -o 'file:///.*\\.html' <<< " & ¬
        tabHistory's quoted form & "; exit 0")

If you want to use Safari to open the URL and have it frontmost, then:

Change:

if fileURL is not "" then ¬
    do shell script ¬
        "open " & fileURL's quoted form

To:

if fileURL is not "" then ¬
    tell application "Safari"
        make new document with properties {URL:fileURL}
        activate
    end tell

The example AppleScript code can be saved as a shell script with a #!/usr/bin/osascript shebang, made executable and run from Terminal.


Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.