I must admit I am completely baffled. I have been trying and searching for hours to no avail. I just can't reconcile zsh and my personal functions.

$ print -l $fpath

as well as the default ones, which aren't needed here.

This is where I have chosen to place my functions. So we're good here.

/home/terry/.zsh/functions contains the following files

-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

Please note that I have indeed prefixed the files with underscores as instructed.

Taking the one from the top of the list

#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

I have tried it with and without #compdef
I have tried it with #!/bin/zsh
At the top and below #compdef
and I've tried it and without #!/bin/zsh

I was unable to find anything that said whether or not to make the file executable by non-root users, so I've tried it as executable and as not executable.

I've also tried it with and without the _all-files-to-top() { both with and without the underscore.

The program calling the function begins with #!/bin/zsh -xv is started directly from the command line in terminal for debugging

Here is the screen printout

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" ]]
    export PATH="/usr/local/bin:/usr/bin:/bin:/usr/games"
+/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

+/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
+/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

Oh, and one last thing - spelling. I copied the name into the clipboard and used 'find and replace' on every instance.

I really don't know what else to try. Could some kind soul provide a real world example (no foo) of a function with an explanation of what is needed to make it work properly? Could it be something like the coding method used in the script or function? Mine is UTF-8.

+/home/terry/scripts/2mkv:10> all-files-to-top
/home/terry/scripts/2mkv:10: command not found: all-files-to-top
  • #compdef is part of the completion system, but it doesn't look like you are trying to write completion functions here.
    – Wieland
    Feb 7, 2017 at 14:18
  • Couldn't sleep. Just wasted a couple more hours with nothing to show for it. Will someone please post an actual real world, non-foo zsh function and answer the questions at the top of the page? Do I chmod 664 the function. Yes or no.
    – Terry
    Feb 8, 2017 at 14:50

1 Answer 1


In order to get this to work, you need to do two things:

  1. You have to tell zsh that it should load the script with the function in it. This can be done with the autoload command:

     autoload -Uz FILENAME

    For your example replace FILENAME with _all-files-to-top

  2. Call the function by the name with which it is defined: Calling all-files-to-top does not work because the function is named _all-files-to-top.

    The starting _ is not removed automatically nor is it in any way special. Convention has it, that completion functions (Those functions called to generate completions when pressing Tab) should start with _ so that can have meaningful names without interfering with any commands. As this does not seem to be a completion function, there is probably no real reason to adhere to this convention. (Also, you do not need #compdef in that case`)

  • Ok, the using autoload was a given, but I really don't remember if I prefixed the filename with the underscore. Probably not as I remember LOTS of attempts without it. I'll ask this quick follow-up out of a combination of laziness and lack of sleep. Do I also prefix with the underscore when calling it from a script? The solution is binary, either yes or no. A vast improvement over my previous status. I will test this out after a few zzzzzs and (hopefully) report an unqualified success. Thanks for taking time to help a knuckle-dragger like myself.
    – Terry
    Feb 8, 2017 at 11:17
  • A quick re-read just answered my own question. Yes, prefix the filename with an underscore when calling a function from within a script.
    – Terry
    Feb 8, 2017 at 11:34
  • Wasted another couple of hours on this vague answer. I asked for a complete real-world example because
    – Terry
    Feb 9, 2017 at 17:15
  • Wasted another couple of hours on this vague answer. I asked for a complete real-world example because due to a certain medical condition my thought processes occasionally get cloudy and when i get an 'all you have to do' type reply Its like watching a movie that is half over and having to figure out what went on before. I started scripting to keep my mind active but right now I'm over my head. So, anybody up for it?
    – Terry
    Feb 9, 2017 at 17:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .