Kabuk betiğine bir çağrıyı sarmak için OSX Uygulaması nasıl oluşturulur?


10

Amacım, müşterime / müşterilere Terminal'i açmasını ve bir kabuk komut dosyası çalıştırmasını bildirmek yerine, bir kısayolun ne anlama geldiğini bir zip dosyasına eklemektir.

Benim konuşlandırılabilirim aslında şöyle görünüyor:

$ unzip Deliverable.zip 
$ cd Deliverable; ls
app.jar run.sh

Komut dosyası run.sh:

#!/bin/sh
java -jar app.jar

Dizinde çok daha fazlası var; Ben bunu göreli yollara erişmek gerekir çünkü Teslim edilebilir dizinden komut dosyasını çalıştırmak gerekir söylemek yeterli . Ancak, bir müşterinin nerede açılacağını garanti edemiyorum Deliverable.zip(ana dizin olabilir, doğrudan İndirilenler dizininde olabilir, vb.)

Bulduğum bu daha sonra, Automator'ın yeni iş akışı oluşturmak bir kabuk başlatmak için bir uygulama olarak kaydetmek için nasıl açıklayan. Bunu sarmak için yapmaya çalıştım run.shama bulamadığını söylüyor run.sh.

Birisi el yazısını kullanmamı önerdi ve bana şu anki dizine geçmek için el yazısını nasıl kullanacağımı gösteren bir bağlantı gönderdi; automator'da bir el yazısı "eylemi" var; bu yüzden yeni bir iş akışı yaptım ve bunu bir uygulama olarak kaydettim. Şöyle görünüyor:

automator elma programı

Kod:

on run {input, parameters}
    tell application "Finder"
        set current_path to container of (path to me) as alias
    end tell

    do shell script "java -jar app.jar" 

    return input
end run

Ve bu, çalıştırdığımda aldığım hata:

2015'e hoş geldiniz

Hadi, bu oldukça basit olmalı. Burada neyi yanlış yapıyorum?


Daha basit bir el yazısı ile güncelleme yayınladım, ancak grgarside tarafından sizin için daha iyi çalışması gereken bir cevapla yumrukya dövüldüğümü görüyorum. :-)
markhunte

Bu sorunun başlığı gerçek soruyu temsil etmiyor, bu yüzden oy kullandım. Soru daha dardır: "PowerPC uygulamaları artık desteklenmiyor" hata mesajıyla ilgili bir sorunu çözmekle ilgilidir ve soru başlığında olması gereken budur. Aslında nasıl bir uygulama paketi oluşturmak için bir cevap arıyorum. OP bir paketin nasıl oluşturulacağını biliyor ancak bir hatayla karşılaştı.
Jason

Yanıtlar:


4

.Sh dosyanızı .command olarak yeniden adlandırın ve .command dosyasının bulunduğu dizine aşağıdaki dosyanın başlangıcında cd yapabilirsiniz:

cd "$(dirname $BASH_SOURCE)"

7

Orada birkaç şey yanlış görebiliyorum.

Öncelikle bir Uygulama değil, bir iş akışı açtınız.

Automator dosya türü için seçiminizi yaparken Uygulama'yı seçmelisiniz.

resim açıklamasını buraya girin

Ve dizini değiştirmediğiniz için sahip olduğunuz kod beklediğiniz gibi çalışmaz. (CD).

Sahip olduğunuz kodda, tek yaptığı yolu bir takma ad olarak almak ve onu current_path değişkeninde ve unix komutları için uygun olmayan bir biçimde saklamaktır .

Ama siz kullanmıyorsunuz.

Geçerli dizin büyük olasılıkla ana klasörünüz olacaktır

Bu aşamada ne başlatmaya çalıştığını söylemek mümkün değildir.

Eğer senin gibi koşarsam alırım.

resim açıklamasını buraya girin

Java yüklü olmadığından mantıklı. Ama yapsaydım doğru dosyayı bulmasını beklemezdim.

Applescript böyle görünmelidir.

on run {input, parameters}
    tell application "Finder"
        set current_path to container of (path to me) as alias
    end tell

    do shell script "cd " & quoted form of (POSIX path of current_path) & " ;ls | open -fe"

    return input
end run 

Örneğimde

do shell script "cd " & quoted form of (POSIX path of current_path) & " ;/bin/ls | /usr/bin/open -fe"

Current_path değişkenindeki diğer adın POSIX yoluna cd

örn. "takma ad" dan Macintosh HD: Uygulamalar: "" ila "/ Uygulamalar /"

quoted form of Tırnak kullanarak yolunu kaçar.

Ben kullandım / bin / ls komutunu ve boru bunu TextEdit Stdin'den açık burada böylece beklediğiniz alanı almadan olup olmadığını görmek için test edebilirsiniz bir göstergesi olarak.

Şöyle bir şey kullanırsınız;

do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\""

Güncelleme:

Başka bir yol sadece saf Applescript kullanmaktır.

on run {input, parameters}
    tell application "Finder"
        set current_path to container of (path to me)

        set theFile to (current_path) as alias

        open file "java -jar app.jar" of theFile
    end tell


end run

Bu bir çözüme çok yakın; ls | openKodun kesinlikle istediğim dizini açtığını onaylıyorum , bu harika. Ama açık Client.apparadığımda, şunu alıyorum: LSOpenURLsWithRole() failed with error -10665 for the file <path-to-Client.app> - Bu hatanın ne anlama geldiğini birkaç arama izin sorunu önerdi , kontrol ettim ve +xbayraklar ayarlandı. Ben de denedim bu ve bu (aynı hata ile) çalışma yoktu.
emptyset

Client.appFinder'dan açmanın (çift tıklama) aynı PowerPC hatası pop-up'ına neden olduğunu unutmayın.
emptyset

@emptyset I call open Client.appBu Automator uygulaması mı? Ben otomatikçisi anlamak kadarıyla sen applescript kod var: do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\"". Peki openkomutu nerede kullanıyorsunuz ? ne yaptığınızı anladığım kadarıyla onu kullanmanıza gerek yok. Müşteriler app çift tıklama kullanacak ve uygulama java çalışacak
markhunte

Her iki şekilde de test ettim: komut satırından: $ open Client.appve çift tıklatarak. Çağırma sürümünüz ls | open -feçalışıyor, ancak bunu değiştirdiğimde java -jar app.jarbana bu hatayı veriyor.
emptyset

@emptyset deneyindo shell script "cd " & quoted form of (POSIX path of current_path) & " ; " & quoted form of "java -jar app.jar"
markhunte

6

Komut Dosyasının Yolu

AppleScript'inizde, java komutunu vermeden önce geçerli çalışma dizinini (cwd) değiştirmeniz gerekir . Bunu aşağıdaki gibi bir AppleScript satırıyla yapın:

do shell script "cd " & quoted form of (POSIX path of file_path) & " && java -jar app.jar"

Bu &&önemlidir. cdBaşarılı olursa, javakomut sağ cwd içinde başlatılır . Eğer cdbaşarısız javakomut çalıştırmak edilmeyecektir.

Muhtemelen karşılaşacağınız sorunlar:

  • kaçan POSIX yolundan cd; kullanıcıların yollarında garip bir şekilde adlandırılmış klasörler ve boşluklar bulunur.
  • cdbaşarısız olabilir; bazı hataları yakalamak ve kullanıcıyı uyarmak için AppleScript'inizi bir try bloğuna sarın .

perl

Şahsen, bash betiği yerine kısa bir perl betiği kullanmak istiyorum.

#!/usr/bin/env perl

use strict;
use warnings;
use FindBin qw($Bin); # $Bin is a path to the script's parent folder

`cd "$Bin" && java -jar app.jar`;

Bu perl snippet'ini yazmanın çok daha iyi yolları var, ancak bu işe yaramalı.

Automator Uygulaması

En iyi yaklaşım, Automator yaklaşımınızla ilgili problemleri çözmektir. @ markhunte'un cevabı , yolun nasıl düzeltileceğini ve bir uygulamanın nasıl oluşturulacağını tartışır . Bu sizi en çok zorlamalıdır.

Ayrıca komut dosyası konumuna göre AppleScript yoluna bakın .

appify - kabuk komut dosyasından mümkün olan en basit Mac uygulamasını oluşturun

Alternatif olarak, kabuk komut dosyanızı bir OS X uygulamasında paketlemek için Thomas Aylott'un appify komut dosyasını kullanabilirsiniz. Mathias Bynen'in makalesi, komut dosyasının nasıl kullanılacağını, kabuk komut dosyalarından basit Mac uygulamalarının nasıl oluşturulacağını açıklar .

#!/bin/bash

if [ "$1" = "-h" -o "$1" = "--help" -o -z "$1" ]; then cat <<EOF
appify v3.0.1 for Mac OS X - http://mths.be/appify
Creates the simplest possible Mac app from a shell script.
Appify takes a shell script as its first argument:
    `basename "$0"` my-script.sh
Note that you cannot rename appified apps. If you want to give your app
a custom name, use the second argument:
    `basename "$0"` my-script.sh "My App"
Copyright (c) Thomas Aylott <http://subtlegradient.com/>
Modified by Mathias Bynens <http://mathiasbynens.be/>
EOF
exit; fi

APPNAME=${2:-$(basename "$1" ".sh")}
DIR="$APPNAME.app/Contents/MacOS"

if [ -a "$APPNAME.app" ]; then
    echo "$PWD/$APPNAME.app already exists :("
    exit 1
fi

mkdir -p "$DIR"
cp "$1" "$DIR/$APPNAME"
chmod +x "$DIR/$APPNAME"

echo "$PWD/$APPNAME.app"

Bu komut dosyasında topluluk tarafından sağlanan iyileştirmeler kullanılabilir:

Kod İmzalama

Uygulama paketinizi oluşturduktan sonra, kod imzalı olmalıdır . Kod imzalı bir uygulama, müşterilerinizin Gatekeeper'ı devre dışı bırakmasına gerek kalmadan başlatılır.

Apple Geliştirici Kimliğinizi ve codesignkomutunu kullanarak uygulamanızı kodla imzalayın :

codesign -s <identity> -v <code-path> 

Kod imzalama, OS X'te kullanılan ve bir uygulamanın sizin tarafınızdan oluşturulduğunu onaylamanızı sağlayan bir güvenlik teknolojisidir. Bir uygulama imzalandıktan sonra sistem, ister yanlışlıkla ister kötü amaçlı kodla başlatılır, uygulamada yapılan değişiklikleri algılayabilir.

Apple Developer sitesinde kod imzalama hakkında daha fazla bilgi edinin .


Kod imzalamadaki ipucu için teşekkürler; Ben şimdi içine bakmak ve appify script test!
emptyset

appify betiği çalışmadı; aynı yol sorunu
emptyset

@ emptyset Bir yol ve perl bölümü ekledim. Yol sorununu yeni bir soruya ayırmak da faydalı olabilir. Bunu düzeltebilirseniz, Automator veya appify komut dosyasını kullanabilirsiniz.
Graham Miln


4

Değiştirmek Can run.shiçin run.commandve çift tıklama o kullanıcıyı olsun?


Neredeyse işe yaradı! Ancak, dosyayı kullanıcının ana dizininin ( cd ~) bağlamından çalıştırdı ve bu da başarısız olmasına neden oldu.
emptyset

1
@emptyset $ BASH_SOURCE kullanın, bkz. apple.stackexchange.com/a/201482
grg

1

İşte başarmaya çalıştığınızı anladığım şeyi ele almam. Kod bilerek uzun süre sarılmıştır.

Tek yapmanız gereken kodu Applescript Editor'a kopyalamak, istediğiniz değişiklikleri yapmak ve bir uygulama olarak kaydetmek.

PowerPC uygulamasıyla ilgili iletişim kutusu desteklenmiyorsa, bilmiyorum. Komut satırından çalıştırabilir misiniz? Uygulamanın önce çalıştığını onaylamak için bunu kontrol ederim.

#
# STEP 1: locate and confirm zip file exists
#
#   This is long winded on purpose. It is meant to save the user some scrolling and 
#   and a click... Isn't this what computers are for to save time? :)
#

# Zip file name 
set zipname to "Deliverable.zip"

# Locate the zip file
set zippath to POSIX path of (choose folder)
log zippath
set qzippath to quoted form of zippath
log qzippath
set zipfile to (zippath & zipname)
set qzipfile to quoted form of (zippath & zipname)
log qzipfile

# Check for the file... Use either test not both :)
try
    # using shell test - case sensetive
    do shell script "test -f " & qzipfile

    # using native test - doesn't like quoted forms and case insensetive...
    POSIX file zipfile as alias
on error
    display dialog "ERROR: Zip file was not found at selected folder." as text ¬
        buttons {"OK"} with icon caution ¬
        with title "Alert"
    return
end try


#
# STEP 2: Zip found. Unzip it
#
try
    # Add " -d Deliverable" at the end to force directory  
    # unzip -o to force overwrite for testing....
    do shell script "cd " & qzippath & "; unzip -o " & zipname
on error eStr
    display dialog "ERROR: Failed to unzip file. Message returned was, " & ¬
        return & return & eStr as text ¬
        buttons {"OK"} with icon caution ¬
        with title "Unzip Error"
    return
end try


#
# STEP 3: Run script 
#
set dpath to (zippath & "Deliverable/")
log dpath
set qdpath to quoted form of dpath
log qdpath
try
    do shell script "cd " & qdpath & ";  sh ./run.sh"
on error eStr
    display dialog "ERROR: Failed to launch script. Message returned was, " & ¬
        return & return & eStr as text ¬
        buttons {"OK"} with icon caution ¬
        with title "Deliverable Script Launch"
    return
end try
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.