11 votos

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

Mi objetivo es incluir en un archivo zip lo que equivale a un acceso directo, en lugar de decirle a mi(s) cliente(s) que abra(n) el Terminal y ejecute(n) un script de shell</strkeep><strkeep>.

Mi desplegable tiene esencialmente este aspecto:

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

scripten 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 ella. Sin embargo, no puedo garantizar dónde va a abrir un cliente Deliverable.zip (podría ser el directorio de inicio, podría estar justo en el directorio de descargas, etc.)

He encontrado este que describe cómo crear un nuevo flujo de trabajo en Automator, y luego guardarlo como una aplicación para lanzar un shell script. Traté de hacer eso para envolver run.sh pero dice que no puede encontrar run.sh .

Alguien me sugirió que usara applescript y también me envió un enlace sobre cómo usar applescript para cambiar al directorio actual; hay una "acción" de applescript en automator; así que hice un nuevo flujo de trabajo con eso, y lo guardé como una aplicación. Esto es lo que parece:

the automator applescript program

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 recibo cuando lo ejecuto:

welcome to 2015

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

0 votos

Bueno, acabo de publicar una actualización con un applescript más simple, pero veo que se me adelantó con una respuesta que debería funcionar mejor para usted por grgarside. :-)

0 votos

El título de esta pregunta no representa la pregunta real, así que he votado 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. En realidad estoy buscando la respuesta a cómo crear un paquete de aplicaciones. El OP sabe cómo crear un paquete, pero se encontró con un error.

7voto

Malik hassan Puntos 16

Veo que hay un par de cosas que no funcionan.

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

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

enter image description here

Y el código que tienes no funcionará como esperas, ya que no has cambiado de directorio. (cd).

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

Pero tú no lo utilizas.

Así que el directorio actual será probablemente su carpeta de inicio

A estas alturas no se sabe qué es lo que intenta lanzar.

Si lo ejecuto como lo tienes me sale.

enter image description here

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

El Applescript tiene que ser 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"

I cd a la Ruta POSIX del alias en la variable ruta_actual

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

El quoted form of escapa de la ruta usando comillas.

He utilizado el /bin/ls y lo canaliza en el comando abrir en TextEdit stdin como demostración aquí para que puedas probar si llegas a la zona que esperas.

Usarías algo como;

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

actualizar:

Otra forma es 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

0 votos

Esto está muy cerca de una solución; confirmo la ls | open El código definitivamente abre el directorio que quiero, lo cual es genial. Pero cuando llamo a open Client.app me sale: LSOpenURLsWithRole() failed with error -10665 for the file <path-to-Client.app> - algunas búsquedas de lo que significa este error sugerido un problema de permisos, lo he comprobado y +x las banderas están puestas. También he probado este y eso no funcionó (con el mismo error).

0 votos

Tenga en cuenta que la apertura Client.app desde el Finder (doble clic) también da como resultado la misma ventana emergente de error de PowerPC.

0 votos

@emptyset I call open Client.app ¿Es la aplicación Automator. Por lo que entiendo en el automator tienes el código applescript: do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\"" . Entonces, ¿dónde está usando el open que, por lo que entiendo, no es necesario utilizarlo. Los clientes estarán usando el doble clic en la aplicación y la aplicación ejecutará el java

6voto

Steve Evans Puntos 155

Ruta de acceso a script

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

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

El && es importante. Si el cd tiene éxito, el java se lanzará dentro de la derecha cwd . Si cd falla, el java no se ejecutará el comando.

Los problemas con los que probablemente se encontrará son:

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

perl

Personalmente, yo envolvería el uso de un corto perl script en lugar de un bash script.

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

Lo mejor es trabajar los problemas con su enfoque de Automator. Respuesta de @markhunte discute cómo arreglar el camino y crear una aplicación . Esto debería servirle para la mayor parte del camino.

Ver también Ruta de AppleScript relativa a la ubicación de script. .

appify - crea la aplicación Mac más sencilla posible a partir de un shell script

Como alternativa, puede utilizar el programa de Thomas Aylott appify script para agrupar su shell script en una aplicación de OS X. El artículo de Mathias Bynen explica cómo utilizar el script, cómo crear aplicaciones sencillas para Mac a partir de scripts .

#!/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ódigos

Una vez que haya creado su paquete de aplicaciones, éste debe estar firmada por el código. Una aplicación firmada por código se lanzará sin requerir que sus clientes desactiven Gatekeeper.

Firme el código de su aplicación utilizando su ID de desarrollador de Apple y el codesign comando:

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

La firma de código es una tecnología de seguridad, utilizada en OS X, que permite certificar que una aplicación ha sido creada por ti. Una vez que una aplicación está firmada, el sistema puede detectar cualquier cambio en ella, ya sea introducido accidentalmente o por un código malicioso.

Aprenda más sobre la firma de código en el sitio de desarrolladores de Apple.

0 votos

Gracias por el consejo sobre la firma de código; ¡estoy investigando ahora y probando el appify script!

0 votos

Appify script no funcionó; mismo problema de ruta

0 votos

@emptyset He añadido una sección de ruta y perl. También puede valer la pena separar el problema de la ruta en una nueva pregunta. Si puedes arreglar eso, puedes usar Automator o el appify script.

4voto

forquare Puntos 841

¿Puede cambiar run.sh a run.command y hacer que el usuario haga doble clic en él?

0 votos

¡Casi ha funcionado! Sin embargo, ejecutó el archivo desde el contexto del directorio root del usuario ( cd ~ ), lo que provocó su fracaso.

1 votos

@emptyset Utilizar $BASH_SOURCE, ver apple.stackexchange.com/a/201482

4voto

siva Puntos 23

Cambie el nombre de su archivo .sh por el de .command y vaya al directorio en el que se encuentra el archivo .command con lo siguiente al principio del archivo:

cd "$(dirname $BASH_SOURCE)"

1voto

SPRBRN Puntos 1008

Esta es mi opinión sobre lo que entiendo que está tratando de lograr. El código es largo a propósito.

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

En cuanto al diálogo sobre la aplicación PowerPC no soportada, no lo sé. ¿Puedes ejecutarla desde la línea de comandos? Yo 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

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X