क्या टर्मिनल में खुली कमांड को ऑटो-पूरा करने का एक तरीका है?


16

मैं अक्सर open -a ssh के माध्यम से एप्लिकेशन खोलने के लिए टर्मिनल में कमांड का उपयोग करता हूं । मैं इसे किसी एप्लिकेशन के नाम को कैसे पूरा करूं?


आप किस खोल का उपयोग कर रहे हैं?
डैनियल बेक

2
मुझे लगता है कि थोड़ा तेज रास्ता पूरा रास्ता टाइप करना होगा (बस कुछ समय के लिए मेरे साथ यहां चलें !!), उदाहरण के लिए open -a /Applications/Textedit.app foo.txt(मुझे लगता है कि आप क्या करने की कोशिश कर रहे हैं)। आप के बाद टैब दबाते हैं /Aके /Applicationsबाद फिर से और फिर टैब /Teकी /Textedit.appतो यह है कि आप के लिए दोनों भागों स्वत: पूर्ण चाहिए के रूप में तुम जाओ। आदर्श नहीं, मैं मानता हूं, लेकिन शायद बेहतर। यह बैश इस्तेमाल कर रहा था।
बाइनरीबोब

आप इस पोस्ट के अंत में दिए गए निर्देशों का पालन कर सकते हैं: brettterpstra.com/grabbing-a-mac-apps-icon-advanced-bash-usage-2
Lri

@ डैनियलबेक बैश।
daviesgeek

जवाबों:


9
_complete_open() {
        COMPREPLY=()
        local cur="${COMP_WORDS[$COMP_CWORD]}"
        local prev="${COMP_WORDS[COMP_CWORD-1]}"
        [[ "$cur" == -* || "$prev" != '-a' ]] && return
        apps="$(mdfind kMDItemKind==Application -onlyin /Applications -onlyin ~/Applications -onlyin /Developer -onlyin ~/Developer | grep -v '/.*/.*/.*/.*/' | sed -E 's|.*/||g;s|\.app$||g' | uniq)"$'Finder\nArchive Utility\nCharacterPalette\nKeyboardViewer'
        local IFS=$'\n'
        if [[ "${cur:0:1}" = '"' || "${cur:0:1}" = "'" ]]; then
            quote="${cur:0:1}"
            cur="${cur:1}"
        fi
        local found="$(grep -i "^$cur" <<< "$apps")"
        if [[ "$quote" == '"' ]]; then
            found="$(sed "s|^|\"|g;s|$|\"|g" <<< "$found")"
        elif [[ "$quote" == "'" ]]; then
            found="$(sed "s|^|'|g;s|$|'|g" <<< "$found")"
        else
            found="$(sed 's| |\\ |g' <<< "$found")"
        fi
        COMPREPLY=($found)
}

complete -o default -F _complete_open open

तीसरा संस्करण, जो अब दोनों असंवेदनशील होना चाहिए और उद्धरणों के भीतर काम करना चाहिए।


मैं इसके साथ काम नहीं कर सका DVD Player। किसी भी विचार क्या गलत है? एक जगह के बजाय एक टैब की तरह दिखता है ...
डैनियल बेक

@DanielBeck यह गायब था IFS=$'\n'। वैसे भी, मैंने उत्तर को फिर से संपादित किया।
13

अछा लगता है। mdfindविचार के लिए एक लेट +1 । अनुकूलन और सुधार पर अच्छा काम किया। CoreServicesहालांकि व्यक्तिगत पसंद कर रहे हैं। nospaceहालांकि इसकी वजह क्या है ? यदि केवल 1 कार्यक्रम है, तो मैं फ़ाइल को खोलने के लिए तुरंत जारी रखना चाहता हूं। सिर्फ व्यक्तिगत पसंद? शेष उद्धरण मुद्दे के बारे में कोई विचार? AFAICT, यह केवल एक उचित समाधान के लिए छोड़ दिया है।
डैनियल बेक

-a@ डैनियलबेक मैंने हमेशा ध्वज को अंत में रखा है, इसलिए मुझे लगता -o nospaceहै कि यह सिर्फ एक व्यक्तिगत प्राथमिकता है। हो सकता है कि हम इस nerdfest को खत्म करने के लिए ब्रेट टेरस्ट्रा या कुछ और पिंग करें ...
Lri

बहुत बहुत धन्यवाद!! @DanielBeck आप भी। मैंने गति के कारण लारी के संस्करण को चुना। दुर्भाग्य से, तुम्हारा थोड़ा धीमा था। आप दोनों को बहुत बहुत धन्यवाद! आपने मेरी बहुत मदद की है और मेरी टर्मिनल की गति को बढ़ाया है।
daviesgeek

7

निम्नलिखित को अपने में जोड़ें .bash_profileया .bashrcएक नया सत्र शुरू करें:

function _complete_open {
    cur=$2
    COMPREPLY=( );

    [[ "$COMP_WORDS" = "open" ]] || return
    [[ "${COMP_WORDS[ $(( $COMP_CWORD - 1 )) ]}" = "-a" ]] || return

    OLDIFS="$IFS"
    IFS=$'\n'
    local _part="${COMP_WORDS[$COMP_CWORD]}"

    if [[ "${_part:0:1}" = '"' || "${_part:0:1}" = "'" ]] ; then
        COMPREPLY=( $( compgen -W "$( mdfind kMDItemKind==Application | sed -e 's|.*/||g' -e 's|.app$||' | sort -u )" -- $cur ) )
    else
        COMPREPLY=( $( compgen -W "$( mdfind kMDItemKind==Application | sed -e 's|.*/||g' -e 's|.app$||' -e 's| |\\\\ |g' | sort -u )" -- $cur ) )
    fi
    IFS="$OLDIFS"
}

complete -o default -F _complete_open open

कुछ भी स्थापित करने की आवश्यकता नहीं है। यह bashबॉक्स से बाहर काम करता है ।


यह केवल स्वत: पूर्ण प्रोग्राम नाम होगा यदि पिछला विकल्प है -aऔर अन्यथा डिफ़ॉल्ट व्यवहार दिखाता है, उदाहरण के लिए वर्तमान निर्देशिका में सभी फ़ाइलों की सूची लौटाएं या वर्तमान पथ उपसर्ग को पूरा करें।

परिणाम उत्पन्न किए जाते हैं system_profiler SPApplicationsDataType, जो उन सभी अनुप्रयोगों को प्राप्त करने का सबसे आसान तरीका है जो आपके सिस्टम पर इस तरह लॉन्च किए जा सकते हैं। सूची को केवल प्रोग्राम नामों को वापस करने के लिए संसाधित किया जाता है, जिसमें रिक्त स्थान हो सकते हैं और बंडल नामों से भिन्न हो सकते हैं (भले ही अनदेखी करने पर .app)

उपयोग: टाइप करें open -a, उसके बाद एक स्पेस, उसके बाद दबाकर Tabया Esc(मेरे सिस्टम पर दो बार, सुनिश्चित नहीं है कि यह हर जगह है)।

मेरे स्कैनर के लिए सभी सहायक अनुप्रयोगों को दिखाने वाला उदाहरण:

$ open -a Scan
Scan to E-mail          Scan to Excel           Scan to Folder          Scan to Print           Scan to Searchable PDF  Scan to Word            ScanSnap Manager

इस समाधान की कमियां और समस्याएं:

  • आपके सिस्टम पर ऐसे कई कार्यक्रम हैं जिनके बारे में आपको जानकारी नहीं होगी, जैसे कि सब कुछ /System/Library/CoreServices। आप उन सभी को सूचीबद्ध नहीं करना चाह सकते हैं। OTOH, उदाहरण के लिए CharacterPaletteऔर KeyboardViewerइस तरह से देखना और लॉन्च करना वास्तव में आसान है । * तर्क से mdfindकॉल (ओं) को उचित रूप से कॉन्फ़िगर करें -onlyin

  • यह धीमी गति के कारण है system_profiler SPApplicationsDataType। शो पूरा होने से पहले आपको एक या दो इंतजार करना पड़ सकता है। अब mdfindजल्दी से प्रोग्राम प्राप्त करने के लिए उपयोग करता है। धन्यवाद @Lri

  • यह एप्लिकेशन नामों और रिक्त स्थान संलग्न प्रोग्राम नामों में रिक्त स्थान को संभाल सकता है, लेकिन यह हैक करने योग्य है। इसके लिए पहले वर्ण का होना आवश्यक है: जबकि Scan" to "Pयह मान्य है bash, यह प्रोग्राम इसका पता नहीं लगाएगा। पूर्णता बची हुई जगह (जैसे Scan\ to) के बाद काम नहीं करता है , ऐसे मामलों में उद्धरण चिह्नों का उपयोग करें ( "Scan to)। बची हुई जगहों के लिए समर्थन केवल पूरा DVDकरने के लिए अच्छा है DVD\ Player


mdfind 'kMDItemKind==Application'तेजी से नहीं होगा ? यदि completion-ignore-caseसेट किया गया है, तो जीआरईपी को संभवतः मामले को भी अनदेखा करना चाहिए।
लारी

@Lri आप सही कह रहे हैं। एक ऐसा मामला नहीं खोजा जा सका है जहाँ इन परिणामों से फर्क पड़ा हो।
डैनियल बेक

3

बचाव के लिए प्रोग्राम करने योग्य स्वत: पूर्णता! हालांकि बैश कम्प्लीशन होमपेज से बहुत सारी नकल की आवश्यकता थी , जो कि बहुत सारे ऑटो-पूर्ण जादू के लिए वैसे भी स्थापित करने के लायक है। यदि आप करते हैं, तो आपको केवल अंतिम फ़ंक्शन ( _open) और नीचे से शुरुआती कमांड की आवश्यकता होगी ।

निम्नलिखित जोड़ें .bashrc:

# taken from http://bash-completion.alioth.debian.org/

_compopt_o_filenames()
{
    # We test for compopt availability first because directly invoking it on
    # bash < 4 at this point may cause terminal echo to be turned off for some
    # reason, see https://bugzilla.redhat.com/653669 for more info.
    type compopt &>/dev/null && compopt -o filenames 2>/dev/null || \
        compgen -f /non-existing-dir/ >/dev/null
}

_tilde() {
    local result=0
    # Does $1 start with tilde (~) and doesn't contain slash (/)?
    if [[ ${1:0:1} == "~" && $1 == ${1//\/} ]]; then
        _compopt_o_filenames
        # Try generate username completions
        COMPREPLY=( $( compgen -P '~' -u "${1#\~}" ) )
        result=${#COMPREPLY[@]}
    fi
    return $result
}

_quote_readline_by_ref()
{
    if [[ ${1:0:1} == "'" ]]; then
        if [[ ${BASH_VERSINFO[0]} -ge 4 ]]; then
            # Leave out first character
            printf -v $2 %s "${1:1}"
        else
            # Quote word, leaving out first character
            printf -v $2 %q "${1:1}"
            # Double-quote word (bash-3)
            printf -v $2 %q ${!2}
        fi
    elif [[ ${BASH_VERSINFO[0]} -le 3 && ${1:0:1} == '"' ]]; then
        printf -v $2 %q "${1:1}"
    else
        printf -v $2 %q "$1"
    fi

    # If result becomes quoted like this: $'string', re-evaluate in order to
    # drop the additional quoting.  See also: http://www.mail-archive.com/
    # bash-completion-devel@lists.alioth.debian.org/msg01942.html
    [[ ${!2:0:1} == '$' ]] && eval $2=${!2}
} # _quote_readline_by_ref()

_filedir()
{
    local i IFS=$'\n' xspec

    _tilde "$cur" || return 0

    local -a toks
    local quoted tmp

    _quote_readline_by_ref "$cur" quoted
    toks=( ${toks[@]-} $(
        compgen -d -- "$quoted" | {
            while read -r tmp; do
                printf '%s\n' $tmp
            done
        }
    ))

    if [[ "$1" != -d ]]; then
        # Munge xspec to contain uppercase version too
        [[ ${BASH_VERSINFO[0]} -ge 4 ]] && \
            xspec=${1:+"!*.@($1|${1^^})"} || \
            xspec=${1:+"!*.@($1|$(printf %s $1 | tr '[:lower:]' '[:upper:]'))"}
        toks=( ${toks[@]-} $( compgen -f -X "$xspec" -- $quoted) )
    fi
    [ ${#toks[@]} -ne 0 ] && _compopt_o_filenames

    COMPREPLY=( "${COMPREPLY[@]}" "${toks[@]}" )
} # _filedir()

# only the following is needed if bash-autocompletion is already installed
_open ()
{
    local cur;

    cur=$2;

    COMPREPLY=();
    if [ $COMP_CWORD -eq 2 ]; then
        COMPREPLY=($(compgen -W "$(/bin/ls /Applications)" -- $cur ));
        return 0
    fi

    _filedir
}

complete -F _open open

इसलिए मैंने इंस्टॉल निर्देशों का पालन किया और कोड को इसमें जोड़ा .bashrc। अब मैं इसे स्वतः पूर्ण कैसे करूं? मैं स्वतः पूर्ण करने के लिए क्या धक्का दे सकता हूं? (क्षमा करें, मैं कोड नहीं पढ़ सकता)
daviesgeek

1
रिक्त स्थान (जैसे DVD Player.app) के साथ प्रोग्राम के नाम को हैंडल नहीं करता है । निर्देशिकाओं /Applicationsको भी (जैसे iWork 09, अलग-अलग प्रविष्टियों के रूप में ) iWorkऔर सूचीबद्ध करता है 09, लेकिन इसमें निहित कार्यक्रम नहीं हैं।
डैनियल बेक

1

यह Zsh शेल के साथ डिफ़ॉल्ट रूप से सक्षम हो जाता है , जब तक कि आपने स्वयं को पूरा कर लिया है, तब तक। Zsh OS X में शामिल है।

आपको केवल autoload -Uz compinit; compinitअपने ~ / .zshrc में डालना है, या पहले रन कॉन्फ़िगरेशन मेनू के माध्यम से पूरा करने में सक्षम करना है।

Zsh वास्तव में ज्यादातर बैश का सुपरसेट है, इसलिए आपको कुछ भी नया नहीं सीखना चाहिए। यहां तक ​​कि आपकी स्क्रिप्ट भी शायद काम करेगी!

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