1

I've developed several utility scripts that solve specific problems of my team's day-to-day work.

Up to now, what I have done to deploy the script in my co-workers' laptops is as follows:

  • Every solution has a main.sh script (as well as other scripts and supporting files)
  • Create a folder in the user's home folder and put the files there
  • Add an alias either to .bashrc or .bash_aliases, depending on the Linux distribution, pointing to the main.sh script
  • Copy autocompletion file to /etc/bash_completion.d/ (completion file name is the same as the alias plus .auto extension).
  • Copy man page to /usr/share/man/man1/ then gzipping it (man file name is the same as the alias plus .1 extension).

I would like to create an installer but the alias part is tricky.

  • Is there a better option that would also allow for automation (installer)?
  • Maybe putting a soft link to main.sh file in /usr/local/bin instead of creating aliases?
  • Is there a best practice for this?
  • 1
    Using a proper build system like Cmake or autotools, plus packaging code as a binary package is a good start. Of course, it does depend on what you are trying to do. Single scripts don't necessarily need packages. – Faheem Mitha Feb 10 '15 at 21:49
2

Well, it is not terribly difficult to work in an init feature into a shell function. For example:

fn(){ 
    echo first time called\!
    fn(){ 
        echo not the first time called\!
    }
}
fn; fn; fn

...will print...

first time called!
not the first time called!
not the first time called!

You can also define shell aliases in a function, or source files, or any manner of things - you can do pretty much anything with the current shell's state that you can also do at the prompt except affect its positional parameters (though even that can be worked around with aliases).

So it could be a good idea to source your installations as .fn.name (or whatever) files and then to call them once in the rc file - where the initial call to the function handles all its own setup as necessary and then redefines itself for all calls thereafter.

Or, similar to some shells will do with autoload, you can create a one-line function that is defined every time the rc file is read like:

printf '%b' '[ -f ~/.fn_name ] &&\n\tfn_name(){ . ~/.fn_name; }\n' >>~/.bash.rc

...and within ~/.fn_name...

fn_name(){ : now redefine the function; }

...in that way the fn_name will use hardly any shell state at all until it is first called, it will not clutter the .bash.rc terribly, and can be easily managed.

It might be easier, though, to put all of those types in a single ~/.fn file and, to source it from the main rc, and then to source each individual from out of it.

  • +1 But that would be tricky to automate in an installer, because running the installer more than once would insert the entry several times in the rc file. – Tulains Córdova Feb 10 '15 at 18:27
  • 1
    @user1598390 - well, not necessarily. You can do a grep -q fn_name <~/.fn && ... test first, or something like - or just do [ -f ~/.fn_name ] || install - so long as you set up some rules that you can abide by you can do the tests pretty easily. – mikeserv Feb 10 '15 at 23:18
  • I haven't accepted this answer after so long, because I don't fully understand it. Would you please make it a little more easy ti digest? Perhaps not asumming that I know certain concepts. O perhaps explaining where exactly to copy things. – Tulains Córdova Aug 11 '16 at 11:48

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.