Comment créer une application OSX pour encapsuler un appel à un script shell?


10

Mon objectif est d'inclure dans un fichier zip ce qui équivaut à un raccourci, au lieu de dire à mes clients d'ouvrir Terminal et d'exécuter un script shell.

Mon déployable ressemble essentiellement à ceci:

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

Script dans run.sh:

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

Il y a beaucoup plus dans le répertoire; il suffit de dire que j'ai besoin d'exécuter le script à partir du répertoire Livrable car j'ai besoin d'accéder aux chemins qui s'y rapportent. Cependant, je ne peux pas garantir où un client va ouvrir Deliverable.zip(peut être le répertoire personnel, peut être directement dans le répertoire Téléchargements, etc.)

J'ai trouvé cela qui décrit comment créer un nouveau flux de travail dans Automator, puis l'enregistrer en tant qu'application pour lancer un script shell. J'ai essayé de faire ça pour envelopper run.shmais il dit qu'il ne peut pas trouver run.sh.

Quelqu'un m'a suggéré d'utiliser applescript et m'a également envoyé un lien expliquant comment utiliser applescript pour basculer dans le répertoire courant; il y a une "action" AppleScript dans l'automate; J'ai donc créé un nouveau workflow avec cela et l'ai enregistré en tant qu'application. Voilà à quoi ça ressemble:

le programme automatisé applescript

Le code:

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

Et voici l'erreur que j'obtiens lorsque je l'exécute:

bienvenue en 2015

Allez, ça devrait être assez simple. Qu'est-ce que je fais mal ici?


Eh bien, je viens de publier une mise à jour avec un script applescript plus simple, mais voyez que j'ai été battu au poing avec une réponse qui devrait mieux fonctionner pour vous par grgarside. :-)
markhunte

Le titre de cette question ne représente pas la question réelle, j'ai donc voté contre. La question est plus étroite: il s'agit de résoudre un problème avec le message d'erreur "Les applications PowerPC ne sont plus prises en charge" et c'est ce qui devrait être dans le titre de la question. Je cherche en fait la réponse à la façon de créer un bundle d'applications. L'OP sait comment créer un bundle mais a rencontré une erreur.
Jason

Réponses:


4

Renommez votre fichier .sh en .command et vous pouvez cd dans le répertoire dans lequel se trouve le fichier .command avec ce qui suit au début du fichier:

cd "$(dirname $BASH_SOURCE)"

7

Je peux voir deux ou trois choses qui ne vont pas.

Tout d'abord, vous avez ouvert un workflow et non une application.

Vous devez choisir Application lorsque vous effectuez votre sélection pour le type de fichier Automator.

entrez la description de l'image ici

Et le code que vous avez ne fonctionnera pas comme prévu, puisque vous n'avez pas changé de répertoire. (CD).

Dans le code tel que vous l'avez, tout ce qu'il fait, c'est obtenir le chemin en tant qu'alias et le stocker dans la variable current_path et dans un format qui ne convient pas aux commandes unix.

Mais vous ne l'utilisez pas.

Le répertoire actuel sera donc probablement votre dossier personnel

À ce stade, on ne sait pas ce qu'il essaie de lancer.

Si je l'exécute comme vous l'avez, je reçois.

entrez la description de l'image ici

Ce qui est logique puisque je n'ai pas installé Java. Mais si je le faisais, je ne m'attendrais pas à ce qu'il trouve le bon fichier.

L'Applescript doit ressembler à ceci.

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 

Dans mon exemple

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

Je passe au chemin POSIX de l'alias dans la variable current_path

c'est-à-dire de "alias" Macintosh HD: Applications: "" à "/ Applications /"

Le quoted form of s'échappe du chemin à l'aide de guillemets.

J'ai utilisé la commande / bin / ls et l' ai dirigée vers l' ouverture dans TextEdit stdin comme démonstration ici afin que vous puissiez tester pour voir si vous arrivez dans la zone que vous attendez.

Vous utiliseriez quelque chose comme;

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

mettre à jour:

Une autre façon consiste simplement à utiliser Applescript pur.

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

C'est très proche d'une solution; Je confirme que le ls | opencode ouvre définitivement le répertoire que je veux, ce qui est génial. Mais lorsque j'appelle open Client.app, j'obtiens: LSOpenURLsWithRole() failed with error -10665 for the file <path-to-Client.app> - quelques recherches sur la signification de cette erreur suggèrent un problème d'autorisation, je vérifie et les +xindicateurs sont définis. J'ai également essayé ceci , et cela n'a pas fonctionné (avec la même erreur).
emptyset

Notez que l'ouverture à Client.apppartir du Finder (double-clic) entraîne également la même fenêtre contextuelle d'erreur PowerPC.
emptyset

@emptyset I call open Client.appEst-ce l'application Automator? D'après ce que je comprends dans le Automator vous avez le code AppleScript: do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\"". Alors, où utilisez-vous la opencommande? pour autant que je sache ce que vous faites, vous n'avez pas besoin de l'utiliser. Les clients utiliseront un double-clic sur l'application et l'application exécutera java
markhunte

Je l'ai testé dans les deux sens: à partir de la ligne de commande: $ open Client.appet en double-cliquant. Votre version avec invocation ls | open -fefonctionne, mais quand je la change, cela java -jar app.jarme donne cette erreur.
emptyset

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

6

Chemin vers le script

Dans votre AppleScript, vous devez modifier le répertoire de travail actuel (cwd) avant d'émettre la commande java. Faites-le avec une ligne AppleScript comme:

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

C'est &&important. Si le cdsuccès, la javacommande sera lancée dans le cwd droit . En cas d' cdéchec, la javacommande ne sera pas exécutée.

Les problèmes que vous rencontrerez probablement incluent:

  • échapper au chemin POSIX passé à cd; les utilisateurs auront des dossiers et des espaces aux noms étranges sur leur chemin.
  • le cdpeut échouer; envelopper votre AppleScript dans un bloc d' essai pour détecter certaines erreurs et avertir l'utilisateur.

perl

Personnellement, je préfère utiliser un script perl court à la place d'un 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`;

Il existe de bien meilleures façons d'écrire cet extrait de code Perl, mais cela devrait fonctionner.

Application Automator

La meilleure approche consiste à résoudre les problèmes liés à votre approche Automator. La réponse de @ markhunte explique comment corriger le chemin d'accès et créer une application . Cela devrait vous aider la plupart du temps.

Voir également le chemin AppleScript relatif à l'emplacement du script .

appify - créez l'application Mac la plus simple possible à partir d'un script shell

Alternativement, vous pouvez utiliser le script appify de Thomas Aylott pour regrouper votre script shell dans une application OS X. L'article de Mathias Bynen explique comment utiliser le script, comment créer de simples applications Mac à partir de scripts 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"

Des améliorations apportées par la communauté à ce script sont disponibles:

Signature du code

Une fois que vous avez créé votre ensemble d'applications, il doit être signé par code. Une application signée par code se lancera sans que vos clients ne désactivent Gatekeeper.

Codez votre application à l'aide de votre identifiant de développeur Apple et de la codesigncommande:

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

La signature de code est une technologie de sécurité, utilisée dans OS X, qui vous permet de certifier qu'une application a été créée par vous. Une fois qu'une application est signée, le système peut détecter toute modification de l'application, que la modification soit introduite accidentellement ou par un code malveillant.

En savoir plus sur la signature de code sur le site des développeurs Apple.


Merci pour le conseil sur la signature de code; Je regarde cela maintenant et je teste le script appify!
emptyset

le script appify n'a pas fonctionné; même problème de chemin
emptyset

@emptyset J'ai ajouté une section path et perl. Il peut également être utile de séparer le problème du chemin d'accès en une nouvelle question. Si vous pouvez résoudre ce problème, vous pouvez utiliser Automator ou le script appify.
Graham Miln


4

Pouvez - vous changer run.shpour run.commandet obtenir l'utilisateur double - cliquez dessus?


Cela a presque fonctionné! Cependant, il a exécuté le fichier à partir du contexte du répertoire personnel de l'utilisateur ( cd ~), ce qui a provoqué son échec.
emptyset

1
@emptyset Use $ BASH_SOURCE, see apple.stackexchange.com/a/201482
grg

1

Voici mon point de vue sur ce que j'ai compris que vous essayez d'accomplir. Le code est exprès depuis longtemps.

Il vous suffit de copier le code dans l'éditeur Applescript, d'apporter les modifications souhaitées et de l'enregistrer en tant qu'application.

Quant à la boîte de dialogue sur l'application PowerPC non prise en charge, je ne sais pas. Pouvez-vous l'exécuter à partir de la ligne de commande? Je vérifierais cela pour confirmer que l'application fonctionne en premier.

#
# 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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.