Wie erstelle ich eine OSX-Anwendung, um einen Aufruf in ein Shell-Skript einzubinden?

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 genügt 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 Home-Verzeichnis sein, könnte sich direkt im Download-Verzeichnis befinden usw.)

Ich habe dies gefunden , das beschreibt, wie man einen neuen Workflow in Automator erstellt und ihn dann als Anwendung speichert, um ein Shell-Skript zu starten. Ich habe versucht, das zu tun, run.shaber es sagt, dass es nicht gefunden werden kann run.sh.

Jemand schlug vor, Applescript zu verwenden, 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?

Nun, ich habe gerade ein Update mit einem einfacheren Applescript gepostet, aber sehen Sie, ich wurde mit einer Antwort, die für Sie von grgarside besser funktionieren sollte, geschlagen. :-)
Der Titel dieser Frage stellt nicht die eigentliche Frage dar, daher habe ich abgelehnt. Die Frage ist enger gefasst: Es geht um die Lösung eines Problems mit der Fehlermeldung „PowerPC-Anwendungen werden nicht mehr unterstützt“, und das sollte im Titel der Frage stehen. Ich suche eigentlich nach der Antwort, wie man ein Anwendungspaket erstellt. Das OP weiß, wie ein Bündel erstellt wird, ist jedoch auf einen Fehler gestoßen.

Antworten (6)

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

cd "$(dirname $BASH_SOURCE)"

Da sehe ich ein paar Dinge falsch.

Erstens 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, wird nicht wie erwartet funktionieren, 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 Sie verwenden es nicht.

Das aktuelle Verzeichnis wird also höchstwahrscheinlich Ihr Home-Ordner sein

In diesem Stadium ist nicht abzusehen, was es zu starten versucht.

Wenn ich es so führe, wie Sie es haben, bekomme ich es.

Geben Sie hier die Bildbeschreibung ein

Was sinnvoll ist, da ich kein Java installiert habe. Aber wenn ich es täte, 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:Applications:"" zu "/Applications/"

Der quoted form ofmaskiert den Pfad mit Anführungszeichen.

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

Sie würden so etwas verwenden wie;

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

aktualisieren:

Eine andere Möglichkeit ist, einfach reines Applescript zu verwenden.

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
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, bekomme ich: LSOpenURLsWithRole() failed with error -10665 for the file <path-to-Client.app>- ein paar Suchen nach dem, was dieser Fehler bedeutet , deuteten auf ein Berechtigungsproblem hin, ich habe es überprüft und +xFlags sind gesetzt. Ich habe dies auch versucht , und das hat nicht funktioniert (mit demselben Fehler).
Beachten Sie, dass das Öffnen Client.appaus dem Finder (Doppelklick) ebenfalls zu demselben PowerPC-Fehler-Popup führt.
@emptyset I call open Client.appIst das die Automator-App. Soweit ich weiß, haben Sie im Automator den Applescript-Code: do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\"". Wo verwendest du also den openBefehl? Was Sie, soweit ich verstehe, was Sie tun, nicht verwenden müssen. Die Clients verwenden einen Doppelklick auf die App und die App führt die Java
Ich habe es auf beide Arten getestet: von der Befehlszeile: $ open Client.appund durch Doppelklicken. Ihre Version mit dem Aufrufen ls | open -fefunktioniert, aber wenn ich sie ändere java -jar app.jar, wird mir dieser Fehler angezeigt.
@emptyset versuchendo shell script "cd " & quoted form of (POSIX path of current_path) & " ; " & quoted form of "java -jar app.jar"

Pfad zum Skript

In Ihrem AppleScript müssen Sie das aktuelle Arbeitsverzeichnis (cwd) ändern, bevor Sie den Java-Befehl ausführen. 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 innerhalb der rechten cwd gestartet . Wenn cddies fehlschlägt, wird der javaBefehl nicht ausgeführt.

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

  • Escapezeichen für den POSIX-Pfad, der an übergeben wurde cd; Benutzer haben seltsam benannte Ordner und Bereiche in ihren Pfaden.
  • das cdkann scheitern; Verpacken Sie Ihr AppleScript in einem try -Block, um einige Fehler abzufangen und den Benutzer zu warnen.

Perl

Persönlich würde ich anstelle eines Bash-Skripts ein kurzes Perl-Skript 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 ist, die Probleme mit Ihrem Automator-Ansatz zu lösen. In der Antwort von @markhunte wird erläutert, wie der Pfad korrigiert und eine Anwendung erstellt wird . Dies sollte Sie am meisten erreichen.

Siehe auch AppleScript-Pfad relativ zum Skriptspeicherort .

appify – Erstellen Sie die einfachstmögliche Mac-App aus einem Shell-Skript

Alternativ können Sie das Appify-Skript von Thomas Aylot verwenden , um Ihr Shell-Skript in eine OS X-Anwendung zu bündeln. Der Artikel von Mathias Bynen erklärt, wie man das Skript verwendet, wie man einfache Mac-Apps aus Shell-Skripten erstellt .

#!/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 eingebrachte Verbesserungen an diesem Skript sind verfügbar:

Code-Signatur

Nachdem Sie Ihr Anwendungspaket erstellt haben, sollte es codesigniert werden. Eine Code-signierte App wird gestartet, ohne dass Ihre Clients Gatekeeper deaktivieren müssen.

Signieren Sie Ihre Anwendung mit Ihrer Apple-Entwickler-ID und dem codesignfolgenden Befehl:

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

Code Signing ist eine in OS X verwendete Sicherheitstechnologie, 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 Code Signing auf der Apple Developer Website.

Danke für den Tipp zum Code-Signing; Ich schaue mir das jetzt an und teste das Appify-Skript!
Appify-Skript funktionierte nicht; Problem mit dem gleichen Pfad
@emptyset Ich habe einen Pfad und einen Perl-Abschnitt hinzugefügt. Es kann sich auch lohnen, das Pfadproblem in eine neue Frage auszugliedern. Wenn Sie das beheben können, können Sie Automator oder das Appify-Skript verwenden.

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

Können Sie run.shzu wechseln run.commandund den Benutzer dazu bringen, darauf zu doppelklicken?

Das hat fast funktioniert! Die Datei wurde jedoch im Kontext des Home-Verzeichnisses des Benutzers ( cd ~) ausgeführt, was zu einem Fehlschlagen führte.
@emptyset Verwenden Sie $BASH_SOURCE, siehe apple.stackexchange.com/a/201482

Hier ist meine Meinung zu dem, was Sie zu erreichen versuchen. Der Code ist absichtlich langatmig.

Alles, was Sie tun müssen, ist, den Code in den Applescript-Editor zu kopieren, alle gewünschten Änderungen vorzunehmen und ihn als Anwendung zu speichern.

Was den Dialog über die nicht unterstützte PowerPC-Anwendung angeht, weiß ich es nicht. Kannst du es über die Kommandozeile ausführen? Ich würde das zuerst überprüfen, um zu bestätigen, dass die App 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