Làm cách nào để tạo Ứng dụng OSX để thực hiện cuộc gọi đến tập lệnh shell?


10

Mục tiêu của tôi là bao gồm trong một tệp zip số tiền cho một phím tắt, thay vì nói với (các) khách hàng của tôi mở Terminal và chạy tập lệnh shell.

Triển khai của tôi về cơ bản trông như thế này:

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

Tập lệnh trong run.sh:

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

Có nhiều hơn nữa trong thư mục; đủ để nói rằng tôi cần chạy tập lệnh từ thư mục Có thể phân phối được vì tôi cần truy cập các đường dẫn liên quan đến nó. Tuy nhiên, tôi không thể đảm bảo nơi khách hàng sẽ mở Deliverable.zip(có thể là thư mục chính, có thể ở ngay trong thư mục Tải xuống, v.v.)

Tôi đã tìm thấy điều này mô tả cách tạo một quy trình công việc mới trong Automator, sau đó lưu nó dưới dạng một ứng dụng để khởi chạy một tập lệnh shell. Tôi đã cố gắng làm điều đó để bọc run.shnhưng nó nói rằng nó không thể tìm thấy run.sh.

Ai đó đề nghị tôi sử dụng applescript và cũng gửi cho tôi một liên kết đến cách sử dụng applescript để chuyển sang thư mục hiện tại; có một "hành động" táo bạo trong máy tự động; Vì vậy, tôi đã thực hiện một quy trình công việc mới với điều đó và lưu nó dưới dạng một ứng dụng. Đây là những gì trông giống như:

chương trình applescript tự động

Mật mã:

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

Và đây là lỗi tôi gặp phải khi chạy nó:

chào mừng đến năm 2015

C'mon, điều này sẽ khá đơn giản. Tôi đang làm gì sai ở đây?


Vâng, tôi vừa đăng cập nhật với một applescript đơn giản hơn, nhưng thấy tôi đã bị đánh với cú đấm với một câu trả lời sẽ hoạt động tốt hơn cho bạn bởi grgarside. :-)
markhunte

Tiêu đề của câu hỏi này không đại diện cho câu hỏi thực tế, vì vậy tôi đã bỏ phiếu. Câu hỏi hẹp hơn: đó là về việc giải quyết vấn đề với thông báo lỗi "Các ứng dụng PowerPC không còn được hỗ trợ" và đây là điều nên có trong tiêu đề câu hỏi. Tôi thực sự đang tìm câu trả lời cho cách tạo một gói ứng dụng. OP biết cách tạo một gói nhưng gặp lỗi.
Jason

Câu trả lời:


4

Đổi tên tệp .sh của bạn thành .command và bạn có thể cd vào thư mục chứa tệp .command với vị trí sau ở đầu tệp:

cd "$(dirname $BASH_SOURCE)"

7

Tôi có thể thấy một vài điều sai ở đó.

Đầu tiên bạn đã mở một quy trình công việc chứ không phải Ứng dụng.

Bạn nên chọn Ứng dụng khi bạn thực hiện lựa chọn cho loại tệp Tự động hóa.

nhập mô tả hình ảnh ở đây

Và mã bạn sẽ không hoạt động như bạn mong đợi, vì bạn không thay đổi thư mục. (CD).

Trong mã như bạn có, tất cả những gì nó đang làm là lấy đường dẫn dưới dạng bí danh và lưu trữ nó trong biến current_path và ở định dạng không phù hợp với các lệnh unix.

Nhưng bạn không sử dụng nó.

Vì vậy, thư mục hiện tại rất có thể sẽ là thư mục nhà của bạn

Ở giai đoạn này, không có gì để nói những gì nó đang cố gắng để khởi động.

Nếu tôi chạy nó như bạn có nó, tôi nhận được.

nhập mô tả hình ảnh ở đây

Điều này hợp lý vì tôi chưa cài đặt Java. Nhưng nếu tôi đã làm, tôi sẽ không mong đợi nó tìm đúng tập tin.

Applescript cần phải trông như thế này.

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 

Trong ví dụ của tôi

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

Tôi cd đến đường dẫn POSIX của bí danh trong biến current_path

tức là từ "bí danh" Macintosh HD: Ứng dụng: "" đến "/ Ứng dụng /"

Các quoted form of lối thoát bằng cách sử dụng dấu ngoặc kép.

Tôi đã sử dụng lệnh / bin / ls và chuyển nó sang open trong TextEdit stdin như một minh chứng ở đây để bạn có thể kiểm tra xem bạn có đến khu vực bạn mong đợi không.

Bạn sẽ sử dụng một cái gì đó như;

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

cập nhật:

Một cách khác là chỉ sử dụng Applescript thuần túy.

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

Điều này rất gần với một giải pháp; Tôi xác nhận ls | openmã chắc chắn mở thư mục tôi muốn, thật tuyệt. Nhưng khi tôi gọi mở Client.app, tôi nhận được: LSOpenURLsWithRole() failed with error -10665 for the file <path-to-Client.app> - một số tìm kiếm cho những gì lỗi này có nghĩa là gợi ý một vấn đề cho phép, tôi đã kiểm tra và +xcờ được thiết lập. Tôi cũng đã thử điều này và nó không hoạt động (với cùng một lỗi).
trống rỗng

Lưu ý rằng việc mở Client.apptừ Finder (nhấp đúp chuột) cũng dẫn đến việc bật lên lỗi PowerPC tương tự.
trống rỗng

@emptyset I call open Client.appĐây có phải là ứng dụng Automator. Từ những gì tôi hiểu trong trình tự động hóa, bạn có mã applescript : do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\"". Vậy bạn đang sử dụng openlệnh ở đâu? theo như tôi hiểu những gì bạn đang làm, bạn không cần phải sử dụng nó. Các khách hàng sẽ sử dụng nhấp đúp chuột vào ứng dụng và ứng dụng sẽ chạy java
markhunte

Tôi đã thử nghiệm cả hai cách: từ dòng lệnh: $ open Client.appvà bằng cách nhấp đúp. Phiên bản của bạn với ls | open -feviệc gọi hoạt động, nhưng khi tôi thay đổi nó thành java -jar app.jarlỗi đó.
trống rỗng

@emptyset thửdo shell script "cd " & quoted form of (POSIX path of current_path) & " ; " & quoted form of "java -jar app.jar"
markhunte

6

Đường dẫn đến tập lệnh

Trong AppleScript của bạn, bạn cần thay đổi thư mục làm việc hiện tại (cwd) trước khi ban hành lệnh java. Làm điều này với một dòng AppleScript như:

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

Điều &&quan trọng. Nếu cdthành công, javalệnh sẽ được khởi chạy trong cwd bên phải . Nếu cdthất bại, javalệnh sẽ không được chạy.

Các vấn đề bạn có thể gặp phải bao gồm:

  • thoát khỏi đường dẫn POSIX được chuyển đến cd; Người dùng sẽ có các thư mục và không gian được đặt tên kỳ lạ trong đường dẫn của họ.
  • những cdcó thể thất bại; bọc AppleScript của bạn trong một khối thử để bắt một số lỗi và cảnh báo người dùng.

perl

Cá nhân, tôi sẽ sử dụng một tập lệnh perl ngắn thay cho tập lệnh 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`;

Có nhiều cách tốt hơn để viết đoạn trích perl này nhưng nó sẽ hoạt động.

Ứng dụng tự động

Cách tiếp cận tốt nhất là giải quyết các vấn đề với phương pháp Automator của bạn. Câu trả lời của @ markhunte thảo luận về cách sửa đường dẫn và tạo một ứng dụng . Điều này sẽ giúp bạn có được hầu hết các cách.

Cũng xem đường dẫn AppleScript liên quan đến vị trí tập lệnh .

appify - tạo ứng dụng Mac đơn giản nhất có thể từ tập lệnh shell

Ngoài ra, bạn có thể sử dụng tập lệnh appify của Thomas Aylott để gói tập lệnh shell của bạn vào một ứng dụng OS X. Bài viết của Mathias Bynen hướng dẫn cách sử dụng tập lệnh, cách tạo các ứng dụng Mac đơn giản từ tập lệnh 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"

Cải thiện đóng góp của cộng đồng cho kịch bản này có sẵn:

Ký mã

Khi bạn đã tạo gói ứng dụng của mình, mã phải được ký. Một ứng dụng đã ký mã sẽ khởi chạy mà không yêu cầu khách hàng của bạn vô hiệu hóa Gatekeeper.

Mã ký ứng dụng của bạn bằng ID nhà phát triển Applecodesignlệnh:

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

Ký mã là một công nghệ bảo mật, được sử dụng trong OS X, cho phép bạn xác nhận rằng một ứng dụng được tạo bởi bạn. Khi một ứng dụng được ký, hệ thống có thể phát hiện bất kỳ thay đổi nào đối với ứng dụng này cho dù thay đổi đó được vô tình giới thiệu hay bởi mã độc.

Tìm hiểu thêm về ký mã trên trang web Apple Developer.


Cảm ơn các mẹo về ký mã; Bây giờ tôi đang xem xét và kiểm tra kịch bản appify!
trống

appify script không hoạt động; cùng một vấn đề đường dẫn
khoảng trống

@emptyset Tôi đã thêm một phần đường dẫn và perl. Nó cũng có thể có giá trị tách vấn đề đường dẫn thành một câu hỏi mới. Nếu bạn có thể khắc phục điều đó, bạn có thể sử dụng Automator hoặc tập lệnh appify.
Graham Miln


4

Bạn có thể thay đổi run.shđể run.commandvà nhận được sử dụng để kích đúp nó?


Điều đó gần như đã làm việc! Tuy nhiên, nó đã chạy tệp từ ngữ cảnh của thư mục chính của người dùng ( cd ~), khiến nó bị lỗi.
trống

1
@emptyset Sử dụng $ BASH_SOURCE, xem apple.stackexchange.com/a/201482
GRG

1

Đây là nhận của tôi về những gì tôi hiểu bạn đang cố gắng thực hiện. Các mã là dài dòng về mục đích.

Tất cả những gì bạn cần làm là sao chép mã vào Trình soạn thảo Applescript, thực hiện bất kỳ thay đổi nào bạn muốn và lưu nó dưới dạng một ứng dụng.

Đối với hộp thoại về ứng dụng PowerPC không được hỗ trợ, tôi không biết. Bạn có thể chạy nó từ dòng lệnh? Tôi sẽ kiểm tra để xác nhận ứng dụng hoạt động trước.

#
# 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.