Scripting

如何使自定義 zsh 腳本自動執行?

  • March 9, 2018

我一定錯過了一些關於如何做到這一點非常簡單的事情,但我有一個簡單的腳本:

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 編寫的,但您可以從任何地方呼叫它,而不僅僅是從 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/bin``PATH

當您鍵入一個不是別名、函式或內置命令的命令名時,shell 會在其中查找具有該名稱的執行檔$PATH並執行它。因此,您無需向 shell 聲明腳本,只需將其放在正確的位置即可。

製作函式

函式是在現有 shell 實例中執行的程式碼。它可以完全訪問所有 shell 的狀態:變數、目前目錄、函式、命令歷史記錄等。您只能在兼容的 shell 中呼叫函式。

你的程式碼可以作為一個函式工作,但是你不會通過把它變成一個函式來獲得任何東西,並且你失去了從其他地方(例如從文件管理器)呼叫它的能力。

在 zsh 中,您可以通過在~/.zshrc. 或者,為了避免.zshrc大量函式的混亂,您可以使用自動載入機制。自動載入分兩步進行:

  1. 用 聲明函式名autoload -U myfunction
  2. 第一次呼叫時,zsh會在 中列出的目錄中myfunction查找呼叫的文件,並將找到的第一個此類文件用作 的定義。myfunction``$fpath``myfunction

所有功能都需要在使用前定義。這就是為什麼將文件放入$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適用於大多數檔案類型。

引用自:https://unix.stackexchange.com/questions/429169