Jalankan skrip shell pada OS X tanpa jendela terminal muncul?

23

Saya mencoba menyiapkan beberapa pintasan keyboard yang membuka sesi khusus ITerm, yang dapat saya lakukan dengan BetterTouchTool dan sedikit sihir AppleScript. Masalahnya adalah bahwa OS X bersikeras untuk membuka jendela Terminal untuk skrip shell yang Anda jalankan melalui GUI (yaitu dari Finder, atau sebagai pintasan keyboard dari BetterTouchTool). Jendela terminal tidak muncul jika saya menjalankan skrip langsung dari terminal lain.

Solusi yang saya temukan adalah untuk membungkus skrip dalam direktori .app, yang memecahkan masalah jendela terminal yang berlebihan, tetapi memiliki beberapa masalah lain (misalnya OS X tampaknya memperlakukan setiap jendela iTerm yang dihasilkan sebagai aplikasi terpisah, mengacaukan dock saya. ). (EDIT: perilaku ini sebenarnya disebabkan oleh bug di skrip saya, lihat di bawah)

Saya juga mencoba menetapkan aplikasi Terminal ke desktop virtual lain di pengaturan Spaces dalam upaya untuk memindahkannya dari pandangan, tetapi kemudian hanya akan beralih ke desktop itu sebelum menjalankan skrip.

Apakah ada cara untuk menonaktifkan perilaku ini sepenuhnya? Saya sudah menemukan pengaturan di preferensi Terminal untuk menutup jendela setelah skrip selesai, tetapi masih menjengkelkan untuk memiliki jendela Terminal muncul sebentar.

toupeira
sumber
Maaf, saya tidak begitu mengerti. Apa yang ingin Anda lakukan dengan skrip shell itu? Apakah Anda ingin membuka iTerm melalui skrip shell? Apakah Anda secara eksklusif berbicara tentang Terminal.app atau mencampur iTerm dengan "Terminal" di pertanyaan Anda? Bisakah Anda memposting contoh apa yang Anda coba jalankan?
slhck
Saya telah menyiapkan beberapa sesi iTerm untuk meluncurkan shell normal, membuka konsol Rails, menampilkan log Rails dll. Saya menggunakan iTerm secara eksklusif, dan Terminal dibuka secara otomatis oleh OS X untuk alasan konyol apa pun. Tapi bagaimanapun, saya menemukan solusi untuk membuat pendekatan bundel berfungsi dengan baik (lihat pertanyaan yang diedit).
toupeira
Saya melihat! Ya, akan luar biasa jika Anda bisa menjawab pertanyaan Anda sendiri (menggunakan tombol di bawah) dan memberi tahu kami apa yang Anda lakukan, atau bagaimana Anda memecahkan masalah tersebut. Mungkin memposting beberapa contoh dalam pertanyaan Anda, dan kemudian tambahkan saja jawaban singkat. Dengan cara ini, jika seseorang menemukan pos Anda, mereka mungkin belajar sesuatu darinya!
slhck
Yah saya masih belum punya jawaban untuk pertanyaan yang sebenarnya (yaitu bagaimana menghindari Terminal sepenuhnya, tanpa harus menggunakan .app wrapper), jadi saya lebih suka membiarkannya terbuka jika seseorang dapat mencerahkan saya.
toupeira
1
Saya masih bingung. Anda tidak ingin menjalankannya melalui .app yang dibuat oleh Automator?
slhck

Jawaban:

21

Buka Automator , pilih Aplikasi , tambahkan tindakan Run Shell Script dan masukkan perintah Shell Anda di antara tanda kutip (jika Anda memiliki file, Anda bisa seret dan jatuhkan).

Selain memainkannya, sekarang Anda dapat menyimpannya (sebagai aplikasi di mana saja) dan bahkan mengatur ikon .

cregox
sumber
Saya mencoba menjalankan perintah dengan cara ini dari aplikasi layar penuh, namun selalu membukanya di latar belakang. Saya harus latar belakang perintah di shell dengan cara non-blocking dengan menambahkan &dan kemudian memanggil AppleScript untuk membawa aplikasi (dalam kasus saya mplayer) ke depan: 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
Retas keren @mcb. Tapi saya tidak mengerti mengapa. Biasanya kami ingin menyembunyikan jendela terminal karena akan membuka jendela lain, yang merupakan jendela utama. Jika Anda memerlukan jendela terminal pertama mplayer, saya kira itu tidak membuka yang lain dan jadi mengapa Anda ingin menyembunyikannya?
cregox
Saya menggunakan mplayeruntuk memutar video dari tayangan slide (dalam Skim). Ada bug yang disimpan pemain di latar belakang jika Skim diatur ke layar penuh, saya tidak yakin, apakah bug ini hanya terkait dengan Skim atau semua aplikasi layar penuh, jadi saya pikir saya akan memposting solusi saya di sini.
Lenar Hoyt
6

Berikut ini adalah contoh cepat dan kotor dengan hampir tanpa usaha (untuk aplikasi bernama "myapp"):

  1. Buat hierarki aplikasi parsial:

        mkdir -p ./myapp.app/Contents/MacOS
    
  2. Pastikan baris pertama skrip Anda memiliki jalur lengkap ke program yang dibutuhkan, misalnya,

    #!/bin/bash
    
  3. Beri nama skrip shell Anda "myapp" (tanpa tanda kutip, tidak ada ekstensi), berikan izin eksekusi, dan kemudian masukkan ke dalam sub-direktori MacOS. Untuk memberikannya jalankan izin:

    chmod ugo+x myapp
    
  4. Buka sub-direktori Isi dan buat file PkgInfo yang berisi string: APPL ???? [tanpa terminator garis di akhir string!] Gunakan utilitas cat (1) untuk membuat file:

    cat > PkgInfo
    APPL????
    

    Setelah Anda mengetikkan string (jangan tekan return!), Masukkan dua control-D, yang akan menutup
    file tanpa terminator baris dan mengembalikan Anda ke prompt shell.)

  5. Klik dua kali "aplikasi" baru Anda dari finder. Ini akan berjalan tanpa jendela.

JeffB
sumber
Tidak berfungsi pada 10.13.6, pesan kesalahan mengatakan "Anda tidak dapat membuka aplikasi" LoginSessionTimeLimit.app "karena tidak didukung pada Mac jenis ini."
Douglas Diadakan
1
Apakah bekerja di Mojave (10.14.3) untuk saya. Saya sangat menyukai pendekatan ini. Terima kasih.
loco.loop
Bekerja untuk saya pada 10.13.6. @Douglas Dimiliki coba jalankan skrip Anda "secara manual", yaitu dari Terminal. Mungkin itu keluar dengan kesalahan maka itu tidak bekerja untuk Anda ...
Marekful
Bagus! Diuji bekerja di Mojave 10.14.6
Nicola Mingotti
4

Anda mungkin ingin memeriksa Platypus , yang membuat aplikasi Mac OS X dari skrip shell dan skrip yang diartikan lainnya.

svth
sumber
3

Ini solusi kecil, jika Anda suka peluncur aplikasi seperti Alfred . Saya menggunakannya setiap hari, dan saya telah membeli Powerpack , yang memungkinkan Anda untuk menjalankan skrip shell diam.

masukkan deskripsi gambar di sini

Ini tidak akan membuka terminal saat dijalankan dan dapat terikat ke urutan kata kunci apa pun. Mereka bahkan dapat memasukkan parameter, dan memiliki opsi tambahan:

masukkan deskripsi gambar di sini

Saya menggunakan ini untuk beberapa cuplikan kecil, dan sangat fleksibel.

slhck
sumber
Ini tidak lagi tersedia di bawah Alfred 2. Sebagai gantinya, buat "Run Script" seperti yang ditunjukkan pada gambar .
Dave Newton
1

Jika Anda menambahkan kunci LSUIElementdan mengaturnya 1di Info.plistaplikasi Anda, itu tidak akan membuat ikon di Dock.

Ini adalah Info.plistaplikasi skrip shell kecil saya:

<?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>
cekcok
sumber
Terima kasih, tetapi ini sepertinya tidak berpengaruh. Saya juga mencoba touchbundel untuk memastikan versi terbaru digunakan. Tapi bagaimanapun, saya tidak terlalu suka pendekatan bundel karena sepertinya itu akan selalu membuat contoh aplikasi yang terpisah
toupeira
Bagi saya sentuh tidak membantu juga (saya mencoba mematikan LSUIElement), ada beberapa jenis caching lainnya, tetapi mengompresi dan mengekstraksi aplikasi membantu. Mengapa Anda tidak menyukai pendekatan bundel? Anda juga dapat menggunakan applescript dan jalankan do shell script "say 'arsti'", ini tidak akan membuka jendela terminal.
tig
Oke, ternyata saya hanya idiot ;-) Saya tidak bisa menemukan cara yang dapat diandalkan untuk memeriksa apakah aplikasi sudah berjalan dengan AppleScript, jadi saya menggunakan skrip bash normal yang memanggil pgrep, dan kemudian meneruskan kode yang relevan langsung ke osascript(juru bahasa AppleScript). Masalahnya adalah itu pgrepdatang dari Homebrew, dan tidak ada di default $PATH. Jadi skrip saya selalu meluncurkan instance iTerm baru, bahkan jika sudah berjalan. Setelah menambahkan path lengkap ke pgrepdalam script pendekatan bundle tampaknya berfungsi dengan baik setelah semua, jadi saya pikir saya senang untuk saat ini ;-)
toupeira
Menggabungkan jawaban ini dengan yang ada di @JeffB di atas, dan dengan versi sederhana dari @ tig's Info.plist (saya menghapus tombol CFBundleExecutabledan CFBundleIconFile), saya membuat ini berfungsi dengan sempurna.
Dave Land
0

Berikut sedikit solusinya:

Kompilasi applescript yang memanggil shell script :)

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

The osacompileakan mengkompilasi 'do shell script "XXX"'potongan applescript. Script shell Anda adalah XXX.

Berhati-hatilah untuk mengutip, skrip shell harus dikutip dengan benar untuk melewati shell yang Anda gunakan untuk mengompilasinya masih utuh.

Tapi ini bisa dijalankan dari BetterTouchTool tanpa rasa ingin tahu.

kenny
sumber
0

Ada kemungkinan latihan lain. Amankan skrip shell Anda dalam alur kerja automator. Aktifkan alur kerja dengan launchd. Kode tersebut adalah:

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

Ini tidak akan meluncurkan program apa pun atau muncul di bilah menu dan caranya lebih hening daripada aplikasi Platypus.

Cara yang lebih baik untuk mengeksekusi skrip shell adalah langsung di launchd.

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

akan menjalankan perintah dengan sangat diam-diam di latar belakang.

Atalantia
sumber