Người ta phải rất cẩn thận khi đi qua các chuỗi qua các môi trường khác nhau.
Tôi chạy 10,4, vì vậy tập lệnh 'tfork' của tôi luôn mở một cửa sổ mới thay thế. Nên dễ dàng điều chỉnh nó để sử dụng tab:
#!/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
Thí dụ: tfork git log -p ..FETCH_HEAD
Sửa đổi: cwd của một quy trình đang chạy, chiếm lĩnh một tab Terminal
Ý tưởng về thư mục hiện tại của chương trình chiếm giữ tab hiện tại, không rõ ràng như người ta mong đợi.
Mỗi tab Terminal có một thiết bị tty duy nhất được sử dụng bởi các quy trình mà nó chạy (ban đầu, một vỏ; sau đó, bất cứ thứ gì vỏ bắt đầu).
Mỗi Terminal tty (bình thường) có một nhóm quy trình tiền cảnh duy nhất mà người ta có thể coi là một người chiếm lĩnh Tty.
Mỗi nhóm quy trình có thể có nhiều quy trình trong đó.
Mỗi tiến trình có thể có thư mục làm việc hiện tại của riêng nó (cwd) (một số môi trường cung cấp cho mỗi luồng tương đương cwd hoặc cwd của riêng chúng, nhưng chúng ta sẽ bỏ qua điều đó).
Các sự kiện trước đó thiết lập một loại dấu vết từ tty đến cwd: tty -> nhóm quy trình tiền cảnh -> các quy trình của nhóm quy trình tiền cảnh -> cwds.
Phần đầu tiên (từ các quá trình tty đến tiền cảnh) của vấn đề có thể được giải quyết với đầu ra từ ps :
ps -o tty,pid,tpgid,pgid,state,command | awk 'BEGIN{t=ARGV[1];ARGC=1} $1==t && $3==$4 {print $2}' ttyp6
(trong đó, ttyp6, là tên của tty quan tâm)
Việc ánh xạ từ tiến trình (PID) sang cwd có thể được thực hiện với lsof :
lsof -F 0n -a -p 2515,2516 -d cwd
(trong đó, 2515,2516, là một danh sách các quy trình quan tâm được phân tách bằng dấu phẩy
Nhưng dưới Tiger, tôi thấy không có cách nào trực tiếp để có được tên thiết bị tty của một cửa sổ Terminal cụ thể . Có một cách xấu xí khủng khiếp để có được cái tên tty trong Tiger. Có lẽ Leopard hoặc Snow Leopard có thể làm tốt hơn.
Tôi kết hợp tất cả lại với nhau trong một AppleScript như thế này:
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
Lưu nó với Script Editor ( AppleScript Editor trong Snow Leopard) và sử dụng launcher (ví dụ FastScripts ) để gán nó cho một khóa (hoặc chỉ chạy nó từ menu AppleScript (được bật thông qua / Ứng dụng / AppleScript / AppleScript Utility.app )).