tags:

views:

65

answers:

2

I have a bash-script (let's call it /usr/bin/bosh) using the following she-bang line:

#!/bin/bash --init-file

It defines a couple of functions, and generally puts the interactive shell in an environment where the user can control a bunch of stuff that I want. This works pretty well. Now for the interesting part, I'd like to be able to let users use this in-between-layer for writing new scripts, without explicitly havnig to source this one. Is that at all possible?

I tried writing a script (let's call it /usr/bin/foo) using the she-bang line

#!/usr/bin/bosh

Which I thought, would be rewritten to execute the command

/usr/bin/bosh /usr/bin/foo

which in turn would result in

/bin/bash --init-file /usr/bin/bosh /usr/bin/foo

But it doesn't work, /usr/bin/foo gets executed, but /usr/bin/bosh is not source before that.

How can I make it source the init file even though the script is not interactive? Or would I have to write a wrapper script for that? I thought of having a script like this

#!/bin/bash
. /usr/bin/bosh
. "$1"

But that wouldn't turn into an interactive shell if I don't specify a script to run, which would be kind of a shame.

EDIT
For clarification, what I'm really asking is, how can I make bash source a file (like --init-file) regardless whether it's interactive (before starting the interactive part) or not (before executing the script)? If there's no way, is there any other way to solve my problem perhaps?

A: 

A script is not a runtime environment. That may be your problem. The shebang defnies the runtime environment. ie... /bin/java /bin/python /bin/bash /bin/dash. Your script is not an environment. Your "wrapper example" would be appropriate.

Adam Outler
You don't really know what the shebang does, do you? :)
roe
It's an interperater for execution. basically, instead of /bin/bash "my commmand" you're saying /bin/bosh "my command".Dosn't seem to make much sense that way.
Adam Outler
I don't really see what you're trying to do. Your ". /path/to/file.config" seems like the way to go and that's how I load environmental variables from settings in my scripts.
Adam Outler
Exactly, the command line `myscript` gets rewritten to be `/bin/bosh myscript`, now `/bin/bosh` has got its own shebang line, so the command line gets rewritten again `/bin/bash --init-file /bin/bosh myscript`. This is not my question, this is working fine. See my edit, it's about getting a file sourced before executing a script, not just before executing an interactive shell. Logically speaking `/bin/bosh` is an interpreter, it just happens to execute bash.
roe
A: 

The program specified by the #! cannot be another script I'm afraid at least until linux kernel 2.6.27.9, which allows this feature. If you run strace on foo you'll see that you'd get an ENOEXEC or exec format error, because bosh cannot be executed as a standalone program.

What is happening is that instead of /bin/bosh being executed and handed foo as input, your login shell is simply silently falling back to executing foo itself in a sub-shell, which is why it seems to almost work.

A wrapper or C program that launches bash the way you want are probably your only options. Even with an upgrade to your kernel, it will not quite work the way you want I'm afraid.

Everything you ever wanted to know about #! here: http://www.in-ulm.de/~mascheck/various/shebang/

EDIT: If your kernel really does support chained scripts, then a work-around for /usr/bin/bosh might be something like:

#!/bin/bash
if [ ! $PS1 ]; then
   exec /bin/bash --init-file "$0" -i "$@"
fi
... rest of bosh init file ...

An exec seems to be unavoidable to get this to work the way you want it to.

Steve Baker
This is not true, it's running fine on 2.6.16. The problem is in the --init-file, if you read the man page you'll notice it wont get executed if it's not an interactive shell, so I can only take advantage of what's in that file when it's an interactive shell. I didn't downvote though.
roe
Then you must not be running a vanilla kernel. To whomever down-voted me, the above is the truth as I know it, so don't down-vote me because you live in your special Red-Hat land or whatever.
Steve Baker
Good idea with the exec! Why didn't I think of that.. Thanks! (Although your example doesn't really do what I want, but still, I can check if I don't have a script argument, and execute the interactive shell in that case)
roe