I have a BASH script that's finished, but now I need to add the capability for it to accept plugins.
As an example, the script can move files from one filesystem location to another. It's currently written to utilize the mv command for this, but I want to know how to give the user the option to do two things:
• Replace the mv command with something else, rsync for example
• Redefine the entire "move" function with their improved version of it
I brainstormed for ways to do this after finding little online, but I'm not confident this is the right way.
Idea for "Replace the mv command with something else":
Provide a specification document that defines all the commands (and their associated switches) that can be replaced. I'd imagine it should also assert where/how these adjustments can be made.
Idea for "redefine the entire move function with their improved version of it":
Source a plugin file that contains a function with the same name as the one the user is redefining. I believe this would overwrite the default code for the given function.
I'd like to know the "right way" to implement plugin functionality on a conceptual level, and also how it might be achieved within BASH scripts specifically.
1. Define your interfaces
The most important part is not about the implementation, but about documentation and usage. Each and every tiny detail you rely on has to be communicated to the user.
Some examples for an overwriteable
mvcommand. With the lazy specificationmv: Move "$1" to "$2"your script might break in case ...mv source1 source2 target/mv -n source targetto prevent overwriting an existing filemvoverwrites an existing target without asking and without errors.mvdoes not print anything, for instance invar=$(mv a /tmp/; ls; mv /tmp/a ./).mv sourcedir/ targetdir/andmv sourcedir targetdirto be the same. Hint:rsyncbehavior changes based on trailing slashesWhen you carefully defined a standardized interface, you can think about the implementation.
2. Implement a plugin system
2.1 Using
bash's default behavior (pretty hacky)Technically, you don't have to do anything here, as most commands in bash are already "plugins", that is, executable binaries or script files as specified in the
$PATHvariable.If a user wanted to write their own
mvas a plugin foryour_script.shthey could already run ...... unless
your_script.shoverwrites thePATHagain or defines a functionmvor stuff like that.2.2 Using dedicated names (cleaner)
However, for a cleaner approach, I would define plugins as functions with dedicated names, to emphasize that those are OK to be overwritten:
If the user defines and exports a function with the name
USER_PLUGIN_MV, then that function will be used in instead of the defaultmvcommand.... prints ...
2.3 Using command strings
Alternatively, you could let the user specify command strings (as seen in
xargs,bash -c, or GNUparallel), e.g. ...Those could be implemented as ...
However, nested quotes pose a serious problem to most users once the plugins become bigger. So, if you implemented this system, I still would recommend your users to go with exported functions ...