วิธีสร้างแอปพลิเคชัน OSX เพื่อตัดคำเรียกไปยังเชลล์สคริปต์


10

เป้าหมายของฉันคือการรวมไว้ในไฟล์ zip ว่ามีจำนวนเท่าใดในทางลัดแทนที่จะบอกลูกค้าของฉันเพื่อเปิด Terminal และเรียกใช้เชลล์สคริปต์

การใช้งานของฉันเป็นหลักดูเหมือนว่านี้:

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

สคริปต์ในrun.sh:

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

มีอีกมากในไดเรกทอรี; เพียงพอที่จะบอกว่าฉันต้องเรียกใช้สคริปต์จากไดเรกทอรีDeliverableเนื่องจากฉันต้องการเข้าถึงเส้นทางที่เกี่ยวข้องกับมัน อย่างไรก็ตามฉันไม่สามารถรับประกันได้ว่าลูกค้าจะเปิดที่ไหนDeliverable.zip(อาจเป็นโฮมไดเร็กตอรี่อาจอยู่ในไดเรคทอรีดาวน์โหลด ฯลฯ )

ฉันพบสิ่งนี้ซึ่งอธิบายวิธีสร้างเวิร์กโฟลว์ใหม่ใน Automator จากนั้นบันทึกเป็นแอปพลิเคชันเพื่อเปิดใช้เชลล์สคริปต์ ผมพยายามที่จะทำแบบนั้นกับห่อแต่มันบอกว่ามันไม่สามารถหาrun.shrun.sh

มีคนแนะนำว่าฉันใช้ applescript และส่งลิงก์ให้ฉันถึงวิธีใช้ applescript เพื่อเปลี่ยนเป็นไดเรกทอรีปัจจุบัน มี "การกระทำ" ของ applescript ใน automator; ดังนั้นฉันจึงสร้างเวิร์กโฟลว์ใหม่ด้วยสิ่งนั้นและบันทึกเป็นแอปพลิเคชัน นี่คือสิ่งที่ดูเหมือนว่า:

โปรแกรมแอปพลิเคชัน automator

รหัส:

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

C'mon นี่ควรจะค่อนข้างง่าย ฉันทำอะไรผิดที่นี่


ฉันเพิ่งโพสต์การอัปเดตด้วยแอปพลิเคชันที่เรียบง่ายกว่า แต่เห็นไหมว่าฉันถูกต่อยด้วยหมัดด้วยคำตอบที่ควรจะทำงานได้ดีขึ้นสำหรับคุณโดย grgarside :-)
markhunte

ชื่อของคำถามนี้ไม่ได้เป็นตัวแทนของคำถามจริงดังนั้นฉันจึงลงคะแนน คำถามแคบลง: เกี่ยวกับการแก้ไขปัญหาด้วยข้อความแสดงข้อผิดพลาด "ไม่สนับสนุนแอปพลิเคชัน PowerPC อีกต่อไป" และนี่คือสิ่งที่ควรอยู่ในชื่อคำถาม ฉันกำลังมองหาคำตอบสำหรับวิธีสร้างกลุ่มแอปพลิเคชันอยู่จริง ๆ OP รู้วิธีสร้างบันเดิล แต่พบข้อผิดพลาด
Jason

คำตอบ:


4

เปลี่ยนชื่อไฟล์. sh ของคุณเป็น. คำสั่งและคุณสามารถ cd ไปยังไดเรกทอรีที่ไฟล์. คำสั่งอยู่ในไฟล์ต่อไปนี้ที่จุดเริ่มต้นของไฟล์:

cd "$(dirname $BASH_SOURCE)"

7

ฉันเห็นสิ่งผิดปกติสองอย่างที่นั่น

ประการแรกคุณได้เปิดเวิร์กโฟลว์ไม่ใช่แอปพลิเคชัน

คุณควรเลือกแอปพลิเคชันเมื่อคุณเลือกประเภทไฟล์ Automator

ป้อนคำอธิบายรูปภาพที่นี่

และรหัสที่คุณมีจะไม่ทำงานอย่างที่คุณคาดไว้เนื่องจากคุณไม่ได้เปลี่ยนไดเรกทอรี (CD)

ในโค้ดตามที่คุณมีสิ่งที่ทำอยู่คือการรับพา ธ เป็นนามแฝงและเก็บไว้ในตัวแปร 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"

ฉัน cd ไปยังเส้นทาง POSIXของนามแฝงในตัวแปร current_path

เช่นจาก "นามแฝง" Macintosh HD: แอปพลิเคชัน: "" ถึง "/ Applications /"

ทาง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

นี่ใกล้กับโซลูชันมาก ฉันยืนยันว่าls | 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 จากสิ่งที่ฉันเข้าใจอัตโนมัติที่คุณมีรหัส do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\""AppleScript: ดังนั้นคุณใช้openคำสั่งอยู่ที่ไหน ซึ่งเท่าที่ฉันเข้าใจสิ่งที่คุณกำลังทำคุณไม่จำเป็นต้องใช้มัน ลูกค้าจะใช้ดับเบิ้ลคลิกที่แอพและแอปจะเรียกใช้จาวา
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 ของคุณในบล็อกลองเพื่อตรวจจับข้อผิดพลาดและเตือนผู้ใช้

Perl

โดยส่วนตัวแล้วฉันจะใช้สคริปต์ Perl สั้น ๆ แทนสคริปต์ทุบตี

#!/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`;

มีวิธีที่ดีกว่ามากในการเขียนตัวอย่างโค้ดนี้ แต่ควรจะได้ผล

แอปพลิเคชันอัตโนมัติ

วิธีที่ดีที่สุดคือการทำงานผ่านปัญหาเกี่ยวกับวิธีการอัตโนมัติของคุณ @ markhunte ของคำตอบที่กล่าวถึงวิธีการแก้ไขเส้นทางและสร้างแอพลิเคชัน สิ่งนี้จะทำให้คุณได้รับประโยชน์สูงสุด

ยังเห็นAppleScript ญาติเส้นทางไปยังสถานที่สคริปต์

appify - สร้างแอพ Mac ที่ง่ายที่สุดจาก shell script

หรือคุณสามารถใช้สคริปต์ต่อท้ายของ Thomas Aylott เพื่อรวมเชลล์สคริปต์ของคุณเข้ากับแอปพลิเคชัน OS X บทความงัด Bynen ของเดินผ่านวิธีการใช้สคริปต์วิธีการสร้างง่าย 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


ขอบคุณสำหรับเคล็ดลับในการเซ็นชื่อโค้ด ฉันกำลังดูอยู่ตอนนี้และทดสอบสคริปต์ต่อท้าย!
emptyset

ต่อท้ายสคริปต์ไม่ทำงาน ปัญหาเส้นทางเดียวกัน
emptyset

@emptyset ฉันได้เพิ่มเส้นทางและส่วนของ Perl นอกจากนี้ยังอาจคุ้มค่าที่จะแยกปัญหาเส้นทางออกเป็นคำถามใหม่ หากคุณสามารถแก้ไขได้คุณสามารถใช้ Automator หรือสคริปต์ต่อท้าย
เกรแฮมมิลน์

5

ใช้ Platypus : "Platypus เป็นเครื่องมือสำหรับนักพัฒนา OS X ที่สร้างแอปพลิเคชัน Mac ดั้งเดิมจากสคริปต์ที่ตีความ ... "

Platypus เป็นเครื่องมือสำหรับนักพัฒนา OS X ที่สร้างแอปพลิเคชั่น Mac ดั้งเดิมจากสคริปต์ตีความ


4

คุณสามารถเปลี่ยนrun.shไปrun.commandและได้รับการให้ผู้ใช้ดับเบิลคลิกมันได้หรือไม่


เกือบจะได้ผลแล้ว! อย่างไรก็ตามมันรันไฟล์จากบริบทของโฮมไดเรกทอรีของผู้ใช้ ( cd ~) ซึ่งทำให้ไฟล์ล้มเหลว
emptyset

1
@emptyset ใช้ $ BASH_SOURCE ดูapple.stackexchange.com/a/201482
grg

1

นี่คือสิ่งที่ฉันเข้าใจว่าคุณกำลังพยายามทำให้สำเร็จ รหัสยืดยาวตามวัตถุประสงค์

สิ่งที่คุณต้องทำคือคัดลอกรหัสไปยัง Applescript Editor ทำการเปลี่ยนแปลงใด ๆ ที่คุณต้องการและบันทึกเป็นแอปพลิเคชัน

สำหรับกล่องโต้ตอบเกี่ยวกับแอปพลิเคชัน 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.