कमांड लाइन से मैक ओएस एप्स की शुरुआत करें


22

मैं कमांड लाइन में उचित मात्रा में काम करता हूं, और मैं खुद को फॉर्म के बहुत सारे उपनामों को परिभाषित करता हुआ पाता हूं:

alias skim='/Applications/Skim.app/Contents/MacOS/Skim'

क्या जादू जोड़ने का एक तरीका है जो निष्पादन योग्य "फू" के लिए पूछ रहा है, स्वचालित रूप से निष्पादन योग्य /Applications/Foo.app/Contents/MacOS/Foo का उपयोग करता है? यह OS X 10.6 पर है।

(मुझे पता है कि मैं कर सकता था open foo.pdf, लेकिन स्किम डिफ़ॉल्ट पीडीएफ रीडर नहीं है, और मैं एक सामान्य समाधान चाहूंगा - कुछ मामलों में, फ़ाइल के लिए डिफ़ॉल्ट हैंडलर के रूप में आवेदन को प्रश्न में सेट करना उचित नहीं है।)


22
आप कर सकते हैं open -a Skim foo.pdf

1
@mankoff: अच्छा, मैं भूल गया था कि आप -a का उपयोग यह बताने के लिए कर सकते हैं कि आप एप्लिकेशन से एक ऐप चाहते हैं। आपको इसे एक उत्तर में बदलना चाहिए :)
रॉबर्ट एस सियाकियो

@ रीड: क्या आप अपने प्रश्न को एक उदाहरण कमांड लाइन को शामिल करने के लिए संपादित कर सकते हैं जिसे आप टाइप करने में सक्षम होना चाहते हैं?
बजे रॉबर्ट एस सियासीओ

@ मेनकॉफ़ का मतलब है कि उन्हें टैब पूरा होने के लिए एलियास की जरूरत है या विस्तार की जरूरत है
रॉबर्ट एस सियाकियो

@ समाधान के साथ किसी भी मुद्दे?

जवाबों:


10

अंत में मुझे मिल गया: इसे अपने में जोड़ें .bash_profile

function foomagick() {
    rm -f ~/.foomagick.tmp
    ls /Applications/ | grep "\.app" | grep -v iWork | while read APP; do
        # clean it up                                                           
        a=`echo $APP | sed s/\ //g`;
        a=`echo $a | sed s/\'//g`;
        echo alias ${a%.*}="'open -a \"${APP%.*}\"'" >> ~/.foomagick.tmp
    done
    source ~/.foomagick.tmp
    rm ~/.foomagick.tmp  
}
foomagick()

अब निम्नलिखित कार्य:

Skim # open Skim.app
Skim foo.pdf
FireFox http://google.com
FireFox google.com # ERROR. Looks for local file.

रीड द्वारा संपादित करें:

मैंने उपरोक्त को पायथन लिपि के रूप में लागू किया है जो उपनामों के बजाय आवरण स्क्रिप्ट बनाती है। आपको ~/bin/mankoffmagicअपने रास्ते में लगाना होगा। यदि आप चाहते हैं कि रैपर अपने आप अपडेट हो जाएं, तो इसे नियमित रूप से क्रोन या सोमेसुच से चलाएं।

#!/usr/bin/python
#
# This script automagically updates a set of wrapper shell scripts in
# ~/bin/mankoffmagic which call Mac apps installed in /Applications.
#
# Inspired by mankoff's shell alias posted on apple.stackexchange.com; see:
# http://apple.stackexchange.com/questions/4240/concisely-starting-mac-os-apps-from-the-command-line/4257#4257
#
# Notes/Bugs:
#
# 1. Does not follow symlinks (aliases?)
#
# 2. Assumes that application names do not contain double-quotes.
#
# 3. Not very smart about finding the actual binary (it guesses). This is
# wrong sometimes, e.g. Firefox. Probably a deeper understanding of the app
# package structure would fix this.

import copy
import glob
import os
import os.path
import re

BINDIR = os.path.expandvars("$HOME/bin/mankoffmagic")
APP_RE = re.compile(r'(.*)\.app$')
STRIP_RE = re.compile(r'[\W_]+')

def main():
   # We aggressively delete everything already in BINDIR, to save the trouble
   # of analyzing what should stay
   for f in glob.glob("%s/*" % BINDIR):
      os.unlink(f)

   # Walk /Applications and create a wrapper shell script for each .app dir
   for (root, dirs, files) in os.walk("/Applications"):
      dirs_real = copy.copy(dirs)  # so we can manipulate dirs while looping
      for d in dirs_real:
         #print "checking %s" % os.path.join(root, d)
         m = APP_RE.search(d)
         if (m is not None):
            #print "Found " + m.group()
            dirs.remove(d)  # no need to recurse into app
            create_script(root, d, m.group(1))

def create_script(path, appdir, appname):
   # remove non-alphanumerics and downcase it
   wrapper = STRIP_RE.sub('', appname).lower()
   wrapper = os.path.join(BINDIR, wrapper)
   fp = open(wrapper, "w")
   # Twiddle the comments in the script depending on whether you want to
   # invoke the binary or use "open" -- the former lets you use any
   # command-line args, while the latter is more Mac-like (app puts itself in
   # the front, etc.)
   fp.write("""
#!/bin/sh
exec "%s/%s/Contents/MacOS/%s" "$@"
#open -a "%s" "$@"
""" % (path, appdir, appname, appname))
   fp.close()
   os.chmod(wrapper, 0700)


if (__name__ == "__main__"):
   main()

"Grep -v iWork" सिर्फ इसलिए है क्योंकि "iWork '09" में एपोस्ट्रोफ चीजों को गड़बड़ कर रहा है। ध्यान दें कि यदि आप एप्लिकेशन को कहीं और संग्रहीत करते हैं (~ / स्थानीय / एप्लिकेशन) तो बस उसे lsकमांड में जोड़ें , और यह वहां भी काम करेगा।

अच्छा है। मुझे यह पसंद है कि यह गतिशील है इसलिए आप पुराने एलियाज़ को साफ करने जैसे किसी भी रखरखाव के मुद्दों के साथ समाप्त नहीं होते हैं।
रॉबर्ट एस सियासीओ

धन्यवाद @ मांकॉफ़! बहुत अच्छी खुशबू आ रही है - एक बार मैंने इसका परीक्षण किया है और यह काम करता है मैं स्वीकृत उत्तर को चिह्नित करूंगा। बहुत सराहना की।
रीड करें

ठीक है, यह काम करता है। यह एपोस्ट्रोफी (और संभवतः नाम में अन्य मजेदार वर्ण) के साथ ऐप्स पर ब्रेक करता है। मैंने आपके समाधान पर भरोसा किया और पायथन में कुछ ऐसा ही किया, जिसे मैं दूसरे उत्तर में पोस्ट करूंगा - हालांकि अगर यह सही शिष्टाचार नहीं है, तो मैं इसे आपके उत्तर (या जो भी) के साथ जोड़कर खुश हूं।
रीड करें

8

आप कुछ भी कल्पना की जरूरत नहीं है, आप पहले से ही जवाब है। प्रयत्न:

open /Applications/Foo.app bar.pdf

संपादित करें

नीचे दी गई टिप्पणियों के प्रकाश में, मुझे लगता है कि मेरा उत्तर अभी भी अपेक्षाकृत समान होगा ... मैं एक ऐसा कार्य करूँगा जो खुले में ओवरराइड करता है, एक पॉपड करता है /Applications, कॉल /usr/bin/open $appName.app $argsकरता है, एक पॉप करता है और रिटर्न करता है।

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

मुझे यकीन है कि सिंटैक्स बाहरी स्थान से है:

function open($appName, $args)
{
    #if we are calling open without a path like /Applications/TextEdit.app AND
    #    $appName ends in '.app'
    if (!hasParent($appName) && isApp($appName))
    {
        pushd /Applications
        /usr/bin/open ${appName}.app $args &
        popd
        return
    }
    #otherwise, use open as normal
    /usr/bin/open $appName $args
    return
}

दूसरे एडिट पर

मूल प्रश्न पर @ mankoff की टिप्पणी को देखते हुए, उपरोक्त फ़ंक्शन में अधिकांश सामान संभवतः समय की बर्बादी होगी क्योंकि आप अभी उपयोग कर सकते हैं open -a $appName। इसलिए मैनकॉफ़ का शायद सबसे आसान समाधान है और अपनी टिप्पणी को एक उत्तर में बदलना चाहिए;)


मुझे लगता है कि @Reid सभी उपनामों को मैन्युअल रूप से बनाने के लिए एक छोटा रास्ता w / o चाहता है।

लेकिन यदि उसे .app पैकेज पर 'ओपन' का उपयोग किया जाता है, तो उसे यूनिक्स एक्जीक्यूटिव के लिए एक उपनाम नहीं बनाना पड़ता है। मुझे यह आभास हुआ कि वह उपनाम बना रहा था क्योंकि उसने कमांड लाइन से सीधे ऐप शुरू करने का एकमात्र तरीका MacOS निर्देशिका में सभी तरह से जाना और उस फ़ाइल को निष्पादित करना था जो एक ऐप के अंदर 'वास्तविक' निष्पादन योग्य है। तो उस स्थिति में, एक उपनाम कम से कम निर्देशिका संरचना के अतिरिक्त तीन स्तरों को टाइप करने से बचाएगा जिसे आपको ऐप शुरू करने के लिए आवश्यक होगा। शायद मैं उसके सवाल को गलत समझ रहा हूं।
रॉबर्ट एस सियासियो

@ कैलेवरा, धन्यवाद - @mankoff सही है; यह लंबाई के बारे में है।
रीड

3
यह संपादित कार्यक्षमता का एक दुरुपयोग है। यदि आप बाद में एक दूसरे उत्तर का प्रस्ताव करना चाहते हैं, तो बस यही करें। अपने मूल उत्तर को संपादित न करें, यह आपके नए विचार पर प्राप्त मतों को गुल्लक करने के लिए।
जेफ स्वेनसेन

1
मैं सहमत नहीं हूँ ... जवाब अभी भी बहुत समान है क्योंकि वह एक ही वाक्यविन्यास का उपयोग कर रहा होगा। इतना ही नहीं, लेकिन अगर मतदाताओं को नया उत्तर पसंद नहीं है, तो वे अपना वोट बदल सकते हैं क्योंकि उत्तर को संपादित किया गया है। यही कारण है कि आप संपादन के बाद अपना वोट बदल सकते हैं। यह भी है कि मैं बोल्ड में "एडिट" क्यों करता हूं।
रॉबर्ट एस सियासीओ

4

वहाँ दो समाधान है कि मैं के बारे में सोच सकते हैं:

आसान तरीका - Info.plistप्रत्येक .app Contentsनिर्देशिका में फ़ाइल का उपयोग करते हुए , चाबियाँ CFBundleExecutable के लिए मूल्य का एक सूचकांक बनाएं। फिर एक संक्षिप्त उपनाम जोड़ें जो एक निष्पादन योग्य के नाम के साथ एक स्क्रिप्ट (पर्ल, अजगर, जो भी हो) को बुलाता है और आप जिन तर्कों को पारित करना चाहते हैं।

आपका अनुक्रमणिका निष्पादन योग्य नामों और उन निष्पादनों के पथों के जोड़े होंगे। आपको इसे अपडेट रखने के लिए एक आवर्ती अनुसूचित स्क्रिप्ट लिखना होगा।

आप अंत में कॉल करने में सक्षम होंगे:

f foo file.txt

जहाँ f एक स्क्रिप्ट के लिए एक उपनाम है जो एक निष्पादन योग्य नाम के लिए आपके सूचकांक की जाँच करता है foo

सब सब में, कार्यक्षमता आप चाहते हैं पाने के लिए बहुत काम नहीं है।

कठिन तरीका - अपनी command_not_foundत्रुटि की हैंडलिंग के पूरक के लिए अपने खोल को बढ़ाएं । अनिवार्य रूप से आप method_missingजो भी शेल का उपयोग कर रहे हैं उसके भीतर एक रूबी शैली की कार्यक्षमता को लागू करेगा । जब command_not_foundफेंक दिया गया था, तो आपका तरीका आपके इंस्टॉल किए गए एप्लिकेशन के निष्पादन योग्य नामों की जांच करेगा।


2

बचाव के लिए आवेदन:

osascript -e 'tell application "iTunes"' -e "activate" -e 'end tell'

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

function f() {
    osascript <<EOF
tell application "$1"
  activate
end tell
EOF
}

और इसे इस तरह से उपयोग करें:

f iTunes

मुझे ऐप्पलस्क्रिप्ट से नफरत है, लेकिन यह कभी-कभी उपयोगी होता है, और मैं कमांड लाइन पर नाम से केवल एक आवेदन को संबोधित करने का एकमात्र तरीका मानता हूं। बाकी सब कुछ एक पूर्ण पथ की आवश्यकता होगी।


टैब-पूर्णता का समर्थन नहीं करता है। एप्लिकेशन नामों को बिल्कुल याद रखने की आवश्यकता है। देखें कि AppleScript क्यों आवश्यक है (विशेषकर यदि आप इसे नफरत करते हैं) यदि शेल स्क्रिप्टिंग यह सब कर सकती है।

1
मुझे कभी भी यह एहसास नहीं हुआ कि ओपन-ए को एक फ़ाइल नाम के बिना तर्क के रूप में इस्तेमाल किया जा सकता है। और मैं 90 के दशक की शुरुआत में नेक्स्टस्टेप के बाद से खुले का उपयोग कर रहा हूं! कृपया जवाब के रूप में प्रस्तुत करें ताकि मैं इस पर मतदान कर सकूं। तो हाँ, सही उत्तर 'ओपन -ए <एप्लीकेशन नाम>' का उपयोग करना है
eric
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.