![编写有效的 zsh 函数](https://linux22.com/image/104893/%E7%BC%96%E5%86%99%E6%9C%89%E6%95%88%E7%9A%84%20zsh%20%E5%87%BD%E6%95%B0.png)
我必须承认我完全困惑了。我一直在尝试和搜索几个小时但无济于事。我只是无法协调 zsh 和我的个人功能。
$ print -l $fpath
/home/terry/.zsh/functions
以及默认的,这里不需要。
这是我选择放置我的功能的地方。所以我们在这里很好。
/home/terry/.zsh/functions
包含以下文件
-rwxrw-r-- 1 terry terry 274 Feb 6 19:20 _all-files-to-top
-rwxrw-r-- 1 terry terry 253 Feb 6 18:30 _check-for-empty-files
-rwxrw-r-- 1 terry terry 452 Feb 6 18:32 _check-video-duration
-rwxrw-r-- 1 terry terry 302 Feb 6 18:33 _error-1
-rwxrw-r-- 1 terry terry 462 Feb 6 18:34 _error-2
-rwxrw-r-- 1 terry terry 198 Feb 6 18:34 _just-hevc
-rwxrw-r-- 1 terry terry 188 Feb 6 18:36 _just-volume
请注意,我确实按照指示在文件前添加了下划线。
从列表顶部取出一个
#compdef all-files-to-top
#
_all-files-to-top() {
mkdir duplicate_files
mkdir ~/Replace
#
find . -type f -exec mv -n {} ./ \;
find . -empty -type d -delete
while [ -d * ]; do
array=(find . -type d)
for x in $array ; do mv -t duplicate_files "$x" ; done
find . -name "duplicate_files" -exec mv {} ~Replace
return
}
我已经尝试过有和没有#compdef
我已经尝试过#!/bin/zsh
在顶部和下面#compdef
我已经尝试过并且没有#!/bin/zsh
我无法找到任何说明是否使非 root 用户可以执行该文件的信息,因此我尝试将其作为可执行文件和不可执行文件进行尝试。
我还尝试过使用和不使用 _all-files-to-top() { 以及带和不带下划线。
调用该函数开头的程序#!/bin/zsh -xv
直接从终端命令行启动进行调试
这是屏幕打印输出
terry-TP500LA% 2mkv
# /etc/zsh/zshenv: system-wide .zshenv file for zsh(1).
#
# This file is sourced on all invocations of the shell.
# If the -f flag is present or if the NO_RCS option is
# set within this file, all other initialization files
# are skipped.
#
# This file should contain commands to set the command
# search path, plus other important environment variables.
# This file should not contain commands that produce
# output or assume the shell is attached to a tty.
#
# Global Order: zshenv, zprofile, zshrc, zlogin
if [[ -z "$PATH" || "$PATH" == "/bin:/usr/bin" ]]
then
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/games"
fi
+/etc/zsh/zshenv:15> [[ -z /home/terry/scripts/cron:/home/terry/scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin || /home/terry/scripts/cron:/home/terry/scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin == /bin:/usr/bin ]]
#!/bin/zsh -xv
top=$(pwd)
+/home/terry/scripts/2mkv:3> top=+/home/terry/scripts/2mkv:3> pwd
+/home/terry/scripts/2mkv:3> top=/home/terry/New_Videos
# call function
# moves any duplicate files to ~/Replace
mkdir duplicate_files
+/home/terry/scripts/2mkv:8> mkdir duplicate_files
mkdir ~/Replace
+/home/terry/scripts/2mkv:9> mkdir /home/terry/Replace
mkdir: cannot create directory ‘/home/terry/Replace’: File exists
all-files-to-top
+/home/terry/scripts/2mkv:10> all-files-to-top
/home/terry/scripts/2mkv:10: command not found: all-files-to-top
exit 0
+/home/terry/scripts/2mkv:12> exit 0
terry-TP500LA%
哦,还有最后一件事——拼写。我将名称复制到剪贴板中,并在每个实例上使用“查找和替换”。
我真的不知道还能尝试什么。某个好心人能否提供一个函数的真实示例(没有 foo),并解释如何使其正常工作?会不会是类似于脚本或函数中使用的编码方法?我的是UTF-8。
all-files-to-top
+/home/terry/scripts/2mkv:10> all-files-to-top
/home/terry/scripts/2mkv:10: command not found: all-files-to-top
答案1
为了让它发挥作用,您需要做两件事:
您必须告诉
zsh
它应该加载包含该函数的脚本。这可以通过以下命令完成autoload
:autoload -Uz FILENAME
对于您的示例,替换
FILENAME
为_all-files-to-top
按定义函数的名称调用函数:调用
all-files-to-top
不起作用,因为该函数被命名为_all-files-to-top
。开头
_
不会自动删除,也没有任何特殊之处。按照惯例,完成函数(按下 时调用以生成完成的函数Tab)应以 开头_
,以便可以具有有意义的名称,而不会干扰任何命令。由于这似乎不是一个完成函数,因此可能没有真正的理由遵守此约定。 (另外,#compdef
在这种情况下你不需要` )