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 '17 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 '17 at 14:50

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 '17 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 '17 at 11:34
  • Wasted another couple of hours on this vague answer. I asked for a complete real-world example because – Terry Feb 9 '17 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 '17 at 17:26

Took bloody hours wading through a bunch of 'not relevant to my situation to create a simple function with a whopping ten points to make it work. If I feel up to it in the next few days I'll try and actually post a proper solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.