コマンドラインから新しいターミナルタブを開く(Mac OS X)


116

現在開いているタブのコマンドラインからMac OS Xのターミナルで新しいタブを開くことはできますか?

ターミナルで新しいタブを開くためのキーボードショートカットが「CMD + t」であることは知っていますが、コマンドラインで実行されるスクリプトベースのソリューションを探しています。

回答:


126

これを試して:

osascript -e 'tell application "Terminal" to activate' -e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down'

ドー!私はあなたのコメントを完全に逃しました、グーグル経由で同様の解決策を見つけました。1つの違い:Terminalが最前面のアプリケーションでない限り、(10.6.8では)機能しませんでした。そのため、 "activate"を追加して強制的に前面に配置しました。
Gordon Davisson、2011

5
編集:新しいコマンドex echo helloをこの新しいタブに配置するにはどうすればよいですか。
ThomasReggi 2012

22
@ThomasReggi:-e 'tell application "Terminal" to do script "echo hello" in selected tab of the front window'osascriptコマンドの最後に追加します。
ゴードンデイヴィッソン2012

2
@clevertension for iTerm is itopen -a iTerm ~/Applications/
onmyway133

1
@Ciastopiekarz新しく開いたタブのことですか?ThomasReggiに対する私の回答と同じアプローチを使用します:add -e 'tell application "Terminal" to do script "cd /path/to/target/directory" in selected tab of the front window'。パスが変数からのものである場合は、一重引用符ではなく二重引用符で囲まれた文字列を使用し、引用符で囲まれた内部の文字列とおそらくパス自体をエスケープする必要があることに注意してください。
Gordon Davisson、

163

更新:この回答は、以下に掲載されているシェル機能に基づいて人気を得ました。これは、OSX 10.10以降でも機能します(-gオプションを除く)。
ただし、より完全に機能し、より堅牢でテスト済みのスクリプトバージョンnpmレジストリでCLIとして利用可能になりましたttabiTerm2もサポートしています

  • あなたが持っている場合 Node.jsがインストールされコマンドを実行します。

    npm install -g ttab
    

    (Node.jsのインストール方法によっては、先頭にを付ける必要がある場合がありますsudo)。

  • それ以外の場合は、 の手順てください

  • インストールしたら、実行ttab -hして簡潔な使用情報を確認するか、man ttabを確認する、マニュアルを表示してください。


受け入れられた答えに基づいて、以下はbashです 現在のターミナルウィンドウで新しいタブを開き、オプションでコマンドを実行するための便利な関数です(おまけとして、新しいウィンドウを作成するためのバリアント関数があります)代わりに)。

コマンドが指定されている場合、その最初のトークンが新しいタブのタイトルとして使用されます。

サンプル呼び出し:

    # Get command-line help.
newtab -h
    # Simpy open new tab.
newtab
    # Open new tab and execute command (quoted parameters are supported).
newtab ls -l "$Home/Library/Application Support"
    # Open a new tab with a given working directory and execute a command;
    # Double-quote the command passed to `eval` and use backslash-escaping inside.
newtab eval "cd ~/Library/Application\ Support; ls"
    # Open new tab, execute commands, close tab.
newtab eval "ls \$HOME/Library/Application\ Support; echo Press a key to exit.; read -s -n 1; exit"
    # Open new tab and execute script.
newtab /path/to/someScript
    # Open new tab, execute script, close tab.
newtab exec /path/to/someScript
    # Open new tab and execute script, but don't activate the new tab.
newtab -G /path/to/someScript

注意点は:あなたが実行するとnewtab(またはnewwin)スクリプトから、スクリプトの最初の作業フォルダは、新しいタブ/ウィンドウで作業フォルダになりますあなたが前にスクリプト内部の作業フォルダを変更しても起動newtab/ newwin-パスevalAでcd回避策としてコマンド(上記の例を参照)。

ソースコード(たとえば、bashプロファイルに貼り付けます):

# Opens a new tab in the current Terminal window and optionally executes a command.
# When invoked via a function named 'newwin', opens a new Terminal *window* instead.
function newtab {

    # If this function was invoked directly by a function named 'newwin', we open a new *window* instead
    # of a new tab in the existing window.
    local funcName=$FUNCNAME
    local targetType='tab'
    local targetDesc='new tab in the active Terminal window'
    local makeTab=1
    case "${FUNCNAME[1]}" in
        newwin)
            makeTab=0
            funcName=${FUNCNAME[1]}
            targetType='window'
            targetDesc='new Terminal window'
            ;;
    esac

    # Command-line help.
    if [[ "$1" == '--help' || "$1" == '-h' ]]; then
        cat <<EOF
Synopsis:
    $funcName [-g|-G] [command [param1 ...]]

Description:
    Opens a $targetDesc and optionally executes a command.

    The new $targetType will run a login shell (i.e., load the user's shell profile) and inherit
    the working folder from this shell (the active Terminal tab).
    IMPORTANT: In scripts, \`$funcName\` *statically* inherits the working folder from the
    *invoking Terminal tab* at the time of script *invocation*, even if you change the
    working folder *inside* the script before invoking \`$funcName\`.

    -g (back*g*round) causes Terminal not to activate, but within Terminal, the new tab/window
      will become the active element.
    -G causes Terminal not to activate *and* the active element within Terminal not to change;
      i.e., the previously active window and tab stay active.

    NOTE: With -g or -G specified, for technical reasons, Terminal will still activate *briefly* when
    you create a new tab (creating a new window is not affected).

    When a command is specified, its first token will become the new ${targetType}'s title.
    Quoted parameters are handled properly.

    To specify multiple commands, use 'eval' followed by a single, *double*-quoted string
    in which the commands are separated by ';' Do NOT use backslash-escaped double quotes inside
    this string; rather, use backslash-escaping as needed.
    Use 'exit' as the last command to automatically close the tab when the command
    terminates; precede it with 'read -s -n 1' to wait for a keystroke first.

    Alternatively, pass a script name or path; prefix with 'exec' to automatically
    close the $targetType when the script terminates.

Examples:
    $funcName ls -l "\$Home/Library/Application Support"
    $funcName eval "ls \\\$HOME/Library/Application\ Support; echo Press a key to exit.; read -s -n 1; exit"
    $funcName /path/to/someScript
    $funcName exec /path/to/someScript
EOF
        return 0
    fi

    # Option-parameters loop.
    inBackground=0
    while (( $# )); do
        case "$1" in
            -g)
                inBackground=1
                ;;
            -G)
                inBackground=2
                ;;
            --) # Explicit end-of-options marker.
                shift   # Move to next param and proceed with data-parameter analysis below.
                break
                ;;
            -*) # An unrecognized switch.
                echo "$FUNCNAME: PARAMETER ERROR: Unrecognized option: '$1'. To force interpretation as non-option, precede with '--'. Use -h or --h for help." 1>&2 && return 2
                ;;
            *)  # 1st argument reached; proceed with argument-parameter analysis below.
                break
                ;;
        esac
        shift
    done

    # All remaining parameters, if any, make up the command to execute in the new tab/window.

    local CMD_PREFIX='tell application "Terminal" to do script'

        # Command for opening a new Terminal window (with a single, new tab).
    local CMD_NEWWIN=$CMD_PREFIX    # Curiously, simply executing 'do script' with no further arguments opens a new *window*.
        # Commands for opening a new tab in the current Terminal window.
        # Sadly, there is no direct way to open a new tab in an existing window, so we must activate Terminal first, then send a keyboard shortcut.
    local CMD_ACTIVATE='tell application "Terminal" to activate'
    local CMD_NEWTAB='tell application "System Events" to keystroke "t" using {command down}'
        # For use with -g: commands for saving and restoring the previous application
    local CMD_SAVE_ACTIVE_APPNAME='tell application "System Events" to set prevAppName to displayed name of first process whose frontmost is true'
    local CMD_REACTIVATE_PREV_APP='activate application prevAppName'
        # For use with -G: commands for saving and restoring the previous state within Terminal
    local CMD_SAVE_ACTIVE_WIN='tell application "Terminal" to set prevWin to front window'
    local CMD_REACTIVATE_PREV_WIN='set frontmost of prevWin to true'
    local CMD_SAVE_ACTIVE_TAB='tell application "Terminal" to set prevTab to (selected tab of front window)'
    local CMD_REACTIVATE_PREV_TAB='tell application "Terminal" to set selected of prevTab to true'

    if (( $# )); then # Command specified; open a new tab or window, then execute command.
            # Use the command's first token as the tab title.
        local tabTitle=$1
        case "$tabTitle" in
            exec|eval) # Use following token instead, if the 1st one is 'eval' or 'exec'.
                tabTitle=$(echo "$2" | awk '{ print $1 }') 
                ;;
            cd) # Use last path component of following token instead, if the 1st one is 'cd'
                tabTitle=$(basename "$2")
                ;;
        esac
        local CMD_SETTITLE="tell application \"Terminal\" to set custom title of front window to \"$tabTitle\""
            # The tricky part is to quote the command tokens properly when passing them to AppleScript:
            # Step 1: Quote all parameters (as needed) using printf '%q' - this will perform backslash-escaping.
        local quotedArgs=$(printf '%q ' "$@")
            # Step 2: Escape all backslashes again (by doubling them), because AppleScript expects that.
        local cmd="$CMD_PREFIX \"${quotedArgs//\\/\\\\}\""
            # Open new tab or window, execute command, and assign tab title.
            # '>/dev/null' suppresses AppleScript's output when it creates a new tab.
        if (( makeTab )); then
            if (( inBackground )); then
                # !! Sadly, because we must create a new tab by sending a keystroke to Terminal, we must briefly activate it, then reactivate the previously active application.
                if (( inBackground == 2 )); then # Restore the previously active tab after creating the new one.
                    osascript -e "$CMD_SAVE_ACTIVE_APPNAME" -e "$CMD_SAVE_ACTIVE_TAB" -e "$CMD_ACTIVATE" -e "$CMD_NEWTAB" -e "$cmd in front window" -e "$CMD_SETTITLE" -e "$CMD_REACTIVATE_PREV_APP" -e "$CMD_REACTIVATE_PREV_TAB" >/dev/null
                else
                    osascript -e "$CMD_SAVE_ACTIVE_APPNAME" -e "$CMD_ACTIVATE" -e "$CMD_NEWTAB" -e "$cmd in front window" -e "$CMD_SETTITLE" -e "$CMD_REACTIVATE_PREV_APP" >/dev/null
                fi
            else
                osascript -e "$CMD_ACTIVATE" -e "$CMD_NEWTAB" -e "$cmd in front window" -e "$CMD_SETTITLE" >/dev/null
            fi
        else # make *window*
            # Note: $CMD_NEWWIN is not needed, as $cmd implicitly creates a new window.
            if (( inBackground )); then
                # !! Sadly, because we must create a new tab by sending a keystroke to Terminal, we must briefly activate it, then reactivate the previously active application.
                if (( inBackground == 2 )); then # Restore the previously active window after creating the new one.
                    osascript -e "$CMD_SAVE_ACTIVE_WIN" -e "$cmd" -e "$CMD_SETTITLE" -e "$CMD_REACTIVATE_PREV_WIN" >/dev/null
                else
                    osascript -e "$cmd" -e "$CMD_SETTITLE" >/dev/null
                fi
            else
                    # Note: Even though we do not strictly need to activate Terminal first, we do it, as assigning the custom title to the 'front window' would otherwise sometimes target the wrong window.
                osascript -e "$CMD_ACTIVATE" -e "$cmd" -e "$CMD_SETTITLE" >/dev/null
            fi
        fi        
    else    # No command specified; simply open a new tab or window.
        if (( makeTab )); then
            if (( inBackground )); then
                # !! Sadly, because we must create a new tab by sending a keystroke to Terminal, we must briefly activate it, then reactivate the previously active application.
                if (( inBackground == 2 )); then # Restore the previously active tab after creating the new one.
                    osascript -e "$CMD_SAVE_ACTIVE_APPNAME" -e "$CMD_SAVE_ACTIVE_TAB" -e "$CMD_ACTIVATE" -e "$CMD_NEWTAB" -e "$CMD_REACTIVATE_PREV_APP" -e "$CMD_REACTIVATE_PREV_TAB" >/dev/null
                else
                    osascript -e "$CMD_SAVE_ACTIVE_APPNAME" -e "$CMD_ACTIVATE" -e "$CMD_NEWTAB" -e "$CMD_REACTIVATE_PREV_APP" >/dev/null
                fi
            else
                osascript -e "$CMD_ACTIVATE" -e "$CMD_NEWTAB" >/dev/null
            fi
        else # make *window*
            if (( inBackground )); then
                # !! Sadly, because we must create a new tab by sending a keystroke to Terminal, we must briefly activate it, then reactivate the previously active application.
                if (( inBackground == 2 )); then # Restore the previously active window after creating the new one.
                    osascript -e "$CMD_SAVE_ACTIVE_WIN" -e "$CMD_NEWWIN" -e "$CMD_REACTIVATE_PREV_WIN" >/dev/null
                else
                    osascript -e "$CMD_NEWWIN" >/dev/null
                fi
            else
                    # Note: Even though we do not strictly need to activate Terminal first, we do it so as to better visualize what is happening (the new window will appear stacked on top of an existing one).
                osascript -e "$CMD_ACTIVATE" -e "$CMD_NEWWIN" >/dev/null
            fi
        fi
    fi

}

# Opens a new Terminal window and optionally executes a command.
function newwin {
    newtab "$@" # Simply pass through to 'newtab', which will examine the call stack to see how it was invoked.
}

3
@jcollum私の喜び。お役に立ててうれしいです。投稿を更新して、注意が必要な作業フォルダーとコードを更新しました:オプションを追加しました-g(新しいタブ/ウィンドウの作成時に-Gターミナルアクティブ化しないでください)および(ターミナルアクティブ化せず、ターミナル内のアクティブなタブを変更しません) )-たとえば、サーバーをバックグラウンドで起動するときに役立ちます。この方法で新しいタブを作成する場合、以前にアクティブだったアプリケーションを再びアクティブにする前に、ターミナルをしばらくアクティブにする必要があることに注意してください。
mklement0

1
@Leonardo新しいタブには、関数が呼び出されたタブと同じ作業ディレクトリがあります。を呼び出す前にスクリプト内の別のフォルダーに変更してもnewtab、残念ながら機能しません。回避策はevalcdコマンドをnewtab含むステートメントをに渡すことです。例:newtab eval "cd ~/Library/Application\ Support; ls"。に渡されるコマンド全体を二重引用符で囲み、eval内部でバックスラッシュエスケープを使用します。
mklement0 2013年

1
@IntegrityFirst:提案に従って、関数のシグネチャをfunction newtabfunction newwin(ただし、括弧なし)に切り替えました。これにより、関数を定義するときにエイリアスとの衝突を回避する必要がありますが、呼び出し時に同じ名前のエイリアスが優先されることに注意してください(エイリアス、アドホックをバイパスし、関数名の任意の部分を引用します(例:)\newtab
mklement0 2015年

2
@IntegrityFirst:これが私が学んだことです:POSIX <name>() { ... }関数構文を使用する<name>と、エイリアス展開の対象となり、エイリアス<name>が定義された場合に関数定義(解析エラー!)が壊れます。通常呼び出されるスクリプトでは、エイリアス展開はデフォルトでオフになっているため、通常は問題ありません。ただし、プロファイル/初期化ファイルなどの対話型シェルから取得されたスクリプトでは、エイリアス拡張がオンになっています。修正:非POSIX function <name> { ... } 構文を使用して関数を定義します-その場合<name>、エイリアス拡張の対象にはなりません。
mklement0 2015年

1
ありがとう!これは、追加されますif [ "${BASH_SOURCE}" == "${0}" ]それはスクリプトとして呼び出すことができるように、case文で(例えばnewtab.shnewwin.sh):gist.github.com/westurner/01b6be85e5a51fda22a6
ウェスターナー

18

これがbash_itによってどのように行われるかです

function tab() {
  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 "cd \"$PWD\"; $*" in window 1
    end tell
EOF
}

これを.bash_profileに追加した後、 tabコマンドをて現在の作業ディレクトリを新しいタブで開きます。

参照:https : //github.com/revans/bash-it/blob/master/plugins/available/osx.plugin.bash#L3


1
非常に役立ちます。これを私の.bash_profileで使用すると、一連のタブを起動して、それらに自動的にsshできます。もちろん、SSHキーペア認証を有効にしています
Sandeep Kanabar 2016

16
osascript -e 'tell app "Terminal"
   do script "echo hello"
end tell'

これにより、新しいターミナルが開き、その中でコマンド「echo hello」が実行されます。


3
これは機能しましたが、新しいタブはターミナルの別のインスタンスで作成されました。とにかく、ターミナルの現在のインスタンスに新しいタブが残っていますか?
Calvin Cheng、

ちなみに、do script ""空の文字列を使用すると、コマンドを発行せずに新しい端末を作成できます。
クリスページ

9

あなたが使用している場合はOH-MY-zshの(すべてのトレンディなオタクを使用する必要があります)、で「OSX」プラグインを起動した後.zshrc、単に入力tabコマンドを、それは新しいタブを開き、cdあなたがいたディレクトリにあります。


とても面白いですね。zcshと従来のbashの違いは何ですか?
Calvin Cheng

それらは非常に似ていますが、最も興味深いのは、インテリジェントで強力なタブ補完と自動修正機能を備えていることです。ここで良い比較を参照してください。Oh-my-zshが、便利で使いやすい設定/プラグインを使用して環境を設定します
CharlesB

CharlesBの比較リンクをざっと見てみました。とても興味深い。BPythonシェルとiPythonシェルのように聞こえます。
Calvin Cheng

zshは制御を失うためにさらに古い古い残骸を回避することに成功しました
ジェームズ

これについてもっと情報を提供できますか?タブコマンドとは何ですか?入力tabしても何も起こらない
Solvitieg

7

キーボードショートカットcmd-tは新しいタブを開くので、次のようにこのキーストロークをOSAコマンドに渡すことができます。

osascript -e 'tell application "System Events"' -e 'keystroke "t" using command down' -e 'end tell'


6

これらを.bash_profileに追加して、tabnameとnewtabにアクセスできるようにしました

tabname() {
  printf "\e]1;$1\a"
}

new_tab() {
  TAB_NAME=$1
  COMMAND=$2
  osascript \
    -e "tell application \"Terminal\"" \
    -e "tell application \"System Events\" to keystroke \"t\" using {command down}" \
    -e "do script \"printf '\\\e]1;$TAB_NAME\\\a'; $COMMAND\" in front window" \
    -e "end tell" > /dev/null
}

したがって、特定のタブにいるときは、次のように入力できます

tabname "New TabName"

開いているすべてのタブを整理します。タブの情報を取得してそこで変更するよりもはるかに優れています。


ありがとう。タブからSSHを実行し、SSHセッションを終了した後、タブ名を保持する方法を知っていますか?
anjanb 2014

4

私はこれが古い投稿であることを知っていますが、これは私にとってうまくいきました:

open -a Terminal "`pwd`"

以下のように要求されたコマンドを実行するには、ちょっとした処理が必要です。

echo /sbin/ping 8.8.8.8 > /tmp/tmp.sh;chmod a+x /tmp/tmp.sh;open -a Terminal /tmp/tmp.sh

非常に素晴らしい!ターミナルの新しいインスタンスで実行されるコマンドを渡したい場合はどうすればよいですか?:D
Strazan

@Strazanは上記の回答を編集しました...楽しんでください!! 端末はそのようなパラメータを取るように見えます...
ネオフィット

3

端末ウィンドウにいるとき、command + n =>は新しい端末を開き、command + t =>は現在の端末ウィンドウに新しいタブを開きます


1
これはコマンドラインから動作する必要があります。基本的にはスクリプトです。それは繰り返しの多い作業なので
Gianfranco P.

2

iTermを使用している場合、このコマンドは新しいタブを開きます。

osascript -e 'tell application "iTerm" to activate' -e 'tell application "System Events" to tell process "iTerm" to keystroke "t" using command down'

これを.zshrcまたは.bashrcに追加する必要がある場合は、エイリアスの代わりに関数を使用して追加できます(すべてのエスケープのため、最終的にエスケープする必要があります)。 stackoverflow.com/a/20111135/1401336
Vigrant

@Andrew Schreiber:しかし、コントロールは新しいタブに移動しません。つまり、新しいタブを開いた後にコードがある場合、そのコードは元のタブで実行されます。新しいタブで次のコマンドを処理するようにスクリプトに指示する方法はありますか?
アシュウィン

1
open -n -a Terminal

そして、あなたはパラメータとしてターゲットディレクトリを渡すことができます

open -n -a Terminal /Users

これにより、新しいウィンドウが開きます。タブではありません。
stack-delay

0

標準のスクリプトコマンド(エコー)に基づく、この単純なスニペットはどうでしょうか。

# set mac osx's terminal title to "My Title"
echo -n -e "\033]0;My Title\007"

0

X(homebrewやQuartzなどから)をインストールすると、単純な "xterm&"が(ほぼ)トリックを実行し、新しいターミナルウィンドウを開きます(ただし、タブではありません)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.