새 Mac OS X 터미널 창에서 명령 실행


92

새로운 Max OS X Terminal.app 창에서 bash 명령을 실행하는 방법을 알아 내려고 노력했습니다. 예를 들어, 새 bash 프로세스에서 명령을 실행하는 방법은 다음과 같습니다.

bash -c "my command here"

그러나 이것은 새 창을 만드는 대신 기존 터미널 창을 재사용합니다. 나는 다음과 같은 것을 원한다.

Terminal.app -c "my command here"

그러나 물론 이것은 작동하지 않습니다. "open -a Terminal.app"명령을 알고 있지만 인수를 터미널로 전달하는 방법을 알 수 없거나 어떤 인수를 사용할지 알 수 없습니다.


언제든지 기본 설정을 열고 "프로필"탭으로 이동 한 다음 "셸"페이지로 이동하여 시작 명령을 설정할 수 있습니다. 응용 프로그램이 열릴 때만 실행되지만 해키 대안보다 더 잘 작동합니다!
Zane Helton 2015 년

또한 수퍼 유저에서 같은 질문을 참조 superuser.com/q/174576/122841
비틀

답변:


96

내가 생각할 수있는 한 가지 방법은 .command 파일을 만들고 다음과 같이 실행하는 것입니다.

echo echo hello > sayhi.command; chmod +x sayhi.command; open sayhi.command

또는 applescript를 사용하십시오.

osascript -e 'tell application "Terminal" to do script "echo hello"'

많은 큰 따옴표를 이스케이프해야하거나 작은 따옴표를 사용할 수 없더라도


첫 번째 방법을 결정했습니다. 꽤 hack-ish이지만 작동하며 내 명령이나 다른 것에서 따옴표를 이스케이프하는 것에 대해 걱정할 필요가 없습니다. 감사.
Walt D

3
명령을 매개 변수화하여 실행해야하는 경우 작은 따옴표와 큰 따옴표를 바꾸고 싶을 것입니다. 이 작업을 올바르게 수행하려면 차이점을 이해해야합니다. osascript -e "tell application \"Terminal\" to do script \"echo '$variable'\"'
tripleee

누구든지 터미널 창 위에 남은 바보를 닫는 방법을 알고 있습니까?
Nicholas DiPiazza

추가 ; exit처럼, 쉘 스크립트 명령의 끝에서 do script "echo hello; exit". 여전히 창을 별도로 닫아야합니다.
tripleee

65

부분 솔루션 :

원하는 것을 쉘 스크립트에 넣으십시오.

#!/bin/bash
ls
echo "yey!"

그리고 ' chmod +x file'을 (를) 실행 가능하게 만드는 것을 잊지 마십시오 . 그런 다음

open -a Terminal.app scriptfile

새 창에서 실행됩니다. bash새 세션이 종료되지 않도록 스크립트 끝에 ' '를 추가하십시오 . (사용자의 rc 파일 등을로드하는 방법을 알아 내야 할 수도 있습니다.)


7
새로 열린 창의 컨텍스트는 사용자의 루트 폴더 인 것 같습니다 /Users/{username}. 컨텍스트 폴더를 연 상위 터미널 창과 동일하게 유지하는 방법이 있습니까?
Johnny Oshika 2015 년

> 비록 사용자 rc 파일과 물건을로드하는 방법을 알아 내야 할 수도 있지만 ..이를 위해 bash -l 사용
Aivar

35

나는 이것을 한동안 시도 해왔다. 다음은 동일한 작업 디렉토리로 변경하고 명령을 실행하고 터미널 창을 닫는 스크립트입니다.

#!/bin/sh 
osascript <<END 
tell application "Terminal"
    do script "cd \"`pwd`\";$1;exit"
end tell
END

허용되는 스크립트를 싫어하면 현재 디렉토리 문제를 해결합니다. 감사!
Marboni

훌륭한 솔루션; 그래도 시작tab 1 of window id 7433에서 stdout 과 같은 것을 출력합니다 . 이를 억제하려면 앞에 . >/dev/null <<END
mklement0

1
이것은 본질적으로 터미널 창을 닫지 않습니다. 명령 인터프리터를 종료합니다. 창을 자동으로 닫거나 명령 인터프리터를 완전히 종료 할 때 Terminal.app을 구성해야합니다.
user66001

8

누군가가 신경 쓰는 경우 iTerm에 해당하는 내용은 다음과 같습니다.

#!/bin/sh
osascript <<END
tell application "iTerm"
 tell the first terminal
  launch session "Default Session"
  tell the last session
   write text "cd \"`pwd`\";$1;exit"
  end tell
 end tell
end tell
END

3

여기에 또 다른 방법이 있습니다 (AppleScript도 사용).

function newincmd() { 
   declare args 
   # escape single & double quotes 
   args="${@//\'/\'}" 
   args="${args//\"/\\\"}" 
   printf "%s" "${args}" | /usr/bin/pbcopy 
   #printf "%q" "${args}" | /usr/bin/pbcopy 
   /usr/bin/open -a Terminal 
   /usr/bin/osascript -e 'tell application "Terminal" to do script with command "/usr/bin/clear; eval \"$(/usr/bin/pbpaste)\""' 
   return 0 
} 

newincmd ls 

newincmd echo "hello \" world" 
newincmd echo $'hello \' world' 

참조 : codesnippets.joyent.com/posts/show/1516


3

나는 Oscar의 대답의 함수 버전을 만들었습니다. 이것은 또한 환경을 복사하고 적절한 디렉토리로 변경합니다.

function new_window {
    TMP_FILE=$(mktemp "/tmp/command.XXXXXX")
    echo "#!/usr/bin/env bash" > $TMP_FILE

    # Copy over environment (including functions), but filter out readonly stuff
    set | grep -v "\(BASH_VERSINFO\|EUID\|PPID\|SHELLOPTS\|UID\)" >> $TMP_FILE

    # Copy over exported envrionment
    export -p >> $TMP_FILE

    # Change to directory
    echo "cd $(pwd)" >> $TMP_FILE

    # Copy over target command line
    echo "$@" >> $TMP_FILE

    chmod +x "$TMP_FILE"
    open -b com.apple.terminal "$TMP_FILE"

    sleep .1 # Wait for terminal to start
    rm "$TMP_FILE"
}

다음과 같이 사용할 수 있습니다.

new_window my command here

또는

new_window ssh example.com

1
TMP_FILE="tmp.command"둘 이상의 프로세스를 동시에 시작하면 라인 이 문제가 될 수 있습니다. 나는 그것을 교체하는 것이 좋습니다TMP_FILE=$(mktemp "/tmp/command.XXXXXX")
duthen

2

여기 내 멋진 스크립트가 있습니다. 필요한 경우 새 터미널 창을 만들고 Finder가 맨 앞에 있으면 Finder가있는 디렉토리로 전환합니다. 명령을 실행하는 데 필요한 모든 기계가 있습니다.

on run
    -- Figure out if we want to do the cd (doIt)
    -- Figure out what the path is and quote it (myPath)
    try
        tell application "Finder" to set doIt to frontmost
        set myPath to finder_path()
        if myPath is equal to "" then
            set doIt to false
        else
            set myPath to quote_for_bash(myPath)
        end if
    on error
        set doIt to false
    end try

    -- Figure out if we need to open a window
    -- If Terminal was not running, one will be opened automatically
    tell application "System Events" to set isRunning to (exists process "Terminal")

    tell application "Terminal"
        -- Open a new window
        if isRunning then do script ""
        activate
        -- cd to the path
        if doIt then
            -- We need to delay, terminal ignores the second do script otherwise
            delay 0.3
            do script " cd " & myPath in front window
        end if
    end tell
end run

on finder_path()
    try
        tell application "Finder" to set the source_folder to (folder of the front window) as alias
        set thePath to (POSIX path of the source_folder as string)
    on error -- no open folder windows
        set thePath to ""
    end try

    return thePath
end finder_path

-- This simply quotes all occurrences of ' and puts the whole thing between 's
on quote_for_bash(theString)
    set oldDelims to AppleScript's text item delimiters
    set AppleScript's text item delimiters to "'"
    set the parsedList to every text item of theString
    set AppleScript's text item delimiters to "'\\''"
    set theString to the parsedList as string
    set AppleScript's text item delimiters to oldDelims
    return "'" & theString & "'"
end quote_for_bash

1

동료가 한 번에 많은 ssh 세션을 여는 방법을 물었습니다. 이 스크립트를 작성하기 위해 cobbal의 답변을 사용했습니다.

tmpdir=$( mktemp -d )
trap '$DEBUG rm -rf $tmpdir ' EXIT
index=1

{
cat <<COMMANDS
ssh user1@host1
ssh user2@host2
COMMANDS
} | while read command
do 
  COMMAND_FILE=$tmpdir/$index.command
  index=$(( index + 1 ))
  echo $command > $COMMAND_FILE
  chmod +x  $COMMAND_FILE
  open $COMMAND_FILE
done
sleep 60

명령 목록을 업데이트하면 (ssh 호출 일 필요는 없음) 실행되는 모든 명령에 대해 추가로 열린 창이 나타납니다. sleep 60끝은 유지하기가 .command그들이이 실행되는 동안 주위에 파일을. 그렇지 않으면 쉘이 너무 빨리 완료되어 실행 된 세션이 파일을 읽을 기회를 갖기 전에 임시 디렉토리 (mktemp에 의해 생성됨)를 삭제하는 트랩을 실행합니다.


0

키 조합 을 눌러 터미널 의 새로운 명령 기능을 호출 할 수도 있습니다 Shift + ⌘ + N. 상자에 입력 한 명령은 새 터미널 창에서 실행됩니다.


물론 알아두면 유용하지만 프로그래밍 방식으로해야합니다. 내 프로그램이 .command 파일을 생성 한 다음 열도록하는 것은 합리적인 (조금 hackish) 솔루션입니다.
Walt D

0

저는이 스크립트를 trun이라고 부릅니다. 실행 가능한 경로의 디렉토리에 넣는 것이 좋습니다. 다음과 같이 실행 가능한지 확인하십시오.

chmod +x ~/bin/trun

그런 다음 다음과 같이 명령 앞에 trun을 추가하여 새 창에서 명령을 실행할 수 있습니다.

trun tail -f /var/log/system.log

다음은 스크립트입니다. 인수를 전달하고, 제목 표시 줄을 변경하고, 화면을 정리하여 쉘 시작 혼란을 제거하고, 완료되면 파일을 제거하는 등의 멋진 작업을 수행합니다. 새 창마다 고유 한 파일을 사용하여 동시에 여러 창을 만드는 데 사용할 수 있습니다.

#!/bin/bash
# make this file executable with chmod +x trun
# create a unique file in /tmp
trun_cmd=`mktemp`
# make it cd back to where we are now
echo "cd `pwd`" >$trun_cmd
# make the title bar contain the command being run
echo 'echo -n -e "\033]0;'$*'\007"' >>$trun_cmd
# clear window
echo clear >>$trun_cmd
# the shell command to execute
echo $* >>$trun_cmd
# make the command remove itself
echo rm $trun_cmd >>$trun_cmd
# make the file executable
chmod +x $trun_cmd

# open it in Terminal to run it in a new Terminal window
open -b com.apple.terminal $trun_cmd

1
$*전체를 잘못 사용 하면 입력에서 사소한 인용문이 손상됩니다. "$@"대신 원합니다 .
tripleee

나는을 찾고 있었다 open -b com.apple.terminal. 감사합니다
Ebru Yener
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.