Come creare un'applicazione OSX per avvolgere una chiamata a uno script di shell?


10

Il mio obiettivo è quello di includere in un file zip ciò che equivale a un collegamento, invece di dire ai miei clienti di aprire Terminal ed eseguire uno script di shell.

Il mio schierabile si presenta essenzialmente come questo:

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

Script in run.sh:

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

C'è molto di più nella directory; basti dire che devo eseguire lo script dalla directory Deliverable poiché ho bisogno di accedere ai percorsi relativi ad esso. Tuttavia, non posso garantire dove verrà aperto un cliente Deliverable.zip(potrebbe essere la home directory, potrebbe essere proprio nella directory dei download, ecc.)

Ho trovato questo che descrive come creare un nuovo flusso di lavoro in Automator, quindi salvarlo come un'applicazione per avviare uno script di shell. Ho provato a farlo per concludere run.shma dice che non riesce a trovarlo run.sh.

Qualcuno mi ha suggerito di usare applecript e mi ha anche inviato un link su come usare applecript per passare alla directory corrente; c'è un '"azione" applecript nell'automatore; così ho creato un nuovo flusso di lavoro e l'ho salvato come un'applicazione. Ecco come appare:

il programma di automazione di applecript

Il codice:

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

E questo è l'errore che ottengo quando lo eseguo:

benvenuti nel 2015

Dai, dovrebbe essere abbastanza semplice. Cosa sto facendo di sbagliato qui?


Beh, ho appena pubblicato un aggiornamento con un semplice script di mele, ma vedi che sono stato battuto fino al pugno con una risposta che dovrebbe funzionare meglio per te da grgarside. :-)
markhunte,

Il titolo di questa domanda non rappresenta la vera domanda, quindi ho votato verso il basso. La domanda è più ristretta: si tratta di risolvere un problema con il messaggio di errore "Le applicazioni PowerPC non sono più supportate" e questo è ciò che dovrebbe essere nel titolo della domanda. In realtà sto cercando la risposta a come creare un pacchetto di applicazioni. L'OP sa come creare un pacchetto ma ha riscontrato un errore.
Jason,

Risposte:


4

Rinomina il tuo file .sh in .command e puoi cd nella directory in cui si trova il file .command con quanto segue all'inizio del file:

cd "$(dirname $BASH_SOURCE)"

7

Riesco a vedere un paio di cose sbagliate lì.

Innanzitutto hai aperto un flusso di lavoro e non un'applicazione.

È necessario scegliere Applicazione quando si effettua la selezione per il tipo di file di Automator.

inserisci qui la descrizione dell'immagine

E il codice che hai non funzionerà come previsto, dal momento che non hai cambiato directory. (CD).

Nel codice come lo hai, tutto ciò che sta facendo è ottenere il percorso come alias e memorizzarlo nella variabile current_path e in un formato non adatto ai comandi unix.

Ma non lo usi.

Quindi la directory corrente sarà molto probabilmente la tua cartella home

In questa fase non si può dire cosa stia cercando di lanciare.

Se lo eseguo come hai, ottengo.

inserisci qui la descrizione dell'immagine

Il che ha senso poiché non ho Java installato. Ma se lo facessi non mi aspetto che trovi il file giusto.

L'Applescript deve apparire così.

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 

Nel mio esempio

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

Ho cd nel percorso POSIX dell'alias nella variabile current_path

cioè da "alias" Macintosh HD: Applicazioni: "" a "/ Applicazioni /"

La quoted form of sfugge il percorso utilizzando le virgolette.

Ho usato il comando / bin / ls e lo instrada all'aperto in TextEdit stdin come una dimostrazione qui in modo da poter provare per vedere se stai arrivando nell'area che ti aspetti.

Useresti qualcosa del genere;

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

aggiornare:

Un altro modo è usare puro Applescript.

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

Questo è molto vicino a una soluzione; Confermo che il ls | opencodice apre definitivamente la directory che desidero, il che è fantastico. Ma quando chiamo aperto Client.app, ottengo: LSOpenURLsWithRole() failed with error -10665 for the file <path-to-Client.app> - alcune ricerche sul significato di questo errore hanno suggerito un problema di autorizzazione, ho controllato e i +xflag sono impostati. Ho anche provato questo e quello non ha funzionato (con lo stesso errore).
emptyset

Si noti che l'apertura Client.appdal Finder (doppio clic) comporta anche lo stesso pop-up di errore PowerPC.
emptyset

@emptyset I call open Client.appÈ questa l'app Automator. Da quello che ho capito in Automator si dispone il codice AppleScript: do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\"". Quindi dove stai usando il opencomando? che per quanto ho capito cosa stai facendo, non hai bisogno di usarlo. I client useranno il doppio clic sull'app e l'app eseguirà java
markhunte il

L'ho provato in entrambi i modi: dalla riga di comando: $ open Client.appe facendo doppio clic. La tua versione con invocazione ls | open -fefunziona, ma quando la cambio a java -jar app.jarmi dà quell'errore.
emptyset

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

6

Path to Script

In AppleScript, è necessario modificare la directory di lavoro corrente (cwd) prima di eseguire il comando java. Fallo con una linea AppleScript come:

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

Il &&è importante. Se l'operazione ha esitocd positivo, il javacomando verrà avviato nel CWD corretto . Se cdfallisce, il javacomando non verrà eseguito.

I problemi che probabilmente incontrerai includono:

  • sfuggire al percorso POSIX passato a cd; gli utenti avranno cartelle e spazi con nomi strani nei loro percorsi.
  • il cdpuò fallire; avvolgi AppleScript in un blocco try per rilevare alcuni errori e avvisare l'utente.

perl

Personalmente, vorrei usare un breve script perl al posto di uno script bash.

#!/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`;

Esistono modi migliori per scrivere questo frammento di perl, ma questo dovrebbe funzionare.

Applicazione automatore

L'approccio migliore è quello di risolvere i problemi con l'approccio Automator. La risposta di @ markhunte illustra come correggere il percorso e creare un'applicazione . Questo dovrebbe prenderti la maggior parte del modo.

Vedi anche il percorso AppleScript relativo alla posizione dello script .

appify: crea l'app per Mac più semplice possibile da uno script di shell

In alternativa, è possibile utilizzare lo script appify di Thomas Aylott per raggruppare lo script shell in un'applicazione OS X. L'articolo di Mathias Bynen spiega come utilizzare lo script e come creare semplici app per Mac da script di shell .

#!/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"

Sono disponibili miglioramenti apportati dalla community a questo script:

Firma del codice

Dopo aver creato il pacchetto dell'applicazione, dovrebbe essere firmato il codice. Verrà avviata un'app con codice firmato senza che i client disabilitino Gatekeeper.

Firma il codice della tua applicazione utilizzando l' ID sviluppatore Apple e il codesigncomando:

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

La firma del codice è una tecnologia di sicurezza, utilizzata in OS X, che ti consente di certificare che un'app è stata creata da te. Una volta firmata un'app, il sistema è in grado di rilevare qualsiasi modifica all'app, indipendentemente dal fatto che la modifica sia stata introdotta accidentalmente o da un codice dannoso.

Ulteriori informazioni sulla firma del codice sul sito per sviluppatori Apple.


Grazie per il suggerimento sulla firma del codice; Lo sto esaminando ora e sto testando lo script Appify!
emptyset

lo script appify non ha funzionato; problema con lo stesso percorso
vuoto

@emptyset Ho aggiunto un percorso e una sezione perl. Potrebbe anche valere la pena separare il problema del percorso in una nuova domanda. Se riesci a risolverlo, puoi usare Automator o lo script Appify.
Graham Miln,



1

Ecco la mia opinione su ciò che ho capito che stai cercando di realizzare. Il codice è a lungo appiccicato di proposito.

Tutto quello che devi fare è copiare il codice nell'editor di Applescript, apportare le modifiche desiderate e salvarlo come applicazione.

Per quanto riguarda la finestra di dialogo sull'applicazione PowerPC non supportata, non lo so. Puoi eseguirlo dalla riga di comando? Verificherei che per confermare l'app funzioni prima.

#
# 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.