/etc/profile.d scripts

Cameron Simpson cs at zip.com.au
Fri Apr 24 21:01:25 UTC 2009


On 24Apr2009 14:25, m.roth2006 at rcn.com <m.roth2006 at rcn.com> wrote:
| >> I have a script in /etc/profile.d that is a Bash shell script with a .sh 
| >> extension.

Really it should have a matching partner ending .csh. In csh syntax:-(

I will describe a workaround at the end of this message.

| >> Is there a way to have the users shell switched to bash shell when they log 
| <snip>
| >Specify the shell to be used in the script. Make the first line of 
| >your script:
| >
| >#!/bin/bash

No. These scripts are being _sourced_ by the login shell. The #! line is
_not_ used; it is driven entirely by the script extension (.sh vs .csh);
the Bourne shell login process sources /etc/profile.d/*.sh and the csh
sourced the *.sh ones likewise. They are not "exec"ed.

 There's a loop like this one in /etc/profile (sourced by all login
 Bourne shells):

  for sh in /etc/profile.d/*.sh ; do
    if [ -r "$sh" ] ; then
      . "$sh"
    fi
  done
  unset sh

| The shell should ALWAYS be the first line. I, personally, would not
| accept one that didn't have that. Of course, I can't think of one I've
| seen that didn't.

For normal scripts this is true, and even for these I would be inclined
to put the #! in just for documentation. But it has no effect on the
login process because they're sourced and chosen by filename, not
execed.

| >There may already be a line specifying another shell. If so, delete 
| >it. Make sure to substitute the proper path if bash is not in /bin.

This will have no effect.

| >Also note that the .sh extension is not really needed.

Actually, here it is vital.

| That first is not a good idea. What works in one may not work in
| another. For example, if there's an old shell script in Bourne, that
| will gag on
| export HOTSHOT=/home/myself
| or 
| alias h=history

Which is why login scripts like these should always be written in lowest
common denominator Bourne shell, so all the Bourne shells will like
them. So:

  A=1
  B=2
  export A B

and never:

  export A=1
  export B=2

And no aliases. (Which anyway belong in the bashrc and friends, since
they're useful only for interactive shells.)

| And the extension certainly isn't necessary; however, I normally do it
| as good practice, so that you know what it is without doing a file on it.

For the login scripts in /etc/profile.d the extension is necessary,
otherwise the loop cited earlier will simply ignore them.

Returning to the original problem, one approach that can be of use is to
write a small Bourne shell program to:
  source a Bourne shell script such as they one you've having trouble
  with
  recite the changed environment as csh-syntax setenv statements
  source its output ifrom csh

Example (untested and unrobust, too):

  #!/bin/sh
  exec 9>&1 1>&2        # avoid plugs in output
  for src
  do
    . "$src"
  done
  exec 1>&9 9>&-        # restore output stream
  set | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=\(.*\)/setenv \1 '\2'/p

You can then add a .csh startup script like this:

  eval `/path/to/sh-to-csh /etc/profile.d/foo.sh /etc/profile.d/bah.sh ...`

And it should run the named Bourne shell startup files and run the
resulting setenv commands as desired.

I've certainly used this appraoch in the past to support csh users.

Cheers,
-- 
Cameron Simpson <cs at zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

Sorry, baby, I can't take you to the pizza joint tonight, I've got to go
back to the lab and split the atom.     - Ayn Rand, "What is Romanticism?"




More information about the redhat-list mailing list