Программно запустить Terminal.app с указанной командой (и пользовательскими цветами) - PullRequest
26 голосов
/ 10 декабря 2010

Я могу запустить xterm из командной строки (или из программы через системный вызов) следующим образом:

/usr/X11/bin/xterm -fg SkyBlue -bg black -e myscript

Это запустит xterm с синим текстом и черным фоном и запуститПроизвольный скрипт внутри него.

Мой вопрос: как мне сделать эквивалент с Terminal.app?

Ответы [ 6 ]

22 голосов
/ 19 октября 2011

Вы также можете открыть приложение по идентификатору пакета и указать другие параметры.

Если в текущем каталоге есть исполняемый скрипт test.sh, следующая команда откроет и запустит его в Terminal.app

 open -b com.apple.terminal test.sh 

Единственный недостаток, который я могу найти, - это то, что Terminal, похоже, не наследует вашу текущую среду, поэтому вам придется найти другой способ передачи параметров в скрипт, который вы хотите запустить. Я думаю, что создание сценария на лету для встраивания параметров было бы одним из подходов (конечно, с учетом последствий для безопасности ...)

13 голосов
/ 10 декабря 2010

Почти все (все?) Программы osx могут быть запущены из командной строки с помощью:

appName.app / Contents / MacOS / command

Для терминала команда:

/ Applications / Utilities / Terminal.app / Contents / MacOS / Terminal

Вы можете использовать автозаполнение (вкладка) или ls, чтобы найти правильные имена файлов.«.app» - это, в основном, папка.

Чтобы изменить цвета и запустить скрипт ... Я думаю, что вы не можете сделать это с помощью скриптов оболочки, так как Terminal не принимает аргументы («Terminal myScript.sh» не делаетзапустить myScript).С iTerm это работает.

Обходной путь - использовать яблочный скрипт (обернутый в скрипт оболочки):

   #!/bin/sh
   osascript -e '
     tell application "Terminal"
       activate
       tell window 1
          do script "sleep 5; exit"
          set background color to {0, 11111, 11111}
          set win_id to id
       end tell

       set w_ids to (id of every window)

       repeat while w_ids contains win_id
         delay 1
         set w_ids to (id of every window)
       end repeat
    end tell'

Хорошо, теперь он должен вести себя точно так же, как в примере xterm.Недостатком является постоянный опрос идентификаторов окон (что является плохим программированием).

edit: Немного более элегантный яблочный скрипт использовал бы свойство busy в терминале.Я оставлю оригинальный код, как он работает для общей программы (не только терминала).

tell application "Terminal"
    tell window 1
        do script "sleep 2"
        set background color to {0, 11111, 11111}
        repeat while busy
            delay 1
        end repeat
        close
    end tell
end tell

Также для совершенно правильной программы необходимо проверить, работает терминал или нет.Это влияет на количество открытых окон.Таким образом, это должно быть выполнено в первую очередь (снова неприятный вид хака, который я отредактирую позже, когда найду рабочее решение).*

12 голосов
/ 06 февраля 2015

Предполагая, что у вас уже есть нужные цвета в одном из ваших профилей терминала, вот что я придумал (с некоторой помощью из ответа Юхи и из этого ответа Serverfault ).


Обновление:

Если подумать, я думаю, что это echo дело слишком сложное. Оказывается, вы можете использовать osascript для создания исполняемого файла AppleScript со строкой Шебанга:

#!/usr/bin/osascript                                                                            

on run argv                                                                                     
  if length of argv is equal to 0                                                               
    set command to ""                                                                           
  else                                                                                          
    set command to item 1 of argv                                                               
  end if                                                                                        

  if length of argv is greater than 1                                                           
    set profile to item 2 of argv                                                               
    runWithProfile(command, profile)                                                            
  else                                                                                          
    runSimple(command)                                                                          
  end if                                                                                        
end run                                                                                         

on runSimple(command)                                                                           
  tell application "Terminal"                                                                   
    activate                                                                                    
    set newTab to do script(command)                                                            
  end tell                                                                                      
  return newTab                                                                                 
end runSimple                                                                                   

on runWithProfile(command, profile)                                                             
  set newTab to runSimple(command)                                                              
  tell application "Terminal" to set current settings of newTab to (first settings set whose name is profile)                                                                                      
end runWithProfile

Сохраните это как term.scpt, сделайте его исполняемым с chmod +x и используйте его так же, как показано ниже, например, term.scpt "emacs -nw" "Red Sands".


Оригинальный ответ:

При условии, что мы сохраним приведенный ниже скрипт как term.sh ...

#!/bin/sh

echo '
on run argv
  if length of argv is equal to 0
    set command to ""
  else
    set command to item 1 of argv
  end if

  if length of argv is greater than 1
    set profile to item 2 of argv
    runWithProfile(command, profile)
  else
    runSimple(command)
  end if
end run

on runSimple(command)
  tell application "Terminal"
    activate
    set newTab to do script(command)
  end tell
  return newTab
end runSimple

on runWithProfile(command, profile)
  set newTab to runSimple(command)
  tell application "Terminal" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
' | osascript - "$@" > /dev/null

... он может быть вызван следующим образом:

  • term.sh
    • открывает новое окно терминала, ничего особенного
  • term.sh COMMAND
    • открывает новое окно терминала, выполняя указанную команду. Команды с аргументами могут быть заключены в кавычки, например, term.sh "emacs -nw" чтобы открыть новый терминал и запустить (не оконный) emacs
  • term.sh COMMAND PROFILE
    • открывает новое окно терминала, выполняя указанную команду, и устанавливает его в указанный профиль. Профили с пробелами в именах могут быть заключены в кавычки, например, term.sh "emacs -nw" "Red Sands" чтобы открыть новый терминал и запустить (не оконный) emacs с профилем Red Sands.

Если вы вызовете его с неверным именем команды, оно все равно откроет окно и настроит профиль, но в новом окне вы получите сообщение об ошибке bash.

Если вы вызовете его с неверным именем профиля, окно все равно откроется, и команда все равно будет выполняться, но окно останется с профилем по умолчанию, и вы получите сообщение об ошибке (в stderr, где бы вы его не запустили) линии

525: 601: ошибка выполнения: Терминал получил ошибку: Не удается получить настройки, установленные 1, чье имя = "elvis". Неверный индекс. (-1719)

Вызов немного хакерский, и, возможно, его можно было бы улучшить, если бы я потратил время на изучение getopt (например, что-то вроде term.sh -p profile -e command было бы лучше и, например, позволило бы вам легко открыть новый терминал в указанный профиль без вызова команды). И я также не удивлюсь, если есть способы облажаться со сложным цитированием. Но это работает для большинства целей.

4 голосов
/ 13 февраля 2012

Вы также можете перейти в графический интерфейс терминала, полностью настроить параметры для своего сердца, экспортировать их в файл ".terminal" и / или сгруппировать конфигурации в группу окон и экспортировать их в файл терминала "myGroup..Терминал".Затем

open myGroup.terminal

сразу откроет терминал (-ы) со всеми вашими настройками и командами запуска, как настроено.

1 голос
/ 31 января 2018

Ответ от @ david-moles выше работает, но запустите терминал и команду в ~ текущем рабочем каталоге, где был запущен термин.Этот вариант добавляет команду cd.

#!/usr/bin/env bash
# based on answer by @david-moles in 
# /2367874/programmno-zapustit-terminal-app-s-ukazannoi-komandoi-i-polzovatelskimi-tsvetami
echo "
on run argv
  if length of argv is equal to 0
    set command to \"\"
  else
    set command to item 1 of argv
  end if
  set command to \"cd '"$PWD"' ;\" & command
  if length of argv is greater than 1
    set profile to item 2 of argv
    runWithProfile(command, profile)
  else
    runSimple(command)
  end if
end run

on runSimple(command)
  tell application \"Terminal\"
    activate
    set newTab to do script(command)
  end tell
  return newTab
end runSimple

on runWithProfile(command, profile)
  set newTab to runSimple(command)
  tell application \"Terminal\" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
" | osascript - "$@" > /dev/null

Может быть способ установить PWD с помощью applecript.

Примечание: Когда я использую это, я иногда использую два окна терминала, одно оболочкуработает в ~ и второй, которая запускает команду cd и команду из argv [1].Кажется, происходит, если Терминал еще не запущен;возможно, это открывает старое состояние (даже если у меня не было открытых терминалов, когда я закрывал его).

1 голос
/ 10 декабря 2010

Вы можете запустить терминал с помощью следующей команды, не зная, как задать цвета:

 open /Applications/Utilities/Terminal.app/
...