Archive

Archive for the ‘Terminal’ Category

Open a new tab (or window) in Mac OSX Terminal and run command

January 25, 2012 1 comment

[ UPDATE ]
After implementing the ruby code by user tig I was like, did I just make things more complicated than they should be? I was surprised that I didn’t first think about using the following applescript instead.

put the following codes in ~/.bash_profile

comm_tw() {
        [ $# -lt 2 ] && return
        osascript -e "
                tell application \"System Events\" to tell process \"Terminal\" to keystroke \"$1\" using command down
                tell application \"Terminal\" to do script \"$2\" in selected tab of the front window
        " > /dev/null 2>&1
}
newt() {
	comm_tw t "$1"
}
neww() {
	comm_tw n "$1"
}

All I need to do then is to run either newt (to open a new tab or neww (to open a new window) and run command(s) in it. For example:

newt "ls -l ~; uptime"
neww "date; who am i"

It’s worth noting that commands separated by semi-colon are allowed.

[ Initial Edit ]
I was looking for a solution to open a new tab (or window) and run a command (ssh for example) as sometimes I need to ssh to a number of hosts at once. I found the answer here. It’s almost what I needed for the tab part. I decided to change the ruby code (by sueruser.com user tig) a bit so I can use an option [ which is -w ] to run command in a new window. I am gonna post the code below. You can also fork me on github.

#!/usr/bin/env ruby
# A ruby script to open a new tab (or a new window) and run command in it on Mac OS X
# Modified based on the answer from tig regarding question posted at
# http://superuser.com/questions/174576/opening-a-new-terminal-from-the-command-line-and-running-a-command-on-mac-os-x
# Expands its feature a bit by allowing -w option top run command in a new window
# Usage Example:
#   ./dt ls -l
#   ./dt -w top
#
# Tested with Ruby 1.8.7

require 'rubygems'
require 'shellwords'
require 'appscript'

class Terminal
  include Appscript
  attr_reader :terminal, :current_window
  def initialize
    @terminal = app('Terminal')
    @current_window = terminal.windows.first
    yield self
  end

  def tab(dir, command = nil, mode = 't')
    app('System Events').application_processes['Terminal.app'].keystroke(mode, :using => :command_down)
    cd_and_run dir, command
  end

  def cd_and_run(dir, command = nil)
    run "clear; cd #{dir.shellescape}"
    run command
  end

  def run(command)
    command = command.shelljoin if command.is_a?(Array)
    if command && !command.empty?
      terminal.do_script(command, :in => current_window.tabs.last)
    end
  end
end

Terminal.new do |t|
  if ARGV.length>=1 && ARGV.first == '-w'
    t.tab(Dir.pwd, ARGV[1, ARGV.length], 'n')
  else
    t.tab(Dir.pwd, ARGV)
  end
end

As a side note, tmux can also be used for this kind of tasks with better scripting support. The only problem I might run into is hot key conflicts between local and remote hosts as most of the hosts I need to access are using tmux.

Categories: mac osx, ruby, Terminal