Czy uruchomić skrypt powłoki w systemie OS X bez wyświetlania okna terminala?

23

Próbuję skonfigurować kilka skrótów klawiaturowych, które otwierają określone sesje iTerm, co mogłem zrobić z BetterTouchTool i odrobiną magii AppleScript. Problem polega na tym, że OS X nalega na otwarcie okna terminala dla dowolnego skryptu powłoki wykonanego za pomocą GUI (tj. Z Findera lub jako skrót klawiaturowy z BetterTouchTool). Okno terminala nie pojawi się, jeśli uruchomię skrypt bezpośrednio z innego terminala.

Rozwiązaniem, które znalazłem, było owinięcie skryptu w katalogu .app, co rozwiązuje problem zbędnego okna terminala, ale ma kilka innych problemów (na przykład OS X wydaje się traktować każde powstałe okno iTerm jako osobną aplikację, zaśmiecając moją stację dokującą ). (EDYCJA: to zachowanie zostało spowodowane przez błąd w moim skrypcie, patrz poniżej)

Próbowałem też przypisać aplikację Terminal do innego wirtualnego pulpitu w ustawieniach Spaces, próbując przenieść go poza zasięg wzroku, ale wtedy po prostu przełączy się na ten pulpit przed uruchomieniem skryptu.

Czy istnieje sposób, aby całkowicie wyłączyć to zachowanie? Znalazłem już ustawienie w preferencjach terminalu, aby zamknąć okno po zakończeniu skryptu, ale nadal denerwujące jest wyświetlanie okna terminala na sekundę.

toupeira
źródło
Przepraszam, nie do końca rozumiem. Co chcesz zrobić z tymi skryptami powłoki? Czy chcesz otworzyć iTerm za pomocą skryptu powłoki? Czy mówisz wyłącznie o Terminal.app lub mieszasz iTerm z „Terminal” w swoim pytaniu? Czy mógłbyś zamieścić przykład tego, co próbujesz uruchomić?
slhck
Skonfigurowałem kilka sesji iTerm, aby uruchomić normalną powłokę, otworzyć konsolę Rails, wyświetlić dziennik Railsów itp. Używam wyłącznie iTerm, a terminal jest automatycznie otwierany przez OS X z jakiegokolwiek niemądrego powodu. Ale tak czy inaczej, znalazłem rozwiązanie, które sprawi, że podejście do pakietu będzie działało poprawnie (patrz edytowane pytanie).
toupeira
Widzę! Byłoby wspaniale, gdybyś mógł odpowiedzieć na własne pytanie (za pomocą przycisku poniżej) i powiedzieć nam, co zrobiłeś lub jak rozwiązałeś problem. Może opublikuj kilka przykładów w swoim pytaniu, a następnie po prostu dodaj krótką odpowiedź. W ten sposób, jeśli ktoś natknie się na twój post, może się czegoś z tego nauczyć!
slhck
Cóż, nadal nie mam odpowiedzi na rzeczywiste pytanie (tj. Jak całkowicie uniknąć terminalu, bez konieczności używania opakowania .app), więc wolę pozostawić otwarte, aby ktoś mógł mnie oświecić.
toupeira
1
Wciąż jestem zdezorientowany. Ty nie chcesz uruchamiać je za pomocą .app stworzonej przez Automator?
slhck

Odpowiedzi:

21

Otwórz Automator , wybierz opcję Aplikacja , dodaj akcję Uruchom skrypt powłoki i wstaw polecenie Shell między cudzysłowami (jeśli masz plik, możesz go po prostu przeciągnąć i upuścić).

Oprócz grania, teraz możesz go zapisać (jako aplikację w dowolnym miejscu), a nawet ustawić ikonę .

Cregox
źródło
Próbowałem uruchomić polecenie w ten sposób z aplikacji pełnoekranowej, ale zawsze otwierało się to w tle. Musiałem w tle wykonać polecenie w powłoce w sposób nieblokujący, dodając a, &a następnie wywołałem AppleScript, aby przenieść aplikację (w moim przypadku mplayer) na przód: mplayer myvideo.avi &; osascript -e 'tell application "System Events" to set frontmost of the first process whose displayed name is "mplayer" to true'
Lenar Hoyt
Cool hack @mcb. Ale nie rozumiem dlaczego. Zwykle chcemy ukryć okno terminala, ponieważ otworzy ono inne okno, które jest główne. Jeśli potrzebujesz pierwszego okna terminala mplayera, przypuszczam, że nie otwiera ono kolejnego, więc dlaczego miałbyś chcieć to ukryć?
cregox,
Używam mplayerdo odtwarzania wideo z pokazu slajdów (w Skim). Jest błąd, że odtwarzacz pozostaje w tle, jeśli Skim jest ustawiony na pełny ekran, nie jestem jednak pewien, czy ten błąd dotyczy tylko Skim lub wszystkich aplikacji pełnoekranowych, więc pomyślałem, że opublikuję tutaj moje rozwiązanie.
Lenar Hoyt
6

Oto szybki i nieprzyzwoity przykład bez żadnego wysiłku (dla aplikacji o nazwie „myapp”):

  1. Utwórz częściową hierarchię aplikacji:

        mkdir -p ./myapp.app/Contents/MacOS
    
  2. Upewnij się, że pierwszy wiersz skryptu zawiera pełną ścieżkę do potrzebnego programu, np.

    #!/bin/bash
    
  3. Nazwij swój skrypt powłoki „myapp” (bez cudzysłowów, bez rozszerzenia), nadaj mu uprawnienia do wykonywania, a następnie umieść go w podkatalogu MacOS. Aby nadać mu uprawnienia do wykonywania:

    chmod ugo+x myapp
    
  4. Przejdź do podkatalogu Contents i utwórz plik PkgInfo zawierający ciąg: APPL ???? [brak terminatora linii na końcu łańcucha!] Użyj narzędzia cat (1), aby utworzyć plik:

    cat > PkgInfo
    APPL????
    

    Po wpisaniu łańcucha (nie wciskaj return!), Wprowadź dwa control-D, które zamkną
    plik bez terminatora linii i powrócą do zachęty powłoki.)

  5. Kliknij dwukrotnie nową „aplikację” w wyszukiwarce. Będzie działać bez okna.

JeffB
źródło
Nie działa w wersji 10.13.6, komunikat o błędzie mówi „Nie można otworzyć aplikacji„ LoginSessionTimeLimit.app ”, ponieważ nie jest obsługiwana na tego typu komputerach Mac.”
Douglas odbył się
1
Pracował dla mnie w Mojave (10.14.3). Podobało mi się to podejście. Dzięki.
loco.loop
Pracował dla mnie 10.13.6. @Douglas Held spróbuj uruchomić skrypt „ręcznie”, tj. Z poziomu terminala. Prawdopodobnie wychodzi z błędem, dlatego nie działa dla ciebie ...
marekful
Świetny! Testowany podczas pracy w Mojave 10.14.6
Nicola Mingotti,
4

Warto sprawdzić Platypus , który tworzy aplikacje Mac OS X ze skryptów powłoki i innych interpretowanych skryptów.

svth
źródło
3

Oto małe obejście na wypadek, gdybyś miał ochotę uruchomić programy uruchamiające takie jak Alfred . Używam go codziennie i kupiłem Powerpack , który pozwala na uruchamianie cichych skryptów powłoki.

wprowadź opis zdjęcia tutaj

Nie będą one otwierać terminala podczas działania i mogą być powiązane z dowolną sekwencją słów kluczowych. Mogą nawet zawierać parametry i mieć dodatkowe opcje:

wprowadź opis zdjęcia tutaj

Używam tego do niektórych małych fragmentów i jest bardzo elastyczny.

slhck
źródło
To nie jest już dostępne w Alfred 2. Zamiast tego utwórz „Uruchom skrypt”, jak pokazano na rysunku .
Dave Newton
1

Jeśli dodasz klucz LSUIElementi ustawisz go 1w Info.plistswojej aplikacji, nie utworzy on ikony w Docku.

Oto Info.plistmoja mała aplikacja skryptowa do powłoki:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleExecutable</key>
    <string>launch</string>
    <key>CFBundleIconFile</key>
    <string>launch</string>
    <key>LSUIElement</key>
    <string>1</string>
</dict>
</plist>
Tig
źródło
Dzięki, ale to nie wydaje się mieć efektu. Próbowałem także touchzainstalować pakiet, aby upewnić się, że użyto najnowszej wersji. Ale tak naprawdę nie podoba mi się podejście pakietowe, ponieważ wydaje się, że zawsze będzie tworzyć osobne instancje aplikacji
toupeira
Dla mnie dotyk też nie pomógł (próbowałem wyłączyć LSUIElement), istnieje inne buforowanie, ale pomogło kompresowanie i rozpakowywanie aplikacji. Dlaczego nie lubisz podejścia pakietowego? Możesz także użyć AppleScript i po prostu uruchomić do shell script "say 'arsti'", to nie otworzy okna terminalu.
tig
Okay, okazuje się, że jestem tylko idiotą ;-) Nie mogłem znaleźć niezawodnego sposobu na sprawdzenie, czy aplikacja działa już z AppleScript, więc użyłem normalnego skryptu bash, który wywołuje pgrep, a następnie przekazuje odpowiedni kod bezpośrednio do osascript(interpreter AppleScript). Problem polega na tym, że pgreppochodzi od Homebrew i nie jest ustawiony domyślnie $PATH. Tak więc mój skrypt zawsze uruchamiał nową instancję iTerm, nawet jeśli już działała. Po dodaniu pełnej ścieżki do pgrepskryptu podejście pakietowe wydaje się w końcu działać dobrze, więc myślę, że na razie jestem szczęśliwy ;-)
toupeira
Łącząc tę ​​odpowiedź z powyższą z @JeffB oraz z uproszczoną wersją Info.plist @ tig (usunąłem klawisze CFBundleExecutablei CFBundleIconFile), udało mi się to doskonale.
Dave Land
0

Oto trochę obejścia:

Skompiluj applecript, który wywołuje skrypt powłoki :)

osacompile -e 'do shell script "cd ~; echo aaa > temp.txt"' -o ~/name_of_script.scpt

osacompileSkompiluje 'do shell script "XXX"'AppleScript fragment. Twój skrypt powłoki to XXX.

Uważaj na cytowanie, skrypt powłoki musi być cytowany poprawnie, aby ominąć powłokę, której używasz do kompilacji.

Ale można to uruchomić z BetterTouchTool bez żadnej bzdury.

Kenny
źródło
0

Istnieje inny możliwy trening. Bezpieczny skrypt powłoki w przepływie pracy automatyzatora. Wywołaj przepływ pracy z uruchomionym. Kod to:

/usr/bin/automator /path/to/the/file.workflow

Nie uruchomi to żadnego programu ani nie pojawi się na pasku menu, a jego działanie jest cichsze niż aplikacja Platypus.

Jeszcze lepszy sposób wykonywania skryptów powłoki jest uruchamiany bezpośrednio.

/bin/bash /path/to/shellScript.command

wykona polecenie bardzo cicho w tle.

Atalantia
źródło