¿Cómo crear una aplicación OSX para ajustar una llamada a un script de shell?

10

Mi objetivo es incluir en un archivo zip lo que equivale a un acceso directo, en lugar de decirles a mis clientes que abran Terminal y ejecuten un script de shell.

Mi despliegue esencialmente se ve así:

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

Guión en run.sh:

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

Hay mucho más en el directorio; basta con decir que necesito ejecutar el script desde el directorio Entregable ya que necesito acceder a las rutas relativas a él. Sin embargo, no puedo garantizar dónde se abrirá un cliente Deliverable.zip(podría ser el directorio de inicio, podría estar justo en el directorio de Descargas, etc.)

Encontré esto que describe cómo crear un nuevo flujo de trabajo en Automator, luego guardarlo como una aplicación para iniciar un script de shell. Traté de hacer eso para envolver run.shpero dice que no puede encontrar run.sh.

Alguien sugirió que usara AppleScript y también me envió un enlace sobre cómo usar Applecript para cambiar al directorio actual; hay una "acción" de applecript en el automatizador; así que hice un nuevo flujo de trabajo con eso y lo guardé como una aplicación. Así es como se ve:

el programa automatizador de applecript

El código:

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

Y este es el error que obtengo cuando lo ejecuto:

bienvenido a 2015

Vamos, esto debería ser bastante simple. ¿Qué estoy haciendo mal aquí?

conjunto vacio
fuente
Bueno, acabo de publicar una actualización con un applecript más simple, pero veo que me golpearon con una respuesta que debería funcionar mejor para ti por grgarside. :-)
markhunte
El título de esta pregunta no representa la pregunta real, así que voté en contra. La pregunta es más estrecha: se trata de resolver un problema con el mensaje de error "Las aplicaciones PowerPC ya no son compatibles" y esto es lo que debería estar en el título de la pregunta. De hecho, estoy buscando la respuesta a cómo crear un paquete de aplicaciones. El OP sabe cómo crear un paquete pero encontró un error.
Jason

Respuestas:

4

Cambie el nombre de su archivo .sh a .command y puede cd al directorio en el que se encuentra el archivo .command con lo siguiente al comienzo del archivo:

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

Puedo ver un par de cosas mal allí.

En primer lugar, ha abierto un flujo de trabajo y no una aplicación.

Debe elegir Aplicación cuando realice su selección para el tipo de archivo Automator.

ingrese la descripción de la imagen aquí

Y el código que tiene no funcionará como espera, ya que no ha cambiado el directorio. (discos compactos).

En el código tal como lo tiene, todo lo que está haciendo es obtener la ruta como un alias y almacenarla en la variable current_path y en un formato inadecuado para los comandos unix.

Pero no lo usas.

Por lo tanto, el directorio actual probablemente sea su carpeta de inicio

En esta etapa no se sabe lo que está tratando de lanzar.

Si lo ejecuto como lo tienes, me sale.

ingrese la descripción de la imagen aquí

Lo cual tiene sentido ya que no tengo Java instalado. Pero si lo hiciera, no esperaría que encontrara el archivo correcto.

El Applescript debe verse así.

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 

En mi ejemplo

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

Cd a la ruta POSIX del alias en la variable current_path

es decir, desde "alias" Macintosh HD: Aplicaciones: "" a "/ Aplicaciones /"

El se quoted form of escapa de la ruta utilizando comillas.

He usado el comando / bin / ls y lo canalizo al abierto en TextEdit stdin como una demostración aquí para que pueda probar si está llegando al área que espera.

Usarías algo como;

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

actualizar:

Otra forma es simplemente usar Applescript puro.

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
fuente
Esto está muy cerca de una solución; Confirmo que el ls | opencódigo definitivamente abre el directorio que quiero, lo cual es genial. Pero cuando llamo a abrir Client.app, obtengo: LSOpenURLsWithRole() failed with error -10665 for the file <path-to-Client.app> - algunas búsquedas de lo que significa este error sugirieron un problema de permiso, lo verifiqué y +xse establecieron las banderas. También probé esto , y eso no funcionó (con el mismo error).
emptyset
Tenga en cuenta que abrir Client.appdesde Finder (hacer doble clic) también genera la misma ventana emergente de error de PowerPC.
emptyset
@emptyset I call open Client.app¿Es esta la aplicación Automator? Por lo que entiendo en el automator tiene el código AppleScript: do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\"". Entonces, ¿dónde estás usando el opencomando? que hasta donde yo entiendo lo que estás haciendo, no necesitas usarlo. Los clientes usarán doble clic en la aplicación y la aplicación ejecutará java
markhunte
Lo probé en ambos sentidos: desde la línea de comandos: $ open Client.appy haciendo doble clic. Su versión con invocación ls | open -fefunciona, pero cuando la cambio java -jar app.jarme da ese error.
emptyset
@emptyset trydo shell script "cd " & quoted form of (POSIX path of current_path) & " ; " & quoted form of "java -jar app.jar"
markhunte
6

Camino al guión

En su AppleScript, debe cambiar el directorio de trabajo actual (cwd) antes de emitir el comando java. Haga esto con una línea AppleScript como:

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

El &&es importante. Si cdtiene éxito, el javacomando se iniciará dentro del cwd correcto . Si cdfalla, el javacomando no se ejecutará.

Los problemas que probablemente encontrará incluyen:

  • escapar de la ruta POSIX pasada a cd; los usuarios tendrán carpetas y espacios con nombres extraños en sus rutas.
  • el cdpuede fallar; envuelva su AppleScript en un bloque de prueba para detectar algunos errores y advertir al usuario.

perl

Personalmente, usaría un script perl corto en lugar de 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`;

Hay formas mucho mejores de escribir este fragmento de Perl, pero esto debería funcionar.

Aplicación automatizadora

El mejor enfoque es resolver los problemas con su enfoque de Automator. La respuesta de @ markhunte discute cómo arreglar el camino y crear una aplicación . Esto debería llevarte la mayor parte del camino.

Consulte también la ruta de AppleScript en relación con la ubicación del script .

appify: crea la aplicación Mac más simple posible desde un script de shell

Alternativamente, puede usar el script de aplicación de Thomas Aylott para agrupar su script de shell en una aplicación OS X. El artículo de Mathias Bynen explica cómo usar el script, cómo crear aplicaciones simples de Mac a partir de scripts de 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"

Las mejoras aportadas por la comunidad a este script están disponibles:

Firma de código

Una vez que haya creado su paquete de aplicaciones, debe estar firmado por código. Se iniciará una aplicación con código firmado sin requerir que sus clientes deshabiliten Gatekeeper.

Código de firmar su aplicación utilizando su ID de desarrollador de Apple y el codesigncomando:

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

La firma de código es una tecnología de seguridad, utilizada en OS X, que le permite certificar que usted creó una aplicación. Una vez que se firma una aplicación, el sistema puede detectar cualquier cambio en la aplicación, ya sea que el cambio se introduzca accidentalmente o por código malicioso.

Obtenga más información sobre la firma de código en el sitio para desarrolladores de Apple.

Graham Miln
fuente
Gracias por el consejo sobre la firma de código; ¡Estoy investigando eso ahora y probando el script de appify!
emptyset
el script de appify no funcionó; mismo problema de ruta
emptyset
@emptyset He agregado una ruta y una sección perl. También puede valer la pena separar el problema del camino en una nueva pregunta. Si puede arreglar eso, puede usar Automator o la secuencia de comandos appify.
Graham Miln
5

Use Platypus : "Platypus es una herramienta para desarrolladores de OS X que crea aplicaciones nativas de Mac a partir de scripts interpretados ..."

Platypus es una herramienta para desarrolladores de OS X que crea aplicaciones nativas de Mac a partir de scripts interpretados

perfectcu.be
fuente
4

Se puede cambiar run.sha run.commandy conseguir que el usuario haga doble clic en él?

forquare
fuente
Eso casi funcionó! Sin embargo, ejecutó el archivo desde el contexto del directorio de inicio del usuario ( cd ~), lo que provocó que fallara.
emptyset
1
@emptyset Use $ BASH_SOURCE, consulte apple.stackexchange.com/a/201482
grg
1

Aquí está mi opinión sobre lo que entendí que estás tratando de lograr. El código es largo sin aliento a propósito.

Todo lo que necesita hacer es copiar el código en el Editor de Applescript, hacer los cambios que desee y guardarlo como una aplicación.

En cuanto al diálogo sobre la aplicación PowerPC no compatible, no lo sé. ¿Puedes ejecutarlo desde la línea de comando? Comprobaría eso para confirmar que la aplicación funciona primero.

#
# 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
fuente