Как создать приложение OSX, чтобы обернуть вызов сценария оболочки?

10

Моя цель - включить в zip-файл ярлык, вместо того, чтобы указывать своим клиентам открыть терминал и запустить скрипт оболочки.

Мой развертываемый по сути выглядит так:

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

Скрипт в run.sh:

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

В каталоге намного больше; Достаточно сказать, что мне нужно запустить скрипт из каталога Deliverable, поскольку мне нужно получить доступ к путям относительно него. Тем не менее, я не могу гарантировать, где клиент откроется Deliverable.zip(может быть домашний каталог, может быть прямо в каталоге загрузок и т. Д.)

Я нашел это , что описывает , как создать новый рабочий процесс в Automator, а затем сохранить его в качестве приложения для запуска сценария оболочки. Я пытался сделать это, чтобы обернуть, run.shно он говорит, что не может найти run.sh.

Кто-то предложил мне использовать applecript, а также прислал мне ссылку на то, как использовать applecript для переключения в текущий каталог; в automator есть «действие» appleScript; поэтому я создал новый рабочий процесс и сохранил его как приложение. Вот как это выглядит:

программа-автомат

Код:

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

И это ошибка, которую я получаю при запуске:

добро пожаловать в 2015

Да ладно, это должно быть довольно просто. Что я здесь не так делаю?

пустой набор
источник
Что ж, я только что опубликовал обновление с более простым яблочным сценарием, но вижу, что меня опередили с ответом, который grgarside должен помочь вам лучше. :-)
markhunte
Название этого вопроса не соответствует актуальному вопросу, поэтому я проголосовал. Вопрос более узкий: речь идет об устранении проблемы с сообщением об ошибке «Приложения PowerPC больше не поддерживаются», и это должно быть в заголовке вопроса. Я на самом деле ищу ответ о том, как создать пакет приложений. ОП знает, как создать пакет, но обнаружил ошибку.
Джейсон

Ответы:

4

Переименуйте ваш файл .sh в .command, и вы можете перейти в каталог, в котором находится файл .command, в начале файла:

cd "$(dirname $BASH_SOURCE)"
Grg
источник
7

Я вижу там несколько вещей не так.

Во-первых, вы открыли рабочий процесс, а не приложение.

Вы должны выбрать Приложение, когда вы делаете выбор для типа файла Automator.

введите описание изображения здесь

И ваш код не будет работать так, как вы ожидаете, так как вы не изменили каталог. (компакт диск).

В том коде, который у вас есть, все, что он делает, это получает путь в качестве псевдонима и сохраняет его в переменной current_path и в формате, неподходящем для команд unix.

Но вы не используете это.

Таким образом, текущий каталог, скорее всего, будет вашей домашней папкой

На данном этапе не известно, что он пытается запустить.

Если я запустлю это, как у вас, я получу.

введите описание изображения здесь

Что имеет смысл, так как у меня не установлена ​​Java. Но если бы я это сделал, я бы не ожидал, что он найдет нужный файл.

Applescript должен выглядеть следующим образом.

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 

В моем примере

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

Я перехожу к POSIX пути псевдонима в переменной current_path

то есть из "псевдонима" Macintosh HD: Приложения: "" в "/ Приложения /"

quoted form of Сбегает путь , используя кавычки.

В качестве демонстрации я использовал команду / bin / ls и направил ее к открытому в TextEdit stdin, чтобы вы могли проверить, попадаете ли вы в ожидаемую область.

Вы бы использовали что-то вроде;

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

Обновить:

Другой способ - просто использовать чистый 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
источник
Это очень близко к решению; Я подтверждаю, что ls | openкод определенно открывает каталог, который я хочу, и это здорово. Но когда я вызываю open Client.app, я получаю: LSOpenURLsWithRole() failed with error -10665 for the file <path-to-Client.app> - несколько поисков того, что означает эта ошибка, предложили проблему с разрешением, я проверил и +xфлаги установлены. Я также попробовал это , и это не сработало (с той же ошибкой).
emptyset
Обратите внимание, что открытие Client.appиз Finder (двойной щелчок) также приводит к тому же всплывающему сообщению об ошибке PowerPC.
emptyset
@emptyset I call open Client.appЭто приложение Automator. Из того, что я понимаю в Automator у вас есть AppleScript код do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\"". Так где вы используете openкоманду? который, насколько я понимаю, что вы делаете, вам не нужно это использовать. Клиенты будут использовать двойной щелчок на приложении, и приложение будет запускать java
markhunte
Я проверил это обоими способами: из командной строки: $ open Client.appи двойным щелчком мыши. Ваша версия с вызовом ls | open -feработает, но когда я изменяю ее, java -jar app.jarона дает мне эту ошибку.
emptyset
@emptyset trydo shell script "cd " & quoted form of (POSIX path of current_path) & " ; " & quoted form of "java -jar app.jar"
markhunte
6

Путь к сценарию

В вашем AppleScript вам нужно изменить текущий рабочий каталог (cwd) перед выполнением команды java. Сделайте это с помощью строки AppleScript, например:

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

Это &&важно. Если это cdудастся, javaкоманда будет запущена в правом cwd . Если произойдет cdсбой, javaкоманда не будет запущена.

Проблемы, с которыми вы, вероятно, столкнетесь, включают:

  • экранирование пути POSIX, переданного в cd; пользователи будут иметь странно названные папки и пробелы в своих путях.
  • cdможет потерпеть неудачу; оберните ваш AppleScript в блок try, чтобы поймать некоторые ошибки и предупредить пользователя.

Perl

Лично я бы использовал короткий Perl-скрипт вместо 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`;

Есть гораздо лучшие способы написать этот фрагмент Perl, но это должно сработать.

Приложение Automator

Наилучшим подходом является проработка проблем с вашим подходом Automator. В ответе @ markhunte обсуждается, как исправить путь и создать приложение . Это должно получить вас большую часть пути.

Также см. Путь AppleScript относительно расположения скрипта .

appify - создайте самое простое приложение для Mac из сценария оболочки

Кроме того, вы можете использовать скрипт appify Томаса Айлотта, чтобы связать ваш сценарий оболочки в приложение OS X. В статье Матиаса Бинена рассказывается, как использовать сценарий, как создавать простые приложения для Mac из сценариев оболочки .

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

Внесенные сообществом улучшения для этого скрипта доступны:

Подписание кода

После того, как вы создали свой пакет приложений, он должен быть подписан кодом. Запустится приложение с подписью кода, не требующее от клиентов отключения Gatekeeper.

Подпишите код вашего приложения, используя Apple Developer ID и codesignкоманду:

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

Подписание кода - это технология безопасности, используемая в OS X, которая позволяет вам подтвердить, что приложение было создано вами. Как только приложение подписано, система может обнаружить любое изменение в приложении - независимо от того, было ли оно внесено случайно или вредоносным кодом.

Узнайте больше о подписи кода на сайте Apple Developer.

Грэм Милн
источник
Спасибо за совет по подписанию кода; Сейчас я изучаю это и тестирую скрипт appify!
emptyset
скрипт appify не работал; тот же вопрос пути
emptyset
@emptyset Я добавил путь и раздел Perl. Возможно, стоит выделить проблему пути в новый вопрос. Если вы можете это исправить, вы можете использовать Automator или скрипт appify.
Грэм Милн
5

Используйте Platypus : «Platypus - это инструмент разработчика OS X, который создает собственные приложения Mac из интерпретированных сценариев ...»

Platypus - это инструмент для разработчиков OS X, который создает собственные приложения Mac из интерпретированных сценариев

perfectcu.be
источник
4

Вы можете изменить , run.shчтобы run.commandи получить пользователь двойного щелчка?

forquare
источник
Это почти сработало! Однако он запустил файл из контекста домашнего каталога пользователя ( cd ~), что привело к сбою.
emptyset
1
@emptyset Используйте $ BASH_SOURCE, см. apple.stackexchange.com/a/201482
grg
1

Вот мое понимание того, что, как я понял, вы пытаетесь достичь. Код долго наматывается специально.

Все, что вам нужно сделать, это скопировать код в редактор Applescript, внести любые необходимые изменения и сохранить его как приложение.

Что касается диалога о том, что приложение PowerPC не поддерживается, я не знаю. Можете ли вы запустить его из командной строки? Я бы проверил это, чтобы подтвердить, что приложение работает в первую очередь.

#
# 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
источник