Wie erstelle ich eine OSX-Anwendung, um einen Aufruf eines Shell-Skripts zu beenden?

10

Mein Ziel ist es, in eine Zip-Datei eine Verknüpfung aufzunehmen, anstatt meinen Kunden zu sagen, dass sie Terminal öffnen und ein Shell-Skript ausführen sollen.

Mein Deployable sieht im Wesentlichen so aus:

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

Skript in run.sh:

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

Es gibt noch viel mehr im Verzeichnis; Es reicht zu sagen, dass ich das Skript aus dem Verzeichnis Deliverable ausführen muss, da ich auf Pfade relativ dazu zugreifen muss. Ich kann jedoch nicht garantieren, wo ein Kunde öffnen wird Deliverable.zip(könnte das Ausgangsverzeichnis sein, könnte sich direkt im Download-Verzeichnis befinden usw.)

Ich habe dies gefunden , das beschreibt, wie ein neuer Workflow in Automator erstellt und dann als Anwendung gespeichert wird, um ein Shell-Skript zu starten. Ich habe versucht, das zu wickeln, run.shaber es heißt, es kann nicht finden run.sh.

Jemand schlug vor, dass ich Applescript verwende, und schickte mir auch einen Link zur Verwendung von Applescript, um in das aktuelle Verzeichnis zu wechseln. Es gibt eine Applescript "Aktion" im Automator; Also habe ich damit einen neuen Workflow erstellt und ihn als Anwendung gespeichert. So sieht das aus:

das Automator-Applescript-Programm

Der 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

Und das ist der Fehler, den ich bekomme, wenn ich es ausführe:

Willkommen im Jahr 2015

Komm schon, das sollte ziemlich einfach sein. Was mache ich hier falsch?

leeres Set
quelle
Nun, ich habe gerade ein Update mit einem einfacheren Applescript gepostet, aber ich wurde mit einer Antwort geschlagen, die von grgarside für Sie besser funktionieren sollte. :-)
Markhunte
Der Titel dieser Frage entspricht nicht der eigentlichen Frage, daher habe ich abgestimmt. Die Frage ist enger gefasst: Es geht darum, ein Problem mit der Fehlermeldung "PowerPC-Anwendungen werden nicht mehr unterstützt" zu beheben. Dies sollte im Fragentitel enthalten sein. Ich suche tatsächlich nach der Antwort, wie man ein Anwendungspaket erstellt. Das OP weiß, wie ein Bundle erstellt wird, es ist jedoch ein Fehler aufgetreten.
Jason

Antworten:

4

Benennen Sie Ihre .sh-Datei in .command um, und Sie können in das Verzeichnis wechseln, in dem sich die .command-Datei befindet. Am Anfang der Datei steht Folgendes:

cd "$(dirname $BASH_SOURCE)"
grg
quelle
7

Ich kann dort ein paar Dinge falsch sehen.

Zunächst haben Sie einen Workflow und keine Anwendung geöffnet.

Sie sollten Anwendung auswählen, wenn Sie Ihre Auswahl für den Typ der Automator-Datei treffen.

Geben Sie hier die Bildbeschreibung ein

Und der Code, den Sie haben, funktioniert nicht wie erwartet, da Sie das Verzeichnis nicht geändert haben. (CD).

In dem Code, wie Sie ihn haben, wird lediglich der Pfad als Alias abgerufen und in der Variablen current_path und in einem für die Unix-Befehle ungeeigneten Format gespeichert.

Aber du benutzt es nicht.

Das aktuelle Verzeichnis ist also höchstwahrscheinlich Ihr Home-Ordner

Zu diesem Zeitpunkt ist nicht abzusehen, was gestartet werden soll.

Wenn ich es so laufen lasse, wie du es hast, bekomme ich es.

Geben Sie hier die Bildbeschreibung ein

Was Sinn macht, da ich kein Java installiert habe. Aber wenn ich das tun würde, würde ich nicht erwarten, dass es die richtige Datei findet.

Das Applescript muss so aussehen.

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 

In meinem Beispiel

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

Ich cd zum POSIX-Pfad des Alias ​​in der Variablen current_path

dh von "alias" Macintosh HD: Anwendungen: "" bis "/ Anwendungen /"

Der quoted form of entkommt dem Pfad mit Anführungszeichen.

Ich habe den Befehl / bin / ls verwendet und ihn als Demonstration hier zum Öffnen in TextEdit stdin weitergeleitet , damit Sie testen können, ob Sie den erwarteten Bereich erreichen.

Sie würden so etwas wie verwenden;

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

aktualisieren:

Eine andere Möglichkeit ist die Verwendung von reinem 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
markhunte
quelle
Dies kommt einer Lösung sehr nahe; Ich bestätige, dass der ls | openCode definitiv das gewünschte Verzeichnis öffnet, was großartig ist. Aber wenn ich open anrufe Client.app, erhalte ich: LSOpenURLsWithRole() failed with error -10665 for the file <path-to-Client.app> - Einige Suchanfragen nach dem, was dieser Fehler bedeutet, deuteten auf ein Berechtigungsproblem hin. Ich habe es überprüft und +xFlags gesetzt. Ich habe auch versucht dies , und das hat nicht funktioniert (mit dem gleichen Fehler).
Emptyset
Beachten Sie, dass das Öffnen Client.appüber den Finder (Doppelklick) auch zu demselben PowerPC-Fehler-Popup führt.
Emptyset
@emptyset I call open Client.appIst dies die Automator-App ? Soweit ich im Automator verstehe, haben Sie den Applescript-Code : do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\"". Wo verwenden Sie den openBefehl? Soweit ich verstehe, was Sie tun, müssen Sie es nicht verwenden. Die Clients verwenden einen Doppelklick auf die App und die App führt die Java
Markhunte
Ich habe es in beide Richtungen getestet: über die Befehlszeile: $ open Client.appund durch Doppelklick. Ihre Version mit Aufruf ls | open -fefunktioniert, aber wenn ich sie ändere java -jar app.jar, wird mir dieser Fehler angezeigt.
Emptyset
@emptyset versuchendo shell script "cd " & quoted form of (POSIX path of current_path) & " ; " & quoted form of "java -jar app.jar"
markhunte
6

Pfad zum Skript

In Ihrem AppleScript müssen Sie das aktuelle Arbeitsverzeichnis (cwd) ändern, bevor Sie den Java-Befehl ausgeben. Tun Sie dies mit einer AppleScript-Zeile wie:

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

Das &&ist wichtig. Wenn dies cderfolgreich ist, wird der javaBefehl im rechten cwd gestartet . Wenn dies cdfehlschlägt, wird der javaBefehl nicht ausgeführt.

Zu den Problemen, auf die Sie wahrscheinlich stoßen werden, gehören:

  • Entkommen aus dem POSIX-Pfad, an den übergeben wurde cd; Benutzer haben seltsam benannte Ordner und Leerzeichen in ihren Pfaden.
  • das cdkann scheitern; Packen Sie Ihr AppleScript in einen Try- Block, um einige Fehler abzufangen und den Benutzer zu warnen.

Perl

Persönlich würde ich ein kurzes Perl-Skript anstelle eines Bash-Skripts verwenden.

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

Es gibt viel bessere Möglichkeiten, dieses Perl-Snippet zu schreiben, aber das sollte funktionieren.

Automator-Anwendung

Der beste Ansatz besteht darin, die Probleme mit Ihrem Automator-Ansatz zu lösen. In der Antwort von @ markhunte wird erläutert, wie der Pfad festgelegt und eine Anwendung erstellt wird . Dies sollte Sie den größten Teil des Weges bringen.

Siehe auch AppleScript-Pfad relativ zum Speicherort des Skripts .

appify - Erstellen Sie die einfachste Mac-App aus einem Shell-Skript

Alternativ können Sie das Appify-Skript von Thomas Aylott verwenden, um Ihr Shell-Skript in einer OS X-Anwendung zu bündeln. In Mathias Bynens Artikel erfahren Sie, wie Sie das Skript verwenden und einfache Mac-Apps aus Shell-Skripten erstellen .

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

Von der Community beigesteuerte Verbesserungen an diesem Skript sind verfügbar:

Codesignatur

Sobald Sie Ihr Anwendungspaket erstellt haben, sollte es mit einem Code signiert sein. Eine mit Code signierte App wird gestartet, ohne dass Ihre Clients Gatekeeper deaktivieren müssen.

Signieren Sie Ihre Anwendung mit Ihrer Apple Developer ID und dem folgenden codesignBefehl:

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

Die Codesignatur ist eine Sicherheitstechnologie, die in OS X verwendet wird und mit der Sie bestätigen können, dass eine App von Ihnen erstellt wurde. Sobald eine App signiert ist, kann das System jede Änderung an der App erkennen - unabhängig davon, ob die Änderung versehentlich oder durch bösartigen Code eingeführt wurde.

Erfahren Sie mehr über die Codesignatur auf der Apple Developer Website.

Graham Miln
quelle
Vielen Dank für den Tipp zur Codesignatur. Ich schaue mir das jetzt an und teste das Appify-Skript!
Emptyset
Appify-Skript hat nicht funktioniert; Problem mit dem gleichen Pfad
Emptyset
@emptyset Ich habe einen Pfad und einen Perl-Abschnitt hinzugefügt. Es kann sich auch lohnen, das Pfadproblem in eine neue Frage zu unterteilen. Wenn Sie das beheben können, können Sie Automator oder das Appify-Skript verwenden.
Graham Miln
4

Können Sie ändern , run.shum run.commandden Benutzer zu doppelklicken Sie es und bekommen?

forquare
quelle
Das hat fast funktioniert! Die Datei wurde jedoch aus dem Kontext des Home-Verzeichnisses ( cd ~) des Benutzers ausgeführt , wodurch sie fehlschlug.
Emptyset
1
@emptyset Verwenden Sie $ BASH_SOURCE, siehe apple.stackexchange.com/a/201482
grg
4

Verwenden Sie Platypus : "Platypus ist ein OS X-Entwicklertool, das native Mac-Anwendungen aus interpretierten Skripten erstellt ..."

Platypus ist ein OS X-Entwicklertool, das native Mac-Anwendungen aus interpretierten Skripten erstellt

perfectcu.be
quelle
1

Hier ist meine Sicht auf das, was ich verstanden habe, was Sie erreichen wollen. Der Code ist absichtlich langwierig.

Sie müssen lediglich den Code in den Applescript-Editor kopieren, die gewünschten Änderungen vornehmen und ihn als Anwendung speichern.

Was den Dialog über die nicht unterstützte PowerPC-Anwendung betrifft, weiß ich nicht. Können Sie es über die Befehlszeile ausführen? Ich würde das überprüfen, um zu bestätigen, dass die App zuerst funktioniert.

#
# 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
Vic
quelle