Reputation: 328
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:
$(dirname "$0")
. If so, how else would you maintain the organization of multiple shell files?Also, please forgive me if this is a naive question, I would just really like some input on this.
Upvotes: 3
Views: 585
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