回答:
OS X 10.7(Lion)では、Terminal.appはこれをネイティブにサポートします: New Windows/Tabs open in: Same working directory
異なる環境を介して文字列を渡すときは注意が必要です。
10.4を実行しているため、「tfork」スクリプトは常に新しいウィンドウを開きます。タブを使用するように簡単に調整できる必要があります。
#!/bin/sh
# source: http://www.pycs.net/bob/weblog/2004/02/23.html#P49
# Rewritten to use osascript args -> run handler args.
# Added ability to pass additional initial command and args to new shell.
# Bug: Non ASCII characters are unreliable on Tiger.
# Tiger's osascript seems to expect args to be encoded in
# the system's primary encoding (e.g. MacRoman).
# Once in AppleScript, they are handled OK. Terminal sends them
# back to the shell as UTF-8.
test $# -eq 0 && set -- : # default command if none given
osascript - "$(pwd)" "$@" <<\EOF
on run args
set dir to quoted form of (first item of args)
set cmd_strs to {}
repeat with cmd_str in rest of args
set end of cmd_strs to quoted form of cmd_str
end
set text item delimiters to " "
set cmd to cmd_strs as Unicode text
tell app "Terminal" to do script "cd " & dir & " && " & cmd
end
EOF
例: tfork git log -p ..FETCH_HEAD
修正:既に実行中のプロセスのcwdが「ターミナル」タブを「占有」
「現在のタブを占めるプログラムの現在のディレクトリ」という考えは、予想されるほど明白ではありません。
各[ ターミナル ]タブには、実行するプロセス(最初はシェル、その後はシェルが起動するもの)で使用される単一のttyデバイスがあります。
各(通常の)端末 ttyには、ttyを「占有」していると見なすことができる単一のフォアグラウンドプロセスグループがあります。
各プロセスグループには、複数のプロセスを含めることができます。
各プロセスは、独自の現在の作業ディレクトリ(cwd)を持つことができます(環境によっては、各スレッドに独自のcwdまたはcwdと同等のものを与えますが、それは無視します)。
上記の事実は、ttyからcwdへの一種の証跡を確立します。tty->フォアグラウンドプロセスグループ->フォアグラウンドプロセスグループのプロセス-> cwds。
問題の最初の部分(ttyからフォアグラウンドプロセスまで)は、psからの出力で解決できます。
ps -o tty,pid,tpgid,pgid,state,command | awk 'BEGIN{t=ARGV[1];ARGC=1} $1==t && $3==$4 {print $2}' ttyp6
(「ttyp6」は対象のttyの名前です)
プロセス(PID)からcwdへのマッピングはlsofを使用して作成できます。
lsof -F 0n -a -p 2515,2516 -d cwd
(「2515,2516」は、対象プロセスのコンマ区切りリストです)
しかし、Tigerでは、特定のターミナルウィンドウのttyデバイス名を直接取得する方法はありません。Tigerでtty名を取得する恐ろしくい方法があります。たぶん、LeopardまたはSnow Leopardの方がうまくいくかもしれません。
次のようなAppleScriptにすべてをまとめます。
on run
(* Find the tty. *)
-- This is ugly. But is seems to work on Tiger. Maybe newer releases can do better.
tell application "Terminal"
set w to window 1
tell w
set origName to name
set title displays device name to not title displays device name
set newName to name
set title displays device name to not title displays device name
end tell
end tell
set tty to extractTTY(origName, newName)
if tty is "" then
display dialog "Could not find the tty for of the current Terminal window." buttons "Cancel" cancel button "Cancel" default button "Cancel"
end if
(* Find the PIDs of the processes in the foreground process group on that tty. *)
set pids to paragraphs of (do shell script "
ps -o pid,tty,tpgid,pgid,state,command |
awk '
BEGIN {t=ARGV[1];ARGC=1}
$2==t && $3==$4 {print $1}
' " & quoted form of tty)
if pids is {} or pids is {""} then
display dialog "Could not find the processes for " & tty & "." buttons "Cancel" cancel button "Cancel" default button "Cancel"
end if
(* Find the unique cwds of those processes. *)
set text item delimiters to {","}
set lsof to do shell script "lsof -F 0n -a -d cwd -p " & quoted form of (pids as Unicode text) without altering line endings
set text item delimiters to {(ASCII character 0) & (ASCII character 10)}
set cwds to {}
repeat with lsofItem in text items of lsof
if lsofItem starts with "n" then
set cwd to text 2 through end of lsofItem
if cwds does not contain cwd then ¬
set end of cwds to cwd
end if
end repeat
if cwds is {} then
display dialog "No cwds found!?" buttons "Cancel" cancel button "Cancel" default button "Cancel"
end if
if length of cwds is greater than 1 then
set cwds to choose from list cwds with title "Multiple Distinct CWDs" with prompt "Choose the directory to use:" without multiple selections allowed and empty selection allowed
if cwds is false then error number -128 -- cancel
end if
(* Open a new Terminal. *)
tell application "Terminal" to do script "cd " & quoted form of item 1 of cwds
end run
to extractTTY(a, b)
set str to textLeftAfterRemovingMatchingHeadAndTail(a, b)
set offs to offset of "tty" in str
if offs > 0 then
return text offs through (offs + 4) of str
end if
return ""
end extractTTY
to textLeftAfterRemovingMatchingHeadAndTail(big, little)
set text item delimiters to space
if class of big is not list then set big to text items of big
if class of little is not list then set little to text items of little
set {maxLen, minLen} to {length of big, length of little}
if maxLen < minLen then ¬
set {big, little, maxLen, minLen} to {little, big, minLen, maxLen}
set start to missing value
repeat with i from 1 to minLen
if item i of big is not equal to item i of little then
set start to i
exit repeat
end if
end repeat
if start is missing value then
if maxLen is equal to minLen then
return ""
else
return items (minLen + 1) through end of big as Unicode text
end if
end if
set finish to missing value
repeat with i from -1 to -minLen by -1
if item i of big is not equal to item i of little then
set finish to i
exit repeat
end if
end repeat
if finish is missing value then set finish to -(minLen + 1)
return items start through finish of big as Unicode text
end textLeftAfterRemovingMatchingHeadAndTail
スクリプトエディター(Snow LeopardのAppleScript Editor)で保存し、ランチャー(FastScriptsなど)を使用してキーに割り当てます(またはAppleScriptメニュー(/ Applications / AppleScript / AppleScript Utility.appで有効化)から実行します)。
私がしましたスクリプト掲示使用していますクリス・ヨンセン、私は自分の端末を色座標主な理由は、現在の設定でカレントディレクトリに新しいタブを開くには、別のスクリプト上のコードを。クリスに感謝します。そのスクリプトについては、私はこれを数か月間使用していますが、時間の節約になります。
(*このスクリプトは、同じ設定で現在のタブのディレクトリに新しいTerminal.app]タブを開き、あなたがする必要があります、あなたはまだ持っていない場合は、ここで説明したように、補助装置にアクセスできるようにします。のhttp:// WWW .macosxautomation.com / applescript / uiscripting / index.html
それは、2つのスクリプトのほとんどすべての作業です。ありがとうございます。
Chris Johnsenのスクリプトは、現在のディレクトリに新しいタブを開きます:OS X Terminal.app:現在のタブと同じディレクトリで新しいタブを開始する方法は?
Jacob Rusの「menu_click」により、TerminalのAPIではできませんが、同じ設定でタブを作成できます:http ://hints.macworld.com/article.php?story=20060921045743404
ターミナルプロファイルの名前を変更すると、アプリケーションを再起動するまでAppleScript APIは古い名前を返すので、それまでスクリプトは名前を変更した設定では機能しません。あー また、ターミナルをアクティブにしてメニューコマンドを実行する必要があるため、すべてのターミナルウィンドウが前面に表示されます。
*)
-- from http://hints.macworld.com/article.php?story=20060921045743404
-- `menu_click`, by Jacob Rus, September 2006
--
-- Accepts a list of form: `{"Finder", "View", "Arrange By", "Date"}`
-- Execute the specified menu item. In this case, assuming the Finder
-- is the active application, arranging the frontmost folder by date.
on menu_click(mList)
local appName, topMenu, r
-- Validate our input
if mList's length < 3 then error "Menu list is not long enough"
-- Set these variables for clarity and brevity later on
set {appName, topMenu} to (items 1 through 2 of mList)
set r to (items 3 through (mList's length) of mList)
-- This overly-long line calls the menu_recurse function with
-- two arguments: r, and a reference to the top-level menu
tell application "System Events" to my menu_click_recurse(r, ((process appName)'s ¬
(menu bar 1)'s (menu bar item topMenu)'s (menu topMenu)))
end menu_click
on menu_click_recurse(mList, parentObject)
local f, r
-- `f` = first item, `r` = rest of items
set f to item 1 of mList
if mList's length > 1 then set r to (items 2 through (mList's length) of mList)
-- either actually click the menu item, or recurse again
tell application "System Events"
if mList's length is 1 then
click parentObject's menu item f
else
my menu_click_recurse(r, (parentObject's (menu item f)'s (menu f)))
end if
end tell
end menu_click_recurse
-- with the noted slight modification, from /superuser/61149/os-x-terminal-app-how-to-start-a-new-tab-in-the-same-directory-as-the-current-ta/61264#61264
on run
(* Find the tty. *)
-- This is ugly. But is seems to work on Tiger. Maybe newer releases can do better.
tell application "Terminal"
set w to the front window
tell w
set origName to name
set title displays device name to not title displays device name
set newName to name
set title displays device name to not title displays device name
end tell
end tell
set tty to extractTTY(origName, newName)
if tty is "" then
display dialog "Could not find the tty for of the current Terminal window." buttons "Cancel" cancel button "Cancel" default button "Cancel"
end if
(* Find the PIDs of the processes in the foreground process group on that tty. *)
set pids to paragraphs of (do shell script "
ps -o pid,tty,tpgid,pgid,state,command |
awk '
BEGIN {t=ARGV[1];ARGC=1}
$2==t && $3==$4 {print $1}
' " & quoted form of tty)
if pids is {} or pids is {""} then
display dialog "Could not find the processes for " & tty & "." buttons "Cancel" cancel button "Cancel" default button "Cancel"
end if
(* Find the unique cwds of those processes. *)
set text item delimiters to {","}
set lsof to do shell script "lsof -F 0n -a -d cwd -p " & quoted form of (pids as Unicode text) without altering line endings
set text item delimiters to {(ASCII character 0) & (ASCII character 10)}
set cwds to {}
repeat with lsofItem in text items of lsof
if lsofItem starts with "n" then
set cwd to text 2 through end of lsofItem
if cwds does not contain cwd then ¬
set end of cwds to cwd
end if
end repeat
if cwds is {} then
display dialog "No cwds found!?" buttons "Cancel" cancel button "Cancel" default button "Cancel"
end if
if length of cwds is greater than 1 then
set cwds to choose from list cwds with title "Multiple Distinct CWDs" with prompt "Choose the directory to use:" without multiple selections allowed and empty selection allowed
if cwds is false then error number -128 -- cancel
end if
(* Open a new Terminal. *)
-- Here is where I substituted the menu_click call to use the current settings
tell application "Terminal"
activate
tell window 1
set settings to name of current settings in selected tab
end tell
end tell
menu_click({"Terminal", "Shell", "New Tab", settings})
tell application "Terminal" to do script "cd " & quoted form of item 1 of cwds in selected tab of window 1
end run
to extractTTY(a, b)
set str to textLeftAfterRemovingMatchingHeadAndTail(a, b)
set offs to offset of "tty" in str
if offs > 0 then
return text offs through (offs + 6) of str
end if
return ""
end extractTTY
to textLeftAfterRemovingMatchingHeadAndTail(big, little)
set text item delimiters to space
if class of big is not list then set big to text items of big
if class of little is not list then set little to text items of little
set {maxLen, minLen} to {length of big, length of little}
if maxLen < minLen then ¬
set {big, little, maxLen, minLen} to {little, big, minLen, maxLen}
set start to missing value
repeat with i from 1 to minLen
if item i of big is not equal to item i of little then
set start to i
exit repeat
end if
end repeat
if start is missing value then
if maxLen is equal to minLen then
return ""
else
return items (minLen + 1) through end of big as Unicode text
end if
end if
set finish to missing value
repeat with i from -1 to -minLen by -1
if item i of big is not equal to item i of little then
set finish to i
exit repeat
end if
end repeat
if finish is missing value then set finish to -(minLen + 1)
return items start through finish of big as Unicode text
end textLeftAfterRemovingMatchingHeadAndTail
このエイリアス/シェルスクリプトを使用して実行します。
# modified from http://www.nanoant.com/programming/opening-specified-path-in-terminals-new-tab
alias twd=new_terminal_working_directory
function new_terminal_working_directory() {
osascript <<END
tell application "Terminal"
tell application "System Events" to tell process "Terminal" to keystroke "t" using command down
do script "cd $(pwd)" in first window
end tell
END
}
http://www.entropy.ch/blog/Mac+OS+X/2008/06/27/Terminal-Tricks-“term”-revisited-with-tabs.html
tab -t $PWD