มีวิธีการเติมคำสั่งเปิดอัตโนมัติใน Terminal หรือไม่?


16

ฉันมักใช้open -a คำสั่งใน Terminal เพื่อเปิดแอปพลิเคชันผ่าน ssh ฉันจะทำให้เป็นชื่อแอปพลิเคชันโดยอัตโนมัติได้อย่างไร


คุณใช้เปลือกอะไร
Daniel Beck

2
ฉันคิดว่าวิธีที่รวดเร็วกว่าเล็กน้อยคือการพิมพ์เส้นทางแบบเต็ม (ไปกับฉันสักพักที่นี่ !!) เช่นopen -a /Applications/Textedit.app foo.txt(ฉันคิดว่านั่นคือสิ่งที่คุณพยายามทำ) หากคุณกดแท็บหลัง/Aของ/Applicationsแล้วแท็บอีกครั้งหลังจากที่/Teของ/Textedit.appแล้วที่ควรเติมทั้งสองส่วนสำหรับคุณที่คุณไป ไม่เหมาะฉันยอมรับ แต่อาจจะดีกว่า นี่คือการใช้ Bash
binarybob

คุณสามารถลองทำตามคำแนะนำในตอนท้ายของโพสต์นี้: brettterpstra.com/grabbing-a-mac-apps-icon-advanced-bash-usage-2
Lri

@DanielBeck Bash
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มันได้ ความคิดใด ๆ ที่ผิดปกติ? ดูเหมือนแท็บแทนที่จะเว้นวรรค ...
Daniel Beck

@DanielBeck IFS=$'\n'มันก็หายไป อย่างไรก็ตามฉันแก้ไขคำตอบอีกครั้ง
Lri

ดูดี. สาย +1 สำหรับmdfindแนวคิดนี้ ทำงานได้ดีในการเพิ่มประสิทธิภาพและการแก้ไข CoreServicesอาจเป็นความชอบส่วนตัว มีเหตุผลnospaceอะไรบ้าง? หากมีเพียง 1 โปรแกรมฉันต้องการเปิดไฟล์ต่อไปทันที เพียงแค่การตั้งค่าส่วนตัว? มีความคิดเกี่ยวกับปัญหาการอ้างที่เหลือ AFAICT นั่นเป็นสิ่งเดียวที่เหลือสำหรับการแก้ไขที่เหมาะสม
Daniel Beck

@DanielBeck ฉันมักจะวาง-aธงในตอนท้ายดังนั้นฉันคิดว่า-o nospaceเป็นเพียงการตั้งค่าส่วนตัว บางทีเราควร ping Brett Terpstra หรือบางสิ่งบางอย่างเพื่อเสร็จ nerdfest นี้ ...
Lri

ขอบคุณมาก!! @DanielBeck คุณเช่นกัน ฉันเลือกเวอร์ชั่นของ Lri เพราะความเร็ว น่าเสียดายที่คุณช้าไปหน่อย ขอบคุณมากทั้งคุณ! คุณช่วยฉันได้มากและทำให้ความเร็วเทอร์มินัลเพิ่มขึ้น
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) การสนับสนุนสำหรับพื้นที่หลบหนีเป็นเพียงที่ดีที่จะเสร็จสิ้นไปDVDDVD\ Player


จะไม่mdfind 'kMDItemKind==Application'เร็วกว่านี้ไหม หากcompletion-ignore-caseตั้งค่าไว้ grep น่าจะไม่สนใจตัวพิมพ์ใหญ่เช่นกัน
Lri

@Lri คุณพูดถูก ไม่พบกรณีที่ผลลัพธ์เหล่านี้สร้างความแตกต่าง
Daniel Beck

3

การเติมข้อความอัตโนมัติที่สามารถตั้งโปรแกรมได้เพื่อช่วยเหลือ! ต้องการการคัดลอกจำนวนมากจากโฮมเพจ Bash Completionซึ่งควรค่าแก่การติดตั้งสำหรับมายากลการเติมข้อมูลอัตโนมัติจำนวนมาก ถ้าคุณทำคุณจะต้องใช้ฟังก์ชั่นสุดท้าย ( _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) แต่ไม่ใช่โปรแกรมที่มีอยู่ในนั้น
Daniel Beck

1

สิ่งนี้เปิดใช้งานโดยค่าเริ่มต้นด้วยเชลล์ Zshตราบใดที่คุณเปิดใช้งานเสร็จแน่นอน Zsh รวมอยู่ใน OS X

สิ่งที่คุณต้องทำคือใส่autoload -Uz compinit; compinitใน ~ / .zshrc ของคุณหรือเปิดใช้งานการทำให้เสร็จสิ้นผ่านเมนูการกำหนดค่าการรันครั้งแรก

Zsh ส่วนใหญ่จะเป็น Bash ส่วนใหญ่ดังนั้นคุณไม่ควรเรียนรู้อะไรใหม่ แม้แต่สคริปท์ก็ยังใช้งานได้!

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