spiff
spiff

Reputation: 328

Shell files referencing other shell files and the best way to call them

So I've been dying to ask this but didn't want to risk losing reputation over it, however at this point I really need some direct input. I'm a Linux newb, using a Raspberry Pi to set up a LAMP server and I like creating shell files of all my installation commands, but I also like keeping things modular, for example:

#!/bin/sh
#LAMPinstall.sh
./apacheinstall.sh
./mysqlinstall.sh
./phpinstall.sh

I'm used to coding environments where such calls are trivial, but the obvious problem with this script is it requires the current working directory to be the script's directory at the time of the call.

I did a lot of Linux-specific reading on absolute vs relative paths, sourcing vs calling, bash vs shell, and various methods to cite the path of a script as a solution to relative path calls outside the CWD, but at the end of the day I came no closer to a solution I feel good about, and maybe never will. For now I'm content with using absolute paths stored in a variable, such as:

#!/bin/sh
#LAMPinstall.sh
thisdir=/path/to/scripts
${thisdir}/apacheinstall.sh
${thisdir}/mysqlinstall.sh
${thisdir}/phpinstall.sh

even though I'd have to modify the script each time the path changes.

So my question is more of a best practice question than asking for a solution to a particular problem (although it is a specific problem), to cover the following altogether instead of the articles and questions I read about each individual piece:

  1. Is it a bad idea to organize calls to shell scripts in the manner I'm using?
  2. Is it a bad idea to cite the path of a script using something like $(dirname "$0"). If so, how else would you maintain the organization of multiple shell files?
  3. When making considerations such as #2, is it important to consider all possible uses of your script (i.e.: if there are subdirectories and it's sourced) by someone else, or is it enough to say "This script must only be called, not sourced, if someone misuses it then it's on them." Sorry I couldn't phrase that any better.

Also, please forgive me if this is a naive question, I would just really like some input on this.

Upvotes: 3

Views: 585

Answers (1)

tripleee
tripleee

Reputation: 189527

The shell does not offer very sophisticated facilities for maintaining a library of related scripts. Common hacks include your suggested or at least implied

#!/bin/sh
here="$(dirname "$0")"
"$here"/apacheinstall.sh
"$here"/mysqlinstall.sh
"$here"/phpinstall.sh

or somewhat similarly

#!/bin/sh
PATH="$(dirname "$0")":$PATH
apacheinstall.sh
mysqlinstall.sh
phpinstall.sh

or requiring the user to set a suitable variable:

#!/bin/sh
: ${LAMP_INSTALL_PATH?Need this variable to be set}
"$LAMP_INSTALL_PATH"/apacheinstall.sh
"$LAMP_INSTALL_PATH"/mysqlinstall.sh
"$LAMP_INSTALL_PATH"/phpinstall.sh

A similar related technique is to default to something like /usr/local/lib/lampinstall and allow the user to override this path by similar means.

#!/bin/sh
: ${LAMP_INSTALL_PATH=/usr/local/lib/lampinstall}
"$LAMP_INSTALL_PATH"/apacheinstall.sh
"$LAMP_INSTALL_PATH"/mysqlinstall.sh
"$LAMP_INSTALL_PATH"/phpinstall.sh

Of course, with any reasonably modern distro, the real solution for this particular problem is to package the stuff you need into a package, and just install that. On Debianish platforms, for example,

sudo apt install -y local-lamp-stuff

where you simply need to create local-lamp-stuff.deb and have it Depends: on the packages you need as prerequisites.

Upvotes: 2

Related Questions