Even though OS X’s Terminal now supports multiple tabs, I still find myself using lots of separate windows so I can see everything at once. A common pain point was opening a second Terminal window and changing to the current working directory (I do this a lot from the root of Rails apps: one window for running the server, and one for git and other work). I’ve since written a little Ruby script that essentially duplicates the current Terminal window. Save the following as dup and put it somewhere on your path:

#!/usr/bin/env ruby
#
# Duplicates a terminal window, optionally running the passed command
# % dup (creates new window)
# % dup command arg1 arg 2 (new window, plus runs passed command)

require 'rubygems'
require 'appscript'

include Appscript

def quote(command)
  command.gsub(/(\$`\\!")/){|m|"\\\\#{m}"}
end

path = ENV['PWD']
terminal = app('Terminal')
coords = terminal.windows.first.position.get
dimensions = terminal.windows.first.size.get

command = "cd \"#{quote(path)}\" && clear"
command << " && #{quote(ARGV.join(' '))}" unless ARGV.empty?

terminal.do_script(command)
terminal.windows.first.size.set([dimensions[0], dimensions[1]])
terminal.windows.first.position.set([coords[0] + dimensions[0] + 10, coords[1]])

Appscript is required, but it is only a sudo gem install appscript away. The script will pass and arguments passed to it to the new terminal window. One common use for me is dup script/server.

6 Responses to “Duplicate a Mac OS X Terminal window with Ruby and Appscript”

  1. When I executed it, the following error message comes

    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:27:in gem_original_require': no such file to load -- appscript (LoadError) from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:27:inrequire’ from /usr/local/bin/dup:8

  2. Malcolm replied on September 20th, 2009 at 04:19 PM:

    Nice idea - I was looking for a way to do this. I also get a similar error as Shin (called the script dupterm):

    WARNING: #<errno::eacces: /> WARNING: Invalid .gemspec format in ‘/Library/Ruby/Gems/1.8/specifications/rb-appscript-0.5.3.gemspec’ /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in gem_original_require': no such file to load -- appscript (LoadError) from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:inrequire’ from /Users/maciver/bin/dupterm:8

  3. Python version. Make sure to “sudo easy_install appscript”

    #!/usr/bin/env python
    #
    # Duplicates a terminal window, optionally running the passed command
    # % dup (creates new window)
    # % dup command arg1 arg2 (new window, plus runs passed command)
    
    from appscript import *
    import os, sys
    from pipes import quote
    
    path = os.environ['PWD']
    terminal = app('Terminal')
    coords = terminal.windows.first.position.get()
    dimensions = terminal.windows.first.size.get()
    
    command = "cd " + quote(path) + " && clear" 
    if len(sys.argv) > 1:
        command += " && " + ' '.join(sys.argv[1:])
    
    terminal.do_script(command)
    terminal.windows.first.size.set([dimensions[0], dimensions[1]])
    terminal.windows.first.position.set([coords[0] + dimensions[0] + 10, coords[1]])
    
  4. Shin/Malcom:

    I’m using a version of Ruby from MacPorts, and Rubygems installed from source. It looks like you are using the system versions, of which I know Rubygems is likely out of date. This page has update instructions.

  5. Good stuff, this is fairly useful, tabs are great in terminal now, have you tried Visor?

    http://the.taoofmac.com/space/apps/Visor

  6. found another solution here… haven’t tried it, but maybe worth a look

Leave a Reply