在OSX(Snow Leopard)中打开一个新的终端选项卡,并且该选项卡的初始路径为当前终端窗口所在的目录。

19

我在谷歌上搜索了一段时间,试图寻找一个简单的方法来解决这个问题,但是我没有找到。
我已经设置了一个自定义终端环境(zsh),包括各种命名别名和功能以使操作更加容易。 但我运行遇到的问题之一是,我经常使用快捷键(APPLE-t)创建一个新标签页,然后在新标签页中输入相对于刚才使用的终端窗口路径的命令。 这通常会失败,因为新标签页的路径是~/,而不是我刚刚使用的路径! 是否有任何脚本可以将新终端选项卡的目录路径设置为打开终端选项卡的目录路径? 非常感谢您提供任何帮助。 Ian

1
解决方案:切换到支持在新标签页/窗口中保留当前工作目录的 http://konsole.kde.org/。 :) - ephemient
1
我想知道是否有一些针对此问题的AppleScript解决方案。 - Emil Sit
5个回答

56
我有几个常用的脚本: dup(新窗口,工作目录相同):
#!/bin/sh
pwd=`pwd`
osascript -e "tell application \"Terminal\" to do script \"cd $pwd; clear\"" > /dev/null

并且tup(在相同的工作目录中打开新标签页):

#!/bin/sh

pwd=`pwd`
osascript -e "tell application \"Terminal\"" \
    -e "tell application \"System Events\" to keystroke \"t\" using {command down}" \
    -e "do script \"cd $pwd; clear\" in front window" \
    -e "end tell"
    > /dev/null

1
这些都很棒,这个回答真的没有足够的+1。谢谢你Gavin,真是太棒了。 - Thomas Nadin
不错!我现在正在使用iTerm,但我在终端中尝试了这些命令,效果很棒。 - John Keyes
3
太棒了,我稍微修改了一下以接受一个参数。现在我将它用于启动我的Web项目环境:https://gist.github.com/2492064 - Stéphane

6

另外一种无需脚本的解决方案是iTerm2,它内置了此功能。它甚至还具有更多特性,值得一试。


1
iTerm2非常有用。如果没有它,我不知道该怎么办。全屏模式和屏幕分割也是必备功能。我简直无法想象人们愿意跳过的AppleScript障碍,当iTerm2使此(以及许多其他基本操作)变得如此简单易行! - isaacs
如何使用iTerm2完成这个任务? - mycargus
2
@mycargus 试试这个:iTerm2 -> 首选项 -> 档案 -> 通用 -> 重复使用上一个会话的主目录 - xer0x

4
您可以修改在http://www.entropy.ch/blog/Mac+OS+X/2008/06/27/Terminal-Tricks-“term”-revisited-with-tabs找到的BASH脚本来获得所需内容。以下是该脚本,摘自Marc Linyage的网站www.entropy.ch/blog
#!/bin/sh
#
# Open a new Mac OS X terminal window or tab in the current or another
# directory and optionally run a command in the new window or tab.
#
# - Without any arguments, the new terminal window opens in
#   the current directory, i.e. the executed command is "cd $PWD".
# - If the first argument is a directory, the new terminal will "cd" into
#   that directory before executing the remaining arguments as command.
# - The optional "-t" flag executes the command in a new tab 
#   instead of a new window.
# - The optional "-x" flag closes the new window or tab
#   after the executed command finishes.
# - The optional "-p" flag takes an argument of the form x,y (e.g. 40,50) and
#   positions the terminal window to the indicated location on the screen
# - The optional "-s" flag takes an argument of the form w,h (e.g. 800,400) and
#   resizes the terminal window to the indicated width and height in pixels.
#
# Written by Marc Liyanage <http://www.entropy.ch>
#
# Version 2.1
#

set -e

while getopts xtp:s: OPTION; do
    [ $OPTION = "x" ] && { EXIT='; exit'; }
    [ $OPTION = "t" ] && { TAB=1; }
    [ $OPTION = "p" ] && { POSITION="set position of window 1 to {$OPTARG}"; }
    [ $OPTION = "s" ] && { SIZE="set size of window 1 to {$OPTARG}"; }
done

for (( $OPTIND; $OPTIND-1; OPTIND=$OPTIND-1 )); do shift; done

if [[ -d "$1" ]]; then WD=$(cd "$1"; pwd); shift; else WD=$PWD; fi


COMMAND="cd '$WD' && echo -n \$'\\\\ec';"
for i in "$@"; do
COMMAND="$COMMAND '$i'"
done

if [ $TAB ]; then

osascript 2>/dev/null <<EOF
tell application "System Events"
    tell process "Terminal" to keystroke "t" using command down
end
tell application "Terminal"
    activate
    do script with command "$COMMAND $EXIT" in window 1
    $POSITION
    $SIZE
end tell
EOF

else

osascript <<EOF
tell application "Terminal"
    activate
    do script with command "$COMMAND $EXIT"
    $POSITION
    $SIZE
end tell
EOF

fi

1
哦,我想知道那个愚蠢的 for (( ... )) 循环是干什么用的;使用 shift $OPTIND 会更好。另外,为了安全起见,COMMAND=... 应该更像 COMMAND="cd $(printf '%q' "$WD") ..."。嗯,不管怎样,它似乎还是相当聪明的。 - ephemient

4

好的,按照我的方式,我再次回答自己的问题(至少接近答案了)。

我发现了比上面那个脚本更简洁的脚本(由 Dan Benjamin 提供),它似乎能解决问题,尽管两个脚本在成功完成之前都会输出类似的错误。我通过在脚本结尾添加clear来处理这个问题,所以这不是什么大问题。

我说我已经快要解决自己的问题,因为我的目标是找到一种方法,使用苹果键+t组合键就可以打开新标签页,而这个组合键已经深深地烙在我的肌肉记忆中,成为在各种网络浏览器中打开新标签页的捷径,感谢无数小时的使用。虽然像 Dan 的脚本一样,我处理这个问题的最佳方案是 t-return,虽然区别不大,但每次发出此命令时都会让我有点心烦意乱。我知道,我应该放手...... 但我不能,这可能是我陷入这个问题的原因,无休止地摆弄电脑。我偏离了主题,以下是我正在使用的脚本:

#!/bin/sh

# Make a new OS X Terminal tab with the current working directory.

if [ $# -ne 1 ]; then
    PATHDIR=`pwd`
else
    PATHDIR=$1
fi

/usr/bin/osascript <<EOF
activate application "Terminal"
tell application "System Events"
    keystroke "t" using {command down}
end tell
tell application "Terminal"
    repeat with win in windows
        try
            if get frontmost of win is true then
                do script "cd $PATHDIR; clear" in (selected tab of win)
            end if
        end try
    end repeat
end tell
EOF
clear

为了完整起见,如果省略尾随的clear,则会在请求窗口上抛出以下错误:

2009-10-20 01:30:38.714 osascript[20862:903] Error loading /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types:  dlopen(/Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types, 262): no suitable image found.  Did find:
    /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types: no matching architecture in universal wrapper
osascript: OpenScripting.framework - scripting addition "/Library/ScriptingAdditions/Adobe Unit Types.osax" declares no loadable handlers.
tab 2 of window id 13942

这在我Snow Leopard(10.6.8)上失败了:第25行:1371 段错误 /usr/bin/osascript - John Keyes
@JohnKeyes和i0n,如果你想要一个适用于Snow Leopard的更简洁的解决方案,你应该看一下[Gavin的](https://dev59.com/XXI-5IYBdhLWcg3w99oH#7911097)答案。 - Thomas Nadin

1
在我的回答这里中,我提供了一个函数和一个别名:
function cd () { command cd "$@"; echo "$PWD" > /tmp/CWD; }
export cd

alias cdp='cd $(cat /tmp/CWD)'

你应该能够在你的~/.bashrc~/.zshrc文件的末尾放置一个(可能是有条件的)语句来执行该别名。


@ephemient: $PROMPT_COMMAND 变量可以设置为 'echo "$PWD" > /tmp/CWD',这样每次发出提示符时都会写入。 @i0n:“breaks” 究竟是什么意思。错误信息?特定行为? - Dennis Williamson
是的,我本可以更加详细的描述一下。cd命令停止工作了,没有任何错误信息。无论是cd ..、cd DIR_NAME还是cd ~,都无法正常运行。这里有我终端相关文件的最新且完整的备份,可以在GitHub上获取:http://github.com/i0n/dotfiles - i0n
你可以尝试添加 export cd - Dennis Williamson
你可以尝试(在任何情况下都适用的Bash中)使用PROMPT_COMMAND='echo "$PWD" > /tmp/CWD' - Dennis Williamson
对于 zsh:PROMPT="$PROMPT$(pwd>/tmp/ZWD)" - Dennis Williamson
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接