【问题标题】:zsh: Command not found (for $EDITOR)zsh:找不到命令(对于 $EDITOR)
【发布时间】:2012-01-08 03:13:39
【问题描述】:

无论出于何种原因,zsh 都不喜欢我为我的$EDITOR 变量设置命令行参数,但据我所知,它不应该是这样的。我见过人们使用

export EDITOR='open -Wn'

在他们的 ~/.zshrc 文件中,但是当我尝试这样做时,我只是收到了投诉。

zsh: command not found: open -Wn

为什么会发生这种情况?将$EDITOR 设置为'mate''vim''open' 似乎可以正常工作,但'mate -w''open -Wn' 不起作用。

我在 Mac OS X 上运行 zsh inside screen,我的 ~/.zshrc 如下:

# -----------------------------------------------
# Screen Settings
# -----------------------------------------------

# If screen isn't already running, turn it on.
if [[ $STY == '' ]]; then
    # Execute screen.
    exec screen -aADRU
fi

# -----------------------------------------------
# Startup Scripts
# -----------------------------------------------

cd ~/Desktop
[[ -s "~/.rvm/scripts/rvm" ]] && source "~/.rvm/scripts/rvm"

# -----------------------------------------------
# Environment Variables
# -----------------------------------------------

export HISTFILE=~/.zsh_history
export HISTSIZE=10000
export HISTCONTROL=ignoredups
export SAVEHIST=10000

export PATH=.:/usr/local/bin:/usr/local/sbin:/usr/local/narwhal/bin:/bin:/sbin:/usr/bin:/usr/local/share:/usr/sbin:/usr/local/texlive/2011/bin/universal-darwin
export EDITOR='open -Wn'
export LC_TYPE=en_US.UTF-8
export LSCOLORS=exFxcxdxAxexbxHxGxcxBx

# -----------------------------------------------
# Prompt
# -----------------------------------------------

## Root Prompt
[ $UID = 0 ] && export PROMPT="%~ +=> " && export RPROMPT="%*"

## General Prompt
[ $UID != 0 ] && export PROMPT="%~ => " && export RPROMPT="%*"

# -----------------------------------------------
# Aliases
# -----------------------------------------------

## Command Aliases
alias ..='cd ..'
alias ...='cd ../..'
alias internet='lsof -P -i -n | cut -f 1 -d " " | uniq'
alias restart='sudo shutdown -r NOW'
alias ls='ls -@1AFGph'
alias tree='tree -alCF --charset=UTF-8 --du --si'
alias mate='mate -w'
alias zshrc='$EDITOR ~/.zshrc && source ~/.zshrc'
alias vimrc='$EDITOR ~/.vimrc.local'
alias gvimrc='$EDITOR ~/.gvimrc.local'

## Root Aliases
[ $UID = 0 ] && \
    alias rm='rm -i' && \
    alias mv='mv -i' && \
    alias cp='cp -i'

# -----------------------------------------------
# User-defined Functions
# -----------------------------------------------

# Usage: extract <file>
# Description: extracts archived files / mounts disk images.
# Note: .dmg/hdiutil is Mac OS X-specific.
extract () {
    if [ -f $1 ]; then
        case $1 in
            *.tar.bz2)  tar -jxvf $1        ;;
            *.tar.gz)   tar -zxvf $1        ;;
            *.bz2)      bunzip2 $1          ;;
            *.dmg)      hdiutul mount $1    ;;
            *.gz)       gunzip $1           ;;
            *.tar)      tar -xvf $1         ;;
            *.tbz2)     tar -jxvf $1        ;;
            *.tgz)      tar -zxvf $1        ;;
            *.zip)      unzip $1            ;;
            *.Z)        uncompress $1       ;;
            *)          echo "'$1' cannot be extracted/mounted via extract()." ;;
        esac
    else
        echo "'$1' is not a valid file."
    fi
}


# Usage: pman <manpage>
# Description: opens up the selected man page in Preview.
pman () {
    man -t $@ | open -f -a /Applications/Preview.app
}

# Usage: fp <name>
# Description: find and list processes matching a case-insensitive partial-match string.
fp () {
    ps Ao pid,comm|awk '{match($0,/[^\/]+$/); print substr($0,RSTART,RLENGTH)": "$1}'|grep -i $1|grep -v grep
}

# Usage: fk <name>
# Description: find and kill a process matching a case-insensitive partial-match string.
fk () {
    IFS=$'\n'
    PS3='Kill which process? (1 to cancel): '
    select OPT in "Cancel" $(fp $1); do
        if [ $OPT != "Cancel" ]; then
            kill $(echo $OPT|awk '{print $NF}')
        fi
        break
    done
    unset IFS
}

# Usage: create <file>
# Description: creates and opens a file for editing.
create () {
    touch $1 && open $1
}

# Usage: reset
# Description: 'resets' the terminal by changing the current working directory
# to the desktop and clearing the screen.
reset () {
    cd ~/Desktop; clear
}

# Usage: quit
# Description: exits the terminal.
quit () {
    killall Terminal
}

# -----------------------------------------------
# zsh Options
# -----------------------------------------------

# Directories
setopt                  \
    AUTO_CD             \
    AUTO_PUSHD          \
    CD_ABLE_VARS        \
    CHASE_DOTS          \
    CHASE_LINKS         \

# Completion
setopt                  \
    AUTO_LIST           \
    AUTO_MENU           \
    AUTO_PARAM_SLASH    \
    COMPLETE_IN_WORD    \
    LIST_TYPES          \
    MENU_COMPLETE       \
    REC_EXACT           \

# History
setopt                  \
    APPEND_HISTORY      \
    EXTENDED_HISTORY    \

# Input/Output
setopt                  \
    CORRECT             \

# Scripts and Functions
setopt                  \
    MULTIOS             \

# Other
setopt                  \
    NO_BEEP             \
    ZLE

# Key Bindings
bindkey "^[[3~" delete-char

# -----------------------------------------------
# zsh Autocompletion
# -----------------------------------------------

# Turn on auto-completion.
autoload -U compinit && compinit -C && autoload -U zstyle+

# Attempt to complete as much as possible.
zstyle ':completion:*' completer _complete _list _oldlist _expand _ignored _match _correct
zstyle ':completion:*::::' completer _expand _complete _ignored _approximate

# Sort files by name.
zstyle ':completion:*' file-sort name

# Allow for case-insensitive completion.
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'

# Color completions.
zstyle ':completion:*' list-colors ${LSCOLORS}
zstyle ':completion:*:*:kill:*:processes' command 'ps -axco pid,user,command'
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'

# Set the amount of completions that triggers the menu.
zstyle ':completion:*' menu select=long

# Ignore certain patterns.
zstyle ':completion:*:functions' ignored-patterns '_*'
zstyle ':completion:*:complete:-command-::commands' ignored-patterns '*\~'
zstyle ':completion:*:*:(^rm):*:*files' ignored-patterns '*?.(o|c~|old|pro|zwc)'

# Cache completions.
zstyle ':completion::complete:*' use-cache 1
zstyle ':completion::complete:*' cache-path ~/.zcompcache/$HOST

# Allow errors.
zstyle -e ':completion:*:approximate:*' max-errors 'reply=( $(( ($#PREFIX+$#SUFFIX)/2 )) numeric )'

# Insert all expansions for expand completer (eh, don't know what this does).
zstyle ':completion:*:expand:*' tag-order all-expansions

# Formatting and messages.
zstyle ':completion:*' list-prompt '%SAt %p: Hit TAB for more, or the character to insert%s'
zstyle ':completion:*' verbose yes
zstyle ':completion:*:descriptions' format '%B%d%b'
zstyle ':completion:*:messages' format '%d'
zstyle ':completion:*:warnings' format 'No matches for: %d'
zstyle ':completion:*:corrections' format '%B%d (errors: %e)%b'
zstyle ':completion:*' group-name ''

# Offer indexes before parameters in subscripts.
zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters

【问题讨论】:

  • Stack Overflow 是一个编程和开发问题的网站。这个问题似乎离题了,因为它与编程或开发无关。请参阅帮助中心的What topics can I ask about here。也许Super UserUnix & Linux Stack Exchange 会是一个更好的提问地点。
  • @jww 这是一个已有 6.5 年历史的问题,答案已被接受。这真的有必要吗?

标签: macos terminal zsh gnu-screen zshrc


【解决方案1】:

你是如何调用 EDITOR 的?如果你设置了带有选项的 EDITOR,那么你会得到一个错误:

$$编辑器文件

但如果你这样做,它应该可以工作:

$ eval $EDITOR 文件

【讨论】:

  • 不用调用eval,你可以专门在这个扩展上开启分词:$=EDITOR file
  • 哇,不知道这是可能的。很棒的提示!
  • @Gilles:你有没有理由没有把它作为答案?这对我来说似乎是最好的答案,我很乐意投票。我很想把它作为答案放在自己身上,但如果我告诉人们对你的评论投赞成票,答案就不容易被看到,因为它会掉到底部。如果人们只是对我的回答投了赞成票,我会觉得我在窃取本应属于你的分数。
  • @iconoclast 我想我觉得威廉的回答已经足够接近了。哦,好吧,我现在已经发布了答案。
【解决方案2】:

调用$EDITOR 定义的编辑器的程序可能假定它引用的整个字符串是命令的名称。所以他们会尝试找到一个名为open -Wn的可执行文件。

另一个问题是 open 仅使用操作系统认为合适的应用程序打开文件。如果没有与该文件类型关联的应用程序,则该命令将失败。

【讨论】:

  • 好吧,这是有道理的,但为什么这对其他人有效,而对我无效?
  • @Itai:我不知道。坦率地说,我很惊讶其他人能做到这一点。
  • 简单地设置 EDITOR="open -Wn" 将在 bash 中工作,因为默认情况下分词是打开的。也许“其他人”没有使用 zsh?
  • 很可能是这样。谢谢,威廉。
【解决方案3】:

在 zsh 中,当你写 $EDITOR 时,它会扩展为一个单词。与其他 Bourne 风格的 shell 不同,zsh 在扩展未加引号的扩展时不会拆分单词。您可以通过 = modifier on parameter expansion.

$=EDITOR $file

更便携的方法是确保EDITOR 不包含任何空格。大多数应用程序将$EDITOR 视为shell sn-p 或以空格分隔的单词列表,但我遇到了一些将其视为命令名称的应用程序。使EDITOR 指向一个shell 脚本。

% cat ~/bin/EDITOR
#!/bin/sh
open -Wn -- "$@"
% grep EDITOR ~/.profile
export EDITOR=~/bin/EDITOR

【讨论】:

  • 谢谢!刚碰到这个试图在zsh中设置EDITOR=emacsclient -c;我不知道 zsh 和 Bash 之间的这种区别。
猜你喜欢
  • 2019-11-25
  • 2016-07-30
  • 2015-07-01
  • 2017-08-09
  • 2016-04-12
  • 2016-06-26
  • 2021-12-15
  • 2016-05-15
相关资源
最近更新 更多