I have a large number of Terminal windows, that I keep open so I can have a record of what I did, and what the responses were. The windows all have titles indicating the problem space they're for, but sometimes something gets done in the "wrong" window.

How can a do a single search across all the windows? Is there an app out there that will read the saved Terminal contents, and write them as text? Even better, is there source code for doing that?

I have this AppleScript:

tell application "Terminal"
    set windowName to ""
    set windowContents to ""

    repeat with theID from 1 to (count windows)
        set windowName to the name of window theID
        log windownName
        set windowContents to the contents of every tab of window theID
        log windowContents
    end repeat
end tell

For which I get told:

error "The variable windownName is not defined." number -2753 from "windownName"

Final end product will be writing "The file is: \n", but AppleScript seems intent on keeping me from doing so

  • You didn’t specify the system you’re running on, but if you’re using MacOS (10.13), this is easily achieved with AppleScript run from the command line: osascript -e 'tell app "terminal" to get the history of every tab of every window' > ~/Desktop/ContentOfTabs.txt
    – CJK
    Jan 25 '18 at 10:55
  • I'm using 10,12. I got this response: $ osascript -e 'tell app "terminal" to get the history of every tab of every window' > ~/Desktop/ContentOfTabs.txt 31:38: execution error: Terminal got an error: AppleEvent timed out. (-1712) File exists but nothing was written to it Jan 26 '18 at 16:45
  • The problem is the buffers are too big, and Terminal times out trying to get them all. Please see above for my failed attempt to work around this Jan 30 '18 at 18:37
  • 2
    FYI log windownName errors out because it should be log windowName, note the removal of the extra n. Jan 30 '18 at 21:49
  • 1
    @CJK I have a solution thanks to you. If you'd like to post an answer, I'll happily upvote it and mark it as the solution Jan 31 '18 at 15:44

Terminal tabs have two useful AppleScript properties called history and contents.

contents contains the text content of the tab currently visible in its pane (that is, any lines lying within the boundaries of the visible portion the window).

history contains the entire history of the tab's contents, from the moment it came into existence to the moment the property's value is requested.

The AppleScript command to retrieve the entire contents (history) of all tabs across all windows currently open in Terminal is:

    tell application "Terminal" to get the history of every tab of every window

But, as you discovered, history can contain an awful lot of text data, depending on how many tabs you have open and how actively they've been used.

Your approach to dealing with this issue is a good one: looping through each tab/window individually and handling its contents one-by-one.

Your current AppleScript only retrieves the contents of each tab, which is going to be a very small subset of the data contained by each tab (which may be sufficient for your needs). If you need to deal with the larger quantities of data contained in each tab's history property, this might be a means of doing so:

    set F to POSIX file "/Users/CK/Desktop/Terminal.txt"

    set _f to open for access F with write permission
    set eof _f to 0 -- Erase old contents

    tell application "Terminal"
        -- Loop through every window
        repeat with W in (a reference to windows)
            set [W] to W

            -- Loop through every tab of each window
            repeat with T in (tabs of W)
                set [T] to T

                set R to (a reference to history of T)
                write R & linefeed to _f
            end repeat
        end repeat

    end tell

    close access _f

This should sequentially append the text history of each tab from each window to the text file specified at the top of the script.

  • 1
    I added these two lines before the inner repeat. But my version refused to run, so I'm going with this. set windowName to the name of W write linefeed & "Text from window " & windowName & linefeed to _f Jan 31 '18 at 19:19
  • Yup, perfect. You can add any text you want that helps delineate between entries.
    – CJK
    Jan 31 '18 at 19:34

You must log in to answer this question.

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