open -a
터미널 의 명령을 자주 사용하여 ssh를 통해 응용 프로그램을 엽니 다. 응용 프로그램 이름을 자동 완성하려면 어떻게해야합니까?
답변
_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
세 번째 버전은 대소 문자를 구분하지 않으며 따옴표 내에서 작동합니다.
답변
다음을 추가 .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
(2 회 내 시스템에, 확실하지가 사방의 경우).
스캐너의 모든 도우미 응용 프로그램을 보여주는 예 :
$ 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
. 완료가 표시되기 전에 1-2 초 정도 기다려야 할 수도 있습니다.mdfind
프로그램을 빨리 얻는 데 사용 합니다. 감사합니다 @Lri -
응용 프로그램 이름의 공백과 따옴표로 묶인 프로그램 이름을 처리 할 수 있지만 다소 해킹 적입니다. 따옴표는 첫 번째 문자 여야합니다.
Scan" to "P
에서 유효 하지만bash
이 프로그램은 따옴표를 감지하지 않습니다. 이스케이프 된 공간 (예 🙂 이후에는 완료가 작동하지 않습니다 (예 :Scan\ to
따옴표"Scan to
). 탈출 한 공간에 대한 지원은 완료DVD
하기 만하면 됩니다DVD\ Player
.
답변
구조에 프로그램 가능한 자동 완성! Bash Completion Homepage 에서 많은 사본이 필요 했지만 자동 완성 마법을 많이 사용하려면 설치해야합니다. 그렇게하면 마지막 함수 ( _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
답변
이 온다 zsh을 쉘 기본적으로 설정 만큼 당신이 자체는 물론, 활성화 완료를 가지고. Zsh는 OS X에 포함되어 있습니다.
당신이해야 할 모든 투입 autoload -Uz compinit; compinit
에 ~ / .zshrc, 또는 첫 번째 실행 구성 메뉴를 통해 완료 할 수 있습니다.
Zsh는 실제로 대부분 Bash의 상위 집합이므로 새로운 것을 배울 필요가 없습니다. 심지어 당신의 스크립트도 작동 할 것입니다!