쉘 스크립트에 대한 호출을 랩핑하기 위해 OSX 애플리케이션을 작성하는 방법은 무엇입니까?


10

내 목표는 고객에게 터미널을 열고 셸 스크립트를 실행하도록 지시하는 대신 압축 파일에 압축 파일을 포함시키는 것입니다.

내 배포 가능은 본질적으로 다음과 같습니다.

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

스크립트 run.sh:

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

디렉토리에는 더 많은 것이 있습니다. Deliverable 디렉토리에서 스크립트를 실행해야한다고 말하면 충분합니다. 스크립트와 관련된 경로에 액세스해야하기 때문입니다. 그러나 고객이 열 곳을 보장 할 수는 없습니다 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 년을 환영합니다

Cmon, 이것은 매우 간단해야합니다. 내가 여기서 뭘 잘못하고 있니?


글쎄, 나는 더 간단한 애플 스크립트로 업데이트를 게시했지만 grgarside가 더 잘 작동 할 수있는 대답으로 펀치에 맞았습니다. :-)
markhunte

이 질문의 제목은 실제 질문을 나타내지 않기 때문에 투표했습니다. 질문이 더 좁습니다. "PowerPC 응용 프로그램이 더 이상 지원되지 않습니다"라는 오류 메시지의 문제를 해결하는 데 관한 것이며 질문 제목에 나와있는 내용입니다. 실제로 응용 프로그램 번들을 만드는 방법에 대한 답변을 찾고 있습니다. OP는 번들 작성 방법을 알고 있지만 오류가 발생했습니다.
Jason

답변:


4

.sh 파일의 이름을 .command로 바꾸고 파일 시작 부분에서 다음을 사용하여 .command 파일이있는 디렉토리로 cd 할 수 있습니다.

cd "$(dirname $BASH_SOURCE)"

7

거기에 몇 가지 잘못된 점이 있습니다.

먼저 응용 프로그램이 아닌 워크 플로를 열었습니다.

Automator 파일 유형을 선택할 때 응용 프로그램을 선택해야합니다.

여기에 이미지 설명을 입력하십시오

디렉토리를 변경하지 않았으므로 코드가 예상대로 작동하지 않습니다. (CD).

코드에서 알 수 있듯이 경로를 별칭으로 가져 와서 변수 current_path 에 저장 하고 유닉스 명령에 적합하지 않은 형식으로 저장하십시오 .

그러나 당신은 그것을 사용하지 않습니다.

따라서 현재 디렉토리는 아마도 홈 폴더가 될 것입니다

이 단계에서는 시작하려는 내용이 없습니다.

내가 가진대로 그것을 실행하면 얻을 수 있습니다.

여기에 이미지 설명을 입력하십시오

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"

변수 current_path 에서 별칭 의 POSIX 경로 로 cd합니다.

즉, "별칭"Macintosh HD : Applications : ""에서 "/ 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.appFinder에서 열면 (두 번 클릭) 동일한 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\"". 어디에서 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 에서 java 명령을 실행하기 전에 현재 작업 디렉토리 (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를 try 블록으로 마무리하여 오류를 포착하고 사용자에게 경고하십시오.

개인적으로, 나는 bash 스크립트 대신 짧은 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`;

이 펄 스 니펫을 작성하는 훨씬 더 좋은 방법이 있지만 이것이 작동합니다.

자동화 응용

가장 좋은 방법은 Automator 방식의 문제를 해결하는 것입니다. @markhunte의 답변 은 경로를 수정하고 응용 프로그램을 만드는 방법에 대해 설명합니다 . 이것은 당신에게 가장 많은 도움이 될 것입니다.

스크립트 위치와 관련된 AppleScript 경로 도 참조하십시오 .

appify — 쉘 스크립트에서 가장 간단한 Mac 앱을 만듭니다

또는 Thomas Aylott의 appify 스크립트 를 사용하여 쉘 스크립트를 OS X 응용 프로그램에 번들로 제공 할 수 있습니다 . Mathias 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 개발자 ID 및 다음 codesign명령을 사용하여 응용 프로그램에 코드 서명하십시오 .

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

코드 서명은 OS X에서 사용되는 보안 기술로, 사용자가 앱을 만들었 음을 인증 할 수 있습니다. 앱에 서명하면 시스템은 변경이 실수로 발생했는지 또는 악성 코드에 의해 발생했는지에 관계없이 앱의 변경 사항을 감지 할 수 있습니다.

Apple 개발자 사이트에서 코드 서명 에 대해 배우십시오 .


코드 서명에 대한 팁을 주셔서 감사합니다. 나는 지금 그것을 조사하고 appify 스크립트를 테스트하고 있습니다!
emptyset

appify 스크립트가 작동하지 않았습니다. 동일한 경로 문제
비어 있음

@emptyset 경로와 펄 섹션을 추가했습니다. 경로 문제를 새로운 질문으로 분리하는 것이 좋습니다. 이를 해결할 수 있으면 Automator 또는 appify 스크립트를 사용할 수 있습니다.
Graham Miln


4

당신은 변경할 수 run.shrun.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.