¿Cómo crear una aplicación OSX para envolver 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 decirle a mis clientes que abran Terminal y ejecuten un script de shell.

Mi implementable se ve esencialmente así:

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

Script en run.sh :

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

Hay mucho más en el directorio; basta con decir que necesito ejecutar la secuencia de comandos desde el directorio Entregable ya que necesito acceder a las rutas relativas a ella. Sin embargo, no puedo garantizar dónde abrirá un cliente Deliverable.zip (podría ser el directorio principal, podría encontrarse en el directorio de descargas, etc.)

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

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

Elcódigo:

onrun{input,parameters}tellapplication"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:

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

    
pregunta emptyset 13.08.2015 - 20:31

6 respuestas

4

Cambie el nombre de su archivo .sh a .command y puede ir al directorio donde se encuentra el archivo .command con lo siguiente al principio del archivo:

cd "$(dirname $BASH_SOURCE)"
    
respondido por el grg 22.08.2015 - 17:16
7

Puedo ver un par de cosas mal allí.

Primero, ha abierto un flujo de trabajo y no una aplicación.

Debes elegir Aplicación cuando hagas tu selección para el tipo de archivo Automator.

Yelcódigoquetienenofuncionarácomoespera,yaquenohacambiadoeldirectorio.(cd).

Enelcódigoquetiene,todoloqueestáhaciendoesobtenerlarutacomounaliasyalmacenarlaenlavariablecurrent_pathyenunformatoinadecuadoparaloscomandosdeUnix.

Peronolousas.

Esprobablequeeldirectorioactualseasucarpetadeinicio

Enestaetapanosesabequéestáintentandolanzar.

Siloejecutocomolotienes,loconsigo.

LoquetienesentidoyaquenotengoJavainstalado.Perosilohiciera,noesperaríaqueencontraraelarchivocorrecto.

ElApplescriptdebeverseasí.

onrun{input,parameters}tellapplication"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"

Me dirijo a la ruta POSIX del alias en la variable current_path

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

El quoted form of escapa de la ruta usando comillas.

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

Usarías algo como;

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

actualización:

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
    
respondido por el markhunte 16.08.2015 - 03:32
5

Ruta al script

En su AppleScript, debe 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 cd tiene éxito, el comando java se lanzará dentro de la derecha cwd . Si cd falla, el comando java no se ejecutará.

Los problemas que probablemente encontrará incluyen:

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

perl

Personalmente, utilizarí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 muchas formas mejores de escribir este fragmento de código de Perl, pero esto debería funcionar.

Aplicación de automatización

El mejor enfoque es resolver los problemas con su enfoque de Automator. @ markhunte's answer explica cómo corregir la ruta y create an application . Esto debería hacerte llegar la mayor parte del camino.

También vea ruta de AppleScript relativa a la ubicación del script .

appify: crea la aplicación Mac más sencilla 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 utilizar el script, cómo crear aplicaciones Mac sencillas 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, debería tener un código firmado. Se iniciará una aplicación de código firmado sin que sus clientes deshabiliten a Gatekeeper.

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

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 mediante un código malicioso.

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

    
respondido por el Graham Miln 21.08.2015 - 12:11
4

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

    
respondido por el forquare 16.08.2015 - 00:11
3

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

    
respondido por el perfectcu.be 30.07.2017 - 21:22
1

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

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

En cuanto al diálogo sobre la aplicación PowerPC no es compatible, no lo sé. ¿Puedes ejecutarlo desde la línea de comandos? Me gustaría comprobar que para confirmar 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
    
respondido por el Vic 19.08.2015 - 20:28

Lea otras preguntas en las etiquetas