AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 429169
Accepted
Ryan Ward
Ryan Ward
Asked: 2018-03-09 22:06:55 +0800 CST2018-03-09 22:06:55 +0800 CST 2018-03-09 22:06:55 +0800 CST

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

  • 772

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

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
}

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

我已经查阅了这个非常彻底的答案:How to define and load your own shell function in zsh,我已经设法让我的 $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但是,除非我每次登录时都明确输入,否则它不起作用。

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

zsh scripting
  • 2 2 个回答
  • 21177 Views

2 个回答

  • Voted
  1. Best Answer
    Gilles 'SO- stop being evil'
    2018-03-10T03:59:59+08:002018-03-10T03:59:59+08:00

    您正在混淆脚本和函数。

    制作脚本

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

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

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

    #!/usr/bin/env zsh
    

    将文件放在$PATH变量中列出的目录中。许多系统都设置了用户的默认值~/bin或默认值,因此您可以使用这些。如果要添加另一个目录,请参阅http://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path~/.local/binPATH

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

    制作函数

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

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

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

    1. 用 声明函数名autoload -U myfunction。
    2. 第一次调用时,zsh会在 中列出的目录中myfunction查找调用的文件,并将找到的第一个此类文件用作 的定义。myfunction$fpathmyfunction

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

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

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

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

    注意包含函数定义的文件必须包含函数体,而不是函数的定义,因为调用函数时zsh执行的是文件的内容。所以如果你想把你的代码放在一个函数中,你可以把它放在一个名为的文件中,该文件extract位于 上的一个目录中$fpath,包含

    #autoload
    if [ -f $1 ]; then
    …
    

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

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

    附言

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

    • 15
  2. rools
    2018-03-09T23:46:17+08:002018-03-09T23:46:17+08:00

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

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

相关问题

  • 启动应用程序的问题:命令行与 gui

  • 用于在日志文件中查找字符串的 Shell 脚本

  • 如何在`zsh`中增加一个动态命名的变量

  • 为什么我不能在 zsh 中定义一个名为 path 的只读变量?

  • 根据其中的值批量重命名(附加)CSV 文件

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve