Chạy script shell trên OS X mà không có cửa sổ terminal xuất hiện?


23

Tôi đang cố gắng thiết lập một vài phím tắt để mở các phiên iTerm cụ thể, điều mà tôi có thể làm với BetterTouchTool và một chút phép thuật AppleScript. Vấn đề là OS X khăng khăng mở cửa sổ Terminal cho bất kỳ tập lệnh shell nào mà bạn thực thi thông qua GUI (tức là từ Finder hoặc dưới dạng phím tắt từ BetterTouchTool). Cửa sổ terminal không xuất hiện nếu tôi chạy script trực tiếp từ terminal khác.

Một cách giải quyết mà tôi tìm thấy là bọc tập lệnh trong thư mục .app, giải quyết vấn đề của cửa sổ đầu cuối thừa, nhưng có một số vấn đề khác (ví dụ OS X dường như coi mỗi cửa sổ iTerm là một ứng dụng riêng biệt, làm lộn xộn dock của tôi ). (EDIT: hành vi này thực sự gây ra bởi một lỗi trong tập lệnh của tôi, xem bên dưới)

Tôi cũng đã thử gán ứng dụng Terminal cho một máy tính để bàn ảo khác trong cài đặt Spaces để cố gắng di chuyển nó ra khỏi tầm nhìn, nhưng sau đó nó sẽ chỉ chuyển sang máy tính để bàn đó trước khi chạy tập lệnh.

Có cách nào để vô hiệu hóa hoàn toàn hành vi này? Tôi đã tìm thấy cài đặt trong tùy chọn Terminal để đóng cửa sổ sau khi tập lệnh kết thúc, nhưng vẫn khó chịu khi cửa sổ Terminal bật lên trong một giây.


Xin lỗi, tôi không hiểu lắm. Bạn muốn làm gì với các kịch bản shell? Bạn có muốn mở iTerm mặc dù một kịch bản shell? Bạn đang nói riêng về Terminal.app hay trộn iTerm với "Terminal" trong câu hỏi của bạn? Bạn có thể đăng một ví dụ về những gì bạn đang cố gắng chạy?
slhck

Tôi đã thiết lập một số phiên iTerm để khởi chạy shell thông thường, mở bảng điều khiển Rails, hiển thị nhật ký Rails, v.v. Tôi đang sử dụng iTerm và Terminal được OS X tự động mở vì bất kỳ lý do ngớ ngẩn nào. Nhưng dù sao, tôi đã tìm thấy một giải pháp để làm cho cách tiếp cận bó hoạt động đúng (xem câu hỏi được chỉnh sửa).
toupeira

Tôi hiểu rồi! Chà, thật tuyệt vời nếu bạn có thể trả lời câu hỏi của chính mình (sử dụng nút bên dưới) và cho chúng tôi biết bạn đã làm gì, hoặc bạn đã giải quyết vấn đề như thế nào. Có thể đăng một số ví dụ trong câu hỏi của bạn, và sau đó chỉ cần thêm một câu trả lời ngắn gọn. Bằng cách này, nếu ai đó tình cờ thấy bài đăng của bạn, họ có thể học được điều gì đó từ nó!
slhck

Chà, tôi vẫn chưa có câu trả lời cho câu hỏi thực tế (nghĩa là làm thế nào để tránh Terminal hoàn toàn, mà không phải sử dụng trình bao bọc .app), vì vậy tôi muốn để nó mở trong trường hợp ai đó có thể khai sáng cho tôi.
toupeira

1
Tôi vẫn còn bối rối. Bạn không muốn chạy chúng thông qua .app được tạo bởi Automator?
slhck

Câu trả lời:


21

Mở Automator , chọn Ứng dụng , thêm hành động Run Shell Scriptđặt lệnh Shell giữa các dấu ngoặc kép (nếu bạn có tệp, bạn chỉ cần kéo và thả tệp).

Khác với việc chơi nó, bây giờ bạn có thể lưu nó (dưới dạng một ứng dụng ở bất cứ đâu) và thậm chí đặt biểu tượng .


Tôi đã cố chạy một lệnh theo cách này từ một ứng dụng toàn màn hình, tuy nhiên nó luôn mở nó ở chế độ nền. Tôi đã phải làm nền lệnh trong shell theo kiểu không chặn bằng cách nối thêm &và sau đó gọi AppleScript để đưa ứng dụng (trong trường hợp của tôi mplayer) ra phía trước: 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 20/1/2015

Tuyệt vời hack @mcb. Nhưng tôi không hiểu tại sao. Thông thường chúng ta muốn ẩn cửa sổ terminal vì nó sẽ mở một cửa sổ khác, đây là cửa sổ chính. Nếu bạn cần cửa sổ đầu cuối đầu tiên của mplayer, tôi cho rằng nó không mở một cửa sổ khác và vậy tại sao bạn lại muốn ẩn nó ở nơi đầu tiên?
cregox

Tôi đang sử dụng mplayerđể phát video từ trong trình chiếu (trong Skim). Có một lỗi mà người chơi vẫn ở trong nền nếu Skim được đặt ở chế độ toàn màn hình, tuy nhiên tôi không chắc chắn, liệu lỗi này chỉ liên quan đến Skim hay tất cả các ứng dụng toàn màn hình, vì vậy tôi đoán rằng tôi sẽ đăng giải pháp của mình ở đây.
Lenar Hoyt

6

Đây là một ví dụ nhanh và bẩn mà hầu như không cần nỗ lực (đối với một ứng dụng có tên "myapp"):

  1. Tạo một hệ thống phân cấp ứng dụng một phần:

        mkdir -p ./myapp.app/Contents/MacOS
    
  2. Đảm bảo dòng đầu tiên của tập lệnh của bạn có đường dẫn đầy đủ đến chương trình cần thiết, ví dụ:

    #!/bin/bash
    
  3. Đặt tên cho tập lệnh shell của bạn là "myapp" (không có dấu ngoặc kép, không có phần mở rộng), cấp cho nó quyền thực thi và sau đó đặt nó vào thư mục con MacOS. Để cung cấp cho nó quyền thực thi:

    chmod ugo+x myapp
    
  4. Chuyển đến thư mục con Nội dung và tạo tệp PkgInfo có chứa chuỗi: ỨNG DỤNG ???? [không có dấu kết thúc dòng ở cuối chuỗi!] Sử dụng tiện ích cat (1) để tạo tệp:

    cat > PkgInfo
    APPL????
    

    Sau khi bạn đã nhập chuỗi (không nhấn return!), Nhập hai control-D, sẽ đóng
    tệp không có dấu kết thúc dòng và đưa bạn trở lại dấu nhắc shell.)

  5. Nhấp đúp vào "ứng dụng" mới của bạn từ công cụ tìm. Nó sẽ chạy mà không có cửa sổ.


Không hoạt động vào ngày 10.13.6, thông báo lỗi cho biết "Bạn không thể mở ứng dụng.
Douglas Held

1
Đã làm việc trong Mojave (10.14.3) cho tôi. Tôi thực sự thích phương pháp này. Cảm ơn.
loco.loop

Làm việc cho tôi vào ngày 10.13.6. @Doumund Held thử chạy tập lệnh của bạn "thủ công", tức là từ Terminal. Có lẽ nó đã thoát w / error do đó nó không hoạt động với bạn ...
marekful

Tuyệt quá! Đã thử nghiệm làm việc trong Mojave 10.14.6
Nicola Mingotti

4

Bạn có thể muốn kiểm tra Platypus , công cụ tạo ứng dụng Mac OS X từ các tập lệnh shell và các tập lệnh diễn giải khác.


3

Đây là một cách giải quyết nhỏ, trong trường hợp bạn có các trình khởi chạy ứng dụng ưa thích như Alfred . Tôi sử dụng nó mỗi ngày và tôi đã mua Powerpack , cho phép bạn chạy các tập lệnh shell im lặng.

nhập mô tả hình ảnh ở đây

Chúng sẽ không mở terminal khi chạy và có thể bị ràng buộc với bất kỳ chuỗi từ khóa nào. Chúng thậm chí có thể bao gồm các tham số và có các tùy chọn bổ sung:

nhập mô tả hình ảnh ở đây

Tôi sử dụng nó cho một số đoạn nhỏ và nó rất linh hoạt.


Điều này không còn có sẵn trong Alfred 2. Thay vào đó, hãy tạo một "Run Script" như trong hình .
Dave Newton

1

Nếu bạn thêm khóa LSUIElementvà đặt nó vào 1trong Info.plistứng dụng của mình, nó sẽ không tạo biểu tượng trong Dock.

Đây là Info.plistứng dụng kịch bản shell nhỏ của tôi:

<?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>

Cảm ơn, nhưng điều này dường như không có tác dụng. Tôi cũng đã thử touching gói để đảm bảo phiên bản mới nhất đã được sử dụng. Nhưng dù sao, tôi không thực sự thích cách tiếp cận gói vì dường như nó sẽ luôn tạo các trường hợp ứng dụng riêng biệt
toupeira

Đối với tôi, cảm ứng cũng không giúp được gì (tôi đã cố gắng tắt LSUIE bổ sung), có một số loại bộ nhớ đệm khác, nhưng ứng dụng nén và giải nén đã giúp ích. Tại sao bạn không thích cách tiếp cận bó? Ngoài ra, bạn có thể sử dụng applescript và chỉ cần chạy do shell script "say 'arsti'", điều này sẽ không mở cửa sổ terminal.
tig

Được rồi, hóa ra tôi chỉ là một thằng ngốc ;-) Tôi không thể tìm thấy một cách đáng tin cậy để kiểm tra xem một ứng dụng đã chạy với AppleScript hay chưa, vì vậy tôi đã sử dụng một tập lệnh bash bình thường để gọi pgrepvà sau đó chuyển trực tiếp mã có liên quan đến osascript(trình thông dịch AppleScript). Vấn đề là pgrepxuất phát từ Homebrew và không có trong mặc định $PATH. Vì vậy, tập lệnh của tôi luôn khởi chạy một phiên bản iTerm mới, ngay cả khi nó đã chạy. Sau khi thêm đường dẫn đầy đủ pgrepvào kịch bản, cách tiếp cận bó dường như vẫn hoạt động tốt, vì vậy tôi nghĩ bây giờ tôi rất vui ;-)
toupeira

Kết hợp câu trả lời này với câu trả lời từ @JeffB ở trên và với phiên bản đơn giản của @ tig's Info.plist (Tôi đã xóa các phím CFBundleExecutableCFBundleIconFile), tôi đã làm cho nó hoạt động hoàn hảo.
Dave Land

0

Đây là một chút giải pháp:

Biên dịch một applescript gọi một kịch bản shell :)

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

Các osacompilesẽ biên dịch các 'do shell script "XXX"'đoạn mã AppleScript. Kịch bản shell của bạn là XXX.

Xem ra để trích dẫn, kịch bản shell phải được trích dẫn chính xác để vượt qua trình bao bạn đang sử dụng để biên dịch nó vẫn còn nguyên vẹn.

Nhưng điều này có thể được chạy từ BetterTouchTool mà không có bất kỳ sự phiền toái nào.


0

Có một tập luyện khác có thể. An toàn tập lệnh shell của bạn trong quy trình tự động hóa. Gọi quy trình làm việc với launchd. Mã này là:

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

Điều này sẽ không khởi chạy bất kỳ chương trình nào cũng như không hiển thị trên thanh menu và cách im lặng hơn là ứng dụng Platypus.

Một cách thậm chí tốt hơn để thực thi các kịch bản shell là trực tiếp trong launchd.

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

sẽ thực hiện lệnh cực kỳ âm thầm trong nền.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.