शेल स्क्रिप्ट पर कॉल लपेटने के लिए OSX एप्लिकेशन कैसे बनाएं?


10

मेरा लक्ष्य एक ज़िप फ़ाइल में शामिल करना है, जो अपने ग्राहक (ओं) को टर्मिनल खोलने और शेल स्क्रिप्ट चलाने के लिए कहने के बजाय, एक शॉर्टकट को क्या मात्रा देता है।

मेरा तैनाती अनिवार्य रूप से इस तरह दिखता है:

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

इसमें स्क्रिप्ट run.sh:

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

निर्देशिका में बहुत अधिक है; पर्याप्त मैं निर्देशिका से स्क्रिप्ट चलाने के लिए की जरूरत है कहने के लिए डिलीवरेबल के बाद से मैं पहुँच पथ यह के सापेक्ष की जरूरत है। हालाँकि, मैं गारंटी नहीं दे सकता कि ग्राहक कहाँ जा रहा है Deliverable.zip(होम डायरेक्टरी हो सकती है, डाउनलोड डायरेक्टरी में सही हो सकती है, आदि)

मुझे यह मिला जो बताता है कि ऑटोमेटर में एक नया वर्कफ़्लो कैसे बनाया जाए, फिर इसे शेल स्क्रिप्ट लॉन्च करने के लिए एक एप्लिकेशन के रूप में सहेजें। मैंने उसे लपेटने की कोशिश की, run.shलेकिन यह कहता है कि यह नहीं मिल सकता है run.sh

किसी ने सुझाव दिया कि मैं ऐप्पस्क्रिप्ट का उपयोग करता हूं और मुझे एक लिंक भी भेजा है कि वर्तमान निर्देशिका में स्विच करने के लिए ऐप्पलस्क्रिप्ट का उपयोग कैसे करें; ऑटोमेकर में एक एप्सस्क्रिप्ट "एक्शन" है; इसलिए मैंने इसके साथ एक नया वर्कफ़्लो बनाया, और इसे एक एप्लिकेशन के रूप में सहेजा। यह वही है जो दिखता है:

ऑटोमेटर एप्सस्क्रिप्ट कार्यक्रम

कोड:

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 में आपका स्वागत है

चलो, यह बहुत आसान होना चाहिए। मैं यहां क्या गलत कर रहा हूं?


वैसे मैंने सिर्फ एक सरल एप्सस्क्रिप्ट के साथ अपडेट पोस्ट किया है, लेकिन देखिए मुझे एक जवाब के साथ पंच के लिए पीटा गया था जो कि आपके लिए बेहतर काम करना चाहिए। :-)
मार्कशीट

इस प्रश्न का शीर्षक वास्तविक प्रश्न का प्रतिनिधित्व नहीं करता है, इसलिए मैंने मतदान किया। प्रश्न अधिक संकीर्ण है: यह त्रुटि संदेश के साथ किसी समस्या को हल करने के बारे में है "पावरपीसी एप्लिकेशन अब समर्थित नहीं हैं" और यही प्रश्न शीर्षक में होना चाहिए। मैं वास्तव में आवेदन बंडल बनाने के तरीके के उत्तर की तलाश कर रहा हूं। ओपी जानता है कि एक बंडल कैसे बनाया जाए लेकिन एक त्रुटि का सामना करना पड़ा।
जेसन

जवाबों:


4

अपनी .sh फ़ाइल को .command का नाम दें और आप उस निर्देशिका को cd कर सकते हैं जो .command फ़ाइल फ़ाइल की शुरुआत में निम्नलिखित के साथ स्थित है:

cd "$(dirname $BASH_SOURCE)"

7

मैं वहां कुछ चीजों को गलत देख सकता हूं।

सबसे पहले आप एक कार्यप्रवाह खोला है और एक आवेदन नहीं है।

जब आप ऑटोमेटर फ़ाइल के प्रकार के लिए अपना चयन करते हैं तो आपको आवेदन चुनना चाहिए।

यहाँ छवि विवरण दर्ज करें

और आपके पास वह कोड नहीं होगा जो आप अपेक्षा के अनुरूप काम करेंगे, क्योंकि आपने निर्देशिका नहीं बदली है। (सीडी)।

कोड में जैसा कि आपके पास है, यह सब कर रहा है एक उपनाम के रूप में पथ प्राप्त कर रहा है और इसे चर current_path में और unix आदेशों के लिए अनुपयुक्त प्रारूप में संग्रहीत कर रहा है ।

लेकिन आप इसका उपयोग नहीं करते हैं।

तो वर्तमान निर्देशिका सबसे अधिक संभावना आपके घर फ़ोल्डर होगी

इस स्तर पर कोई यह नहीं बता रहा है कि यह क्या लॉन्च करने की कोशिश कर रहा है।

अगर मैं इसे चलाता हूं तो आपके पास यह है।

यहाँ छवि विवरण दर्ज करें

जो समझ में आता है क्योंकि मेरे पास जावा स्थापित नहीं है। लेकिन अगर मैंने किया तो मुझे सही फ़ाइल मिलने की उम्मीद नहीं होगी।

एप्सस्क्रिप्ट को इस तरह देखने की जरूरत है।

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"

मैं चर current_path में उपनाम के POSIX पथ पर जाता हूं

"उर्फ" मैकिन्टोश एचडी से: अनुप्रयोग: "" से "/ अनुप्रयोग /"

quoted form of पथ उद्धरण का उपयोग कर निकल जाता है।

मैंने / bin / ls कमांड का उपयोग किया है और इसे TextEdit स्टड में खुले में एक प्रदर्शन के रूप में यहां पर पाइप कर रहा हूं ताकि आप यह देखने के लिए परीक्षण कर सकें कि क्या आप उस क्षेत्र से मिल रहे हैं जिसकी आप अपेक्षा करते हैं।

आप कुछ का उपयोग करेंगे;

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

अपडेट करें:

एक और तरीका सिर्फ शुद्ध एप्सस्क्रिप्ट का उपयोग है।

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झंडे लगाए गए हैं। मैं भी कोशिश की इस , और कहा कि काम (एक ही त्रुटि के साथ) नहीं किया।
एम्प्टीसेट

ध्यान दें कि Client.appफाइंडर से खुलने (डबल-क्लिक) के परिणामस्वरूप समान पावरपीसी त्रुटि पॉप-अप भी होती है।
12

@emptyset I call open Client.appयह ऑटोमेकर ऐप है। ऑटोमोटिव में मुझे जो समझ में आता है, आपके पास एप्सस्क्रिप्ट कोड है do shell script "cd " & quoted form of (POSIX path of current_path) & " ;\"java -jar app.jar\"":। तो आप openकमांड का उपयोग कहां कर रहे हैं ? जहां तक ​​मैं समझता हूं कि आप क्या कर रहे हैं, आपको इसका उपयोग करने की आवश्यकता नहीं है। ग्राहकों को एप्लिकेशन पर डबल क्लिक का उपयोग किया जाएगा और ऐप
मार्क

मैंने इसे दोनों तरीकों से जांचा: कमांड लाइन से: $ open Client.appऔर डबल-क्लिक करके। आपका संस्करण इनवोकिंग के साथ ls | open -feकाम करता है, लेकिन जब मैं इसे बदलता हूं तो java -jar app.jarयह मुझे वह त्रुटि दे रहा है।
Emptyset

@emptyset कोशिशdo shell script "cd " & quoted form of (POSIX path of current_path) & " ; " & quoted form of "java -jar app.jar"
markhunte

6

स्क्रिप्ट के लिए पथ

अपने AppleScript में, आपको जावा कमांड जारी करने से पहले वर्तमान कार्य निर्देशिका (cwd) को बदलने की आवश्यकता है । 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 को लपेटें ।

पर्ल

व्यक्तिगत रूप से, मैं बैश स्क्रिप्ट के स्थान पर एक छोटी पर्ल स्क्रिप्ट का उपयोग करूंगा।

#!/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 - शेल स्क्रिप्ट से सबसे सरल संभव मैक ऐप बनाएं

वैकल्पिक रूप से, आप अपने शेल स्क्रिप्ट को OS X अनुप्रयोग में बंडल करने के लिए थॉमस आयलॉट की अपीलीय स्क्रिप्ट का उपयोग कर सकते हैं । मैथियास बिएन का लेख स्क्रिप्ट का उपयोग करने के तरीके से चलता है, शेल स्क्रिप्ट से सरल मैक ऐप कैसे बनाएं

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

इस लिपि में सामुदायिक योगदान में सुधार उपलब्ध हैं:

कोड पर हस्ताक्षर

एक बार जब आप अपना आवेदन बंडल बना लेते हैं, तो इसे कोड पर हस्ताक्षरित होना चाहिए । गेटकीपर को अक्षम करने के लिए आपके ग्राहकों की आवश्यकता के बिना एक कोड हस्ताक्षरित ऐप लॉन्च होगा।

कोड आपके ऐप्पल डेवलपर आईडी और codesignकमांड का उपयोग करके अपने आवेदन पर हस्ताक्षर करें :

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

कोड साइनिंग एक सुरक्षा तकनीक है, जिसका उपयोग ओएस एक्स में किया जाता है, जो आपको यह प्रमाणित करने की अनुमति देता है कि आपके द्वारा एक ऐप बनाया गया था। एक बार एक ऐप पर हस्ताक्षर करने के बाद, सिस्टम ऐप में किसी भी बदलाव का पता लगा सकता है - चाहे वह परिवर्तन गलती से या दुर्भावनापूर्ण कोड द्वारा पेश किया गया हो।

Apple डेवलपर साइट पर कोड साइनिंग के बारे में अधिक जानें ।


कोड हस्ताक्षर पर टिप के लिए धन्यवाद; मैं अब उस पर गौर कर रहा हूं और अपीलीय स्क्रिप्ट का परीक्षण कर रहा हूं!
खाली

appify स्क्रिप्ट काम नहीं किया; एक ही रास्ता मुद्दा
खाली

@emptyset मैंने एक पथ और पर्ल अनुभाग जोड़ा है। यह पथ समस्या को एक नए प्रश्न में अलग करने के लायक भी हो सकता है। यदि आप इसे ठीक कर सकते हैं, तो आप ऑटोमेटर या एपिफाई स्क्रिप्ट का उपयोग कर सकते हैं।
ग्राहम मिलन


4

आप बदल सकते हैं run.shकरने के लिए run.commandऔर डबल क्लिक करें करने के लिए उपयोगकर्ता मिलता है?


यह लगभग काम किया! हालाँकि, इसने फ़ाइल को उपयोगकर्ता के होम डायरेक्टरी ( cd ~) के संदर्भ से चलाया , जिससे यह विफल हो गया।
खाली

1
@emptyset उपयोग $ BASH_SOURCE, देख apple.stackexchange.com/a/201482
GRG

1

यहाँ मेरा जो कुछ समझ में आया उसे आप पूरा करने की कोशिश कर रहे हैं। कोड लंबे उद्देश्य से घुमावदार है।

आपको बस ऐप्पलस्क्रिप्ट संपादक के कोड को कॉपी करने की ज़रूरत है, जो भी बदलाव आप चाहते हैं और उसे एक आवेदन के रूप में सहेजें।

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.