Search code examples
cbashcddistributebuilt-in

Distributing loadable builtin bash modules


I've written a built-in for bash which modifies the 'cd' command, a requirement for my software. Is there a way to actually distribute a loadable independently of bash itself? I'd ideally like to distribute just a drop in "additional feature" because I know people can be put off by patching and compiling their shell from source code.

I want to time how long a user is in a directory so I can determine where they want to be. It's this functionality: http://github.com/joelthelion/autojump/tree/master rewritten as a bash builtin, for performance issues. This implementation uses $PROMPT_COMMAND to work but I wanted something integrated.


Solution

  • It is unclear what you have modified but in any case, bash (like at least ksh93 which IIRC introduced the concept and zsh) supports, using the enable -f file name syntax, loading built-in functions as external dynamically loaded modules.

    These modules being plain files can certainly be distributed independently, as long as you make sure they are compatible with the target version/architecture. This was already true 5 years ago when you asked this question.

    One issue in your case is there seems to be no documented way to overload a internal built-in like cd by a dynamically loaded one while keeping the ability to access the former.

    A simple workaround would be to implement your customized cd with a different name, say mycd, like this:

    int mycd_builtin(list)
    WORD_LIST *list;
    {
      int rv;
      rv=cd_builtin(list);
      if(rv == EXECUTION_SUCCESS) {
        char wd[PATH_MAX+1];
        getcwd(wd,sizeof(wd));
        // do your custom stuff knowing the new working directory
        ...
      }
      return (rv);
    }
    

    then to use an alias, or better, a shell function for your customized version to be used instead of the regular one:

    cd() {
      mycd "$@"
    }
    

    As long as your customization doesn't affect the behavior of the standard command and thus doesn't risk breaking scripts using it, there is nothing wrong in your approach.