在新的Mac OS X终端窗口中运行命令

时间:2009-06-12 22:26:29

标签: macos bash terminal

我一直在试图弄清楚如何在新的Max OS X Terminal.app窗口中运行bash命令。举个例子,这是我在新的bash过程中运行命令的方法:

bash -c "my command here"

但是这会重用现有的终端窗口而不是创建新的终端窗口。我想要这样的东西:

Terminal.app -c "my command here"

但当然这不起作用。我知道“open -a Terminal.app”命令,但是我没有看到如何将参数转发到终端,或者即使我使用了哪些参数。

10 个答案:

答案 0 :(得分:76)

我能想到的一种方法就是创建一个.command文件并运行它:

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

或使用applescript:

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

虽然你要么必须逃避很多双引号或者不能使用单引号

答案 1 :(得分:64)

部分解决方案:

将您想要完成的事情放在shell脚本中,如此

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

不要忘记'chmod +x file'使其可执行。那你可以

open -a Terminal.app scriptfile

它将在新窗口中运行。在脚本末尾添加“bash”以防止新会话退出。 (虽然您可能必须弄清楚如何加载用户rc文件和东西..)

答案 2 :(得分:31)

我一直试图这样做。这是一个更改到同一工作目录的脚本,运行命令并关闭终端窗口。

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

答案 3 :(得分: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

答案 4 :(得分:3)

我制作了奥斯卡答案的功能版本,这个版本也复制环境并更改到相应的目录

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

答案 5 :(得分:2)

这是另一种观点(也使用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

答案 6 :(得分: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

答案 7 :(得分:0)

您还可以通过按Shift + ⌘ + N组合键来调用终端的新命令功能。您放入该框的命令将在新的终端窗口中运行。

答案 8 :(得分:0)

一个同事问我如何一次打开很多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文件保持不变。否则,shell将完成得太快,在启动的会话有机会读取文件之前执行陷阱以删除temp目录(由mktemp创建)。

答案 9 :(得分:-1)

我称这个脚本为trun。我建议将它放在可执行路径的目录中。确保它是可执行的,如下所示:

Private Sub CommandButton1_Click()

'This Code will remove any names defined in name manager
    Dim nm As Name

    On Error Resume Next
    For Each nm In ActiveWorkbook.Names
        nm.Delete
    Next
    On Error GoTo 0

'Find the last used row in a Column B and select range from B2 to D:LastRow
  Dim LastRow2 As Long

    With Worksheets("FES LIST")
        LastRow2 = .Cells(.Rows.Count, "B").End(xlUp).Row

    Sheets("FES LIST").Activate

    Worksheets("FES LIST").Range(Cells(2, 2), Cells(LastRow2, 4)).Select
    Worksheets("FES LIST").Range(Cells(2, 2), Cells(LastRow2, 4)).Name = "NameRange0"

    End With
End Sub

然后你可以在新窗口中运行命令,只需在它们之前添加trun,如下所示:

chmod +x ~/bin/trun

这是脚本。它做了一些奇特的事情,比如传递你的参数,更改标题栏,清除屏幕以删除shell启动杂乱,完成后删除它的文件。通过为每个新窗口使用唯一文件,它可以用于同时创建许多窗口。

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