명령 줄에서 새 터미널 탭 열기 (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'

오! 귀하의 의견을 완전히 놓치고 Google을 통해 유사한 해결책을 찾았습니다. 한 가지 차이점은 터미널이 가장 앞쪽에있는 응용 프로그램이 아니라면 작동하지 않았다는 것입니다 (10.6.8에서). 그래서 "활성화"를 추가하여 강제로 맨 앞으로 옮겼습니다.
Gordon Davisson 2011-08-25

5
편집 : echo hello이 새 탭에 새 명령을 어떻게 삽입합니까?
ThomasReggi

22
@ThomasReggi : -e 'tell application "Terminal" to do script "echo hello" in selected tab of the front window'osascript 명령 끝에 추가 합니다.
Gordon Davisson 2012-08-26

2
iTerm에 대한 @clevertension 그것은 단지open -a iTerm ~/Applications/
onmyway133

1
@Ciastopiekarz 새로 열린 탭에서 의미합니까? ThomasReggi에 대한 내 대답과 동일한 접근 방식을 사용하십시오 -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으로ttab , 도 지원 iTerm2를 :

  • 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- 해결 방법 eval으로 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 dec.

1
@Leonardo 새 탭에는 함수가 호출 된 탭과 동일한 작업 디렉토리가 있습니다. newtab불행히도 를 호출하기 전에 스크립트 내에서 다른 폴더로 변경하면 작동하지 않습니다. 해결 방법은 명령 eval과 함께 명령문 을에 전달하는 것입니다 . 예 : . 에 전달 된 전체 명령을 큰 따옴표 로 묶고 내부에 백 슬래시 이스케이프를 사용합니다. cdnewtabnewtab eval "cd ~/Library/Application\ Support; ls"eval
mklement0

1
@IntegrityFirst : 귀하의 제안에 따라 함수 시그니처를 function newtabfunction newwin(그러나 괄호 없음)로 전환 했으므로 함수를 정의 할 때 별칭과의 충돌을 피해야 하지만 호출시 동일한 이름의 별칭이 우선합니다. 별칭, 임시를 무시하고 함수 이름의 일부를 인용합니다 (예 :) \newtab.
mklement0

2
@IntegrityFirst : 내가 배운 내용은 다음과 같습니다. POSIX <name>() { ... }함수 구문을 사용하면 별칭 확장<name>적용되어 별칭이 정의되면 함수 정의 (파싱 오류!)가 깨집니다 <name>. 일반적으로 호출되는 스크립트에서는 별칭 확장이 기본적으로 해제되어 있으므로 일반적으로 문제가되지 않습니다. 그러나 프로파일 / 초기화 파일과 같이 INTERACTIVE 셸에서 가져온 스크립트에서는 별칭 확장이 켜져 있습니다. 수정 : 비 POSIX function <name> { ... } 구문을 사용하여 함수를 정의합니다. <name>그러면 별칭 확장이 적용되지 않습니다.
mklement0

1
감사! 이것은 추가 if [ "${BASH_SOURCE}" == "${0}" ]가 스크립트로 호출 할 수 있도록 case 문 (예를 들어 newtab.sh, newwin.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에게

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

그러면 새 터미널이 열리고 그 안에서 "echo hello"명령이 실행됩니다.


3
이것은 작동했지만 새 탭은 별도의 터미널 인스턴스에서 생성되었습니다. 어쨌든 내 터미널의 현재 인스턴스에 새 탭이 남아 있습니까?
Calvin Cheng

그런데 do script ""빈 문자열을 사용하여 명령을 내리지 않고 새 터미널을 만들 수 있습니다 .
Chris 페이지

9

당신이 사용하는 경우 오 - 내 - zsh을을 (모든 트렌디 한 괴짜가 사용해야하는)에 플러그인 "OSX"를 활성화 한 후 .zshrc, 단순히 입력 tab명령을; 새 탭이 열리고 cd귀하가 있던 디렉토리에 있습니다.


매우 흥미로워 보입니다. zcsh와 기존 bash의 차이점은 무엇입니까?
Calvin Cheng

매우 유사하지만 가장 흥미롭게도 지능적이고 강력한 탭 완성 및 자동 수정 기능이 있습니다. 여기에서 좋은 비교를 참조 하십시오 . 아 - 내 - zsh을 얻을 수있는 좋은 편리한 설정 / 플러그인과 환경을 설정하는 것입니다 당신은 시작
CharlesB

CharlesB의 비교 링크를 간략히 살펴 보았습니다. 매우 흥미로운. BPython 쉘 대 iPython 쉘과 거의 비슷합니다.
Calvin Cheng

zsh는 통제력을 잃기 위해 훨씬 더 오래된 잔해를 유지 관리합니다
James

이에 대한 자세한 정보를 제공 할 수 있습니까? 탭 명령은 무엇입니까? 입력 tab이 아무것도하지 않는 것 같습니다
Solvitieg

7

키보드 단축키 cmd-t는 새 탭을 열므로 다음과 같이이 키 입력을 OSA 명령에 전달할 수 있습니다.

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


6

tabname 및 newtab에 액세스 할 수 있도록 .bash_profile에 추가했습니다.

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

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이 위의 답변을 편집했습니다 ... 재미있게 즐기십시오! 터미널이 이와 같은 매개 변수를 사용하는 것 같습니다 ...
neophytte

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 :하지만 컨트롤이 새 탭으로 전송되지 않습니다. 새 탭을 연 후 코드가 있으면 해당 코드가 원래 탭에서 실행됩니다. 새 탭에서 다음 명령을 처리하도록 스크립트에 지시하는 방법이 있습니까?
Ashwin

1
open -n -a Terminal

대상 디렉토리를 매개 변수로 전달할 수 있습니다.

open -n -a Terminal /Users

이것은 나를 위해 새 창을 엽니 다. 탭이 아닙니다.
스택 지연

0

표준 스크립트 명령 (echo)을 기반으로하는이 간단한 스 니펫은 어떻습니까?

# 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.