如何使自定义 zsh 脚本自动可执行?

如何使自定义 zsh 脚本自动可执行?

我一定错过了一些关于如何做到这一点的非常简单的事情,但我有一个简单的脚本:

extract () {
  if [ -f $1 ] ; then
    case $1 in
      *.tar.bz2)   tar xvjf $1    ;;
      *.tar.gz)    tar xvzf $1    ;;
      *.tar.xz)    tar xvJf $1    ;;
      *.bz2)       bunzip2 $1     ;;
      *.rar)       unrar x $1     ;;
      *.gz)        gunzip $1      ;;
      *.tar)       tar xvf $1     ;;
      *.tbz2)      tar xvjf $1    ;;
      *.tgz)       tar xvzf $1    ;;
      *.zip)       unzip $1       ;;
      *.Z)         uncompress $1  ;;
      *.7z)        7z x $1        ;;
      *.xz)        unxz $1        ;;
      *.exe)       cabextract $1  ;;
      *)           echo "\'$1': unrecognized file compression" ;;
    esac
  else
    echo "\'$1' is not a valid file"
  fi
}

该脚本有效,但当我登录时,我似乎无法默认执行它。

我查阅了这个非常彻底的答案:如何在 zsh 中定义并加载自己的 shell 函数,并且我已设法让 $fpath 显示我存储该函数的相应目录。

在我的 .zshrc 配置文件中,我已添加fpath=( ~/.local/bin "${fpath[@]}" )到底部,这是我的函数所在的路径。

当我输入 时echo $fpath,我得到:

/home/me/.local/bin /home/me/.oh-my-zsh/plugins/git /home/me/.oh-my-zsh/functions /home/me/.oh-my-zsh/completions ...

autoload -Uz extract但是,除非我每次登录时明确键入,否则它不起作用。

有没有办法让我在登录时自动加载整个目录?

答案1

您混淆了脚本和函数。

制作脚本

脚本是一个独立的程序。它可能恰好是用 zsh 编写的,但您可以从任何地方调用它,而不仅仅是从 zsh 命令行。如果您碰巧从 zsh 命令行或另一个 zsh 脚本运行用 zsh 编写的脚本,这只是巧合,不会影响脚本的行为。该脚本在自己的进程中运行,它不影响其父进程(例如,它不能更改变量或当前目录)。

您的代码完成一个独立的任务,可以从任何地方调用该任务,并且不需要访问运行它的 shell 的状态,因此它应该是一个脚本,而不是一个函数。

脚本必须是可执行文件:chmod +x /path/to/script.它必须以舍邦线让内核知道使用什么程序来解释脚本。在您的情况下,将此行添加到文件顶部:

#!/usr/bin/env zsh

将文件放入变量中列出的目录中$PATH。许多系统在用户默认值中设置 或~/bin,因此您可以使用它们。如果您想添加其他目录,请参阅~/.local/binPATHhttp://unix.stackexchange.com/questions/26047/how-to- Correctly-add-a-path-to-path

当您键入的命令名称不是别名、函数或内置命令时,shell 会查找该名称的可执行文件$PATH并执行它。因此,您不需要向 shell 声明脚本,只需将其放在正确的位置即可。

制作一个函数

函数是在现有 shell 实例内运行的代码。它可以完全访问所有 shell 的状态:变量、当前目录、函数、命令历史记录等。您只能在兼容的 shell 中调用函数。

您的代码可以作为函数工作,但是通过使其成为函数您不会获得任何东西,并且您失去了从其他地方(例如从文件管理器)调用它的能力。

在 zsh 中,您可以通过将函数的定义包含在~/.zshrc.或者,为了避免.zshrc大量函数造成混乱,您可以使用自动加载机制。自动加载分两步进行:

  1. 用 声明函数名称autoload -U myfunction
  2. myfunction第一次调用时,zsh 会myfunction在 中列出的目录中查找一个名为的文件$fpath,并使用它找到的第一个这样的文件作为 的定义myfunction

所有函数在使用前都需要定义。这就是为什么将文件放入$fpath.使用 声明该函数autoload实际上会创建一个存根定义,其中表示“从中加载该函数$fpath并重试”:

% autoload -U myfunction
% which myfunction
myfunction () {
        # undefined
        builtin autoload -XU
}

Zsh 确实有一种通过探索来生成这些存根的机制$fpath。它嵌入在完成子系统中。

  • #autoload作为文件的第一行。
  • 在您调用完成系统初始化函数之前,.zshrc请确保您已完全设置。fpathcompinit

请注意,包含函数定义的文件必须包含该函数身体,不是函数的定义,因为调用函数时zsh执行的是文件的内容。因此,如果您想将代码放入函数中,则可以将其放入名为的文件中,extract该文件位于 的目录之一中$fpath,包含

#autoload
if [ -f $1 ]; then

如果您希望在加载函数时运行初始化代码,或者定义辅助函数,您可以使用此习惯用法(在 zsh 发行版中使用)。将函数定义以及所有辅助定义和任何其他初始化代码放入文件中。最后,调用函数并传递参数。然后myfunction将包含:

#autoload
my_auxiliary_function () {
}
myfunction () {
}
myfunction "$@"

聚苯乙烯

7z x适用于大多数存档类型。

答案2

有几种方法可以解决此问题:

  • 你可以把这个函数放在你的.zshrc中;
  • 您可以获取您的脚本;
  • 您可以将函数的代码直接放在名为的文件中提炼在您的 PATH 中的目录中。

相关内容