ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm having trouble getting make to recognize shell aliases to commands and I don't know why. Any help would be appreciated. Here's what I've tried so far.
Whenever I execute make, I never see that install is aliased elsewhere. Of the methods I've tried:
1. First attempt -- encapsulated shell script (plain jane aliases)
contents of ~/scripts/soft_install.bash
Code:
#!/bin/bash
alias install='sudo /path/to/special/install'
make SHELL=/bin/bash install
unalias install
2. Second attempt -- startup files and environment variables
Because make starts a sub-shell for each command, I thought to try putting the alias in startup files (triggered by an environment variable).
contents of ~/scripts/soft_install2.bash:
Code:
#!/bin/bash
SOFTWARE_INSTALL=yes
make SHELL=/bin/bash install
unset SOFTWARE_INSTALL
abbreviated contents of ~/.bashrc:
Code:
if [ -n ${SOFTWARE_INSTALL} ] ; then
alias install='sudo /path/to/special/install'
fi
3. Third attempt -- more startup files
Started grasping a straws here. I worried about how make was starting each sub-shell (regarding POSIX compliance). So I linked ~/.profile to ~/.bash_profile. ~/.bash_profile in turn sources ~/.bashrc above.
4. Fourth attempt -- more straw-grasping
I set the ENV environment variable to point to ~/.bashrc thinking (again) that a POSIX problem might be involved.
cotents of ~/scripts/soft_install3.bash:
Code:
#!/bin/bash
ENV=/home/compile/.bashrc
make SHELL=/bin/bash install
unset ENV
In ALL cases, I get the following output from make:
Code:
alias
which install
/usr/bin/install
SHELL = /bin/bash
install -d /home/compile/install_test
The directory is created, but not with the proper install executable. The "special" version of install displays a debug message when invoked.
I'm at wit's end here. I need to have make see the aliases and I want it to be transparent--that is, no modification of the Makefile necessary. My bag of tricks is empty, and unless someone here saves me, I may have to open the make source code to see why in the world it absolutely refuses to take the aliases.
For those that must know, I've hacked some of the coreutils programs (chgrp, chmod, chown, cp, install, mkdir, mv, and rm) to accept new arguments: --allow-src-path=<arg>, --allow-dst-path=<arg>, --allow-path=<arg>. If any of the programs that support these arguments try to operate on a file outside the allowed path(s), the program fails. I install each package into its own directory, and I don't want anything to go outside that directory: config files, "share" files, executables, etc. Those arguments ensure that the files get put in the proper directory or the make install fails.
And then I get to gripe at the developers for not honoring the --prefix option to the configure script.
Last edited by Dark_Helmet; 02-23-2007 at 03:05 PM.
I'm having trouble getting make to recognize shell aliases to commands and I don't know why.
Bash aliases aren't normally expanded in non-interactive shells, and I think it's safe to assume that shells started by make are non-interactive. Try putting "shopt -s expand_aliases" in the script, before the alias is used.
Thanks for the reply. Interactive vs. non-interactive shells has never been something I've felt comfortable with.
Anyway, I gave your suggestion a try, but the shopt option isn't preserved when I invoke make. I tried inserting "shopt -s expand_aliases" in the script of my original message and in my ~/.bashrc. I also added this line to Makefile:
Code:
<tab>shopt | grep expand_aliases
The output:
Code:
$ ~/scripts/soft_install.bash
shopt | grep expand_aliases
expand_aliases off
aliases
which install
/usr/bin/install
...
$ shopt | grep expand_aliases
expand_aliases on
Any ideas?
EDIT: Wow... I decided to add "shopt -s expand_aliases" to Makefile. It changed nothing.
shopt -s expand_aliases
shopt | grep expand_aliases
expand_aliases off
alias
which install
/usr/bin/install
install -d /home/compile/install_test
EDIT2:
After reading the bash man page, I may try to change the aliases into functions and export them with "export -f". That'll have to wait until later though.
Last edited by Dark_Helmet; 02-23-2007 at 04:29 PM.
Yuck. Why do you *have* to do it this way, and not just the normal approach of using enviroment variables to hold various aspects of the build configuration and use make -e so that the enviroment overrides whatever is in the Makefile?
The problem is this: the traditional software compile/install routine wants root to execute "make install". When root does this, files can go anywhere, regardless of what the --prefix argument was set to with the configure script. I don't want that. I want every piece of software tucked into its own directory. Installing as a non-root user will give a "permission denied" error if any file tries to stray from the specified --prefix path.
Then the custom coreutils commands are what allow the install to set appropriate permissions and ownerships to installed files. I give the non-root user the ability to execute those commands as root with sudo, but only with appropriate limits: the destination and source directories must be specified and file operations are limited to only those directories.
There are very respectable software packages that don't honor --prefix completely. The ntp client being one (it wants to install its config file in /etc regardless of --prefix value).
I'll take a look at the -e option, but if memory serves, I think it's possible for the Makefile to override the -e. And I'm not sure what the scope of the environment settings imported are.
Sorry, I don't think I understood what you were asking at first. I re-read the make manual, and I must have been confused. There doesn't seem to be any indication that the Makefile can override the -e option (except maybe the SHELL environment variable).
So I experimented, and I can get the setup I need (I think) by using the -e, but it's still a two-step process.
I have to set environment variables for the functions to work properly. That becomes tedious quickly because I need to set three, sometimes four, environment variables. And that has to be done each time I want to install a new package. So I created an alias that sources a file to adjust the variables. So it becomes something like this:
In that version, the environment for the compile user isn't modified, giving regular access to the traditional versions of the chgrp, chmod, chown, cp, install, mv, and rm commands.
If I still haven't answered your question (i.e. don't understand what you were getting at), or if you have an alternative, please let me know.
Last edited by Dark_Helmet; 02-24-2007 at 07:55 PM.
Hmm, there may be a way for a Makefile to override -e, call itself recursively. This sounds like a yucky problem, so I suppose a yucky solution fits. How would you handle a Makefile calling install directly by /usr/bin/install or whatever? The ultimate solution to this problem may be a chroot jail-like thing.
I'd thought of trying the chroot thing, but ultimately decided it wasn't efficient. The chroot environment must be updated after any system change--whether it be a newly installed piece of software (a dependency) or a configuration file change (such as ld.so.conf). Essentially your system occupies twice the normal space--one for each copy because you can't symlink outside the chroot. So there's aggravation in keeping the chroot environment current and in reduced disk space.
It's funny you mention the /usr/bin/install thing, because my first prime-time test was compiling and installing rsync, and its Makefile uses /usr/bin/install. Fortunately, they made variables for it (broken into INSTALLCMD and INSTALLMAN) and I could change those values from the command line. But I imagine I'll have to inspect the Makefiles of each package to see if any changes are needed. I'll likely start making modifications to the Makefile and save the changes as patches. The grand idea being that I might be able to use the same patch on a later release. Or I might send in the patch to the devs and attempt to convince them that they should change their style, or use variables like rsync.
I only plan to inspect the Makefile on failures. I'm about to wrap all the above stuff into yet another script. The script will extract the source, configure it, compile, install to a directory inside the compile user's home directory, and run some checks. Specifically, did the install exit with non-zero result and are any of the installed files not owned by root. If so, then something didn't go according to plan and the Makefile needs to be modified. If all is successful, it re-configures, re-makes, and installs in the proper location.
At least, that's how it will work in theory...
I'll look into installwatch and unionfs. I hadn't heard of either. Thanks.
Hmm, this kind of work would be really, really useful in src2pkg to do the whole packaging process as a normal user, than only install the package as superuser. src2pkg doesn't support generating RPMs (yet), so it's not so useful to a RPM distro user as yourself.
(mumbles and grumbles about pains with RPM-based distros...)
Well this is for my LFS system. In fact, I need to update my profile because I don't have FC4 installed anywhere. So yeah, this is all source-based installation. I'll take a look at what gnashley has come up with.
In fact, he was helping me out before. The problem I'm trying to solve here is step 1 in a larger goal of a general change in filesystem structure. The next step is to hack at bash to modify how executables are found. Instead of PATH pointing to each bin directory, it will point to directories containing a collection of installed packages--each package having a bin subdirectory.
Who knows, I may actually be able to contribute something useful to his project
$ ~/scripts/soft_install.bash
shopt | grep expand_aliases
expand_aliases off
aliases
which install
/usr/bin/install
...
The "which" command is a program that is external to bash and doesn't know anything about aliases or shell functions. In bash, you should always use "type" instead of "which" if you want to see whether a command is aliased.
Quote:
Originally Posted by Dark_Helmet
EDIT: Wow... I decided to add "shopt -s expand_aliases" to Makefile. It changed nothing.
One solution would be to invoke bash as an interactive shell by using the -i option, and also perhaps use the --rcfile option to specify a startup file that contains your aliases. In this case, you'd have something like
Code:
SHELL=/bin/bash --rcfile my_aliases -i
in your Makefile.
Or you could just set BASH_ENV to the value of a file that contains aliases and the "shopt -s expand_aliases" command. BASH_ENV is used to to determine the startup file for a non-interactive shell; by default no startup files are used (don't forget to export BASH_ENV). Check the "Bash Startup Files" section of the bash reference manual for more info. I think that this approach is a little cleaner than forcing the shell into interactive mode, because the latter might have some unintended consequences.
Quote:
Originally Posted by Dark_Helmet
EDIT2:
After reading the bash man page, I may try to change the aliases into functions and export them with "export -f". That'll have to wait until later though.
If functions work for you, then I'd strongly recommend them over using aliases. Aliases just perform very simple substitutions and are rarely the best choice for scripting.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.