Why does `source .bashrc` complain "command not found"?

Is it just me or is this something that just cant be done?

Ive found out that whenever system calls are made they open a child
shell process. And as soon as that call is finished the child shell is
closed and any changes that were made to the environment are lost with
it.

But i should still be able to execute source .bashrc (even though the
changes will be lost as soon as that call finishes). Instead I get
command not found. How come?

(Ubuntu 9.04 and Ruby 1.8x)

On Wed, Jan 27, 2010 at 10:11 AM, Adam A. [email protected]
wrote:

(Ubuntu 9.04 and Ruby 1.8x)

irb(main):004:0> echo $0
=> “sh\n”

and sh doesn’t have a source command. I remember there was a question
recently about changing the shell the backticks use, but I can’t
remember the answers, maybe you can search for it in the archives?

Jesus.

Adam A. wrote:

Is it just me or is this something that just cant be done?

(Ubuntu 9.04 and Ruby 1.8x)

In recent Ubuntu versions, the default shell is dash (/bin/sh is a link
to /bin/dash), and ‘source’ is not a known keyword in that shell. To
demonstrate:

$ /bin/sh
$ source /dev/null
/bin/sh: source: not found
$ exit

The solution: use ‘.’ instead of ‘source’.

dash is a POSIX-compatible shell without lots of non-standard bash
extensions. If you really need to use bash-isms, then you should invoke
bash explicitly.

/bin/bash -c 'source /dev/null'
=> “”

HTH,

Brian.

Adam A. wrote:

script or in irb.

source is a built-in shell command, not an executable. It is only
available from within the shell. When you go to your command line,
you’re in the shell. In a ruby script, or irb, the above works because
it runs the bash shell and hands it the commands to run as a string (the
-c option).

Try running these:

$ which bash

/bin/bash

$ which source

returns nothing

HTH,
ammar

Adam A. wrote:

Thank you very much for both of your replies. I just tried

/bin/bash -c 'source whatever'

and it worked! Fantastic.

But i don’t understand if source isnt a known command then how come when
i go to my command line and type source it works fine?

because your login shell is /bin/bash not /bin/sh (grep for your
username in /etc/passwd)

The correct solution is not to use bash-specific functionality:

. whatever

should work just fine. By doing this you’ll help your script to be
portable to other operating systems, like *BSD which tend not to install
bash by default because of its restrictive GPL licence.

Ammar A. wrote:

source is a built-in shell command, not an executable. It is only
available from within the shell.

You are correct, but you’ve missed the point. As the OP already
observed, ruby does invoke a shell when you pass it a string in
backticks.

The point is that his default shell doesn’t have a ‘source’ builtin.

source /dev/null # fails (not a POSIX shell feature)
. /dev/null # works

Thank you very much for both of your replies. I just tried

/bin/bash -c 'source whatever'

and it worked! Fantastic.

But i don’t understand if source isnt a known command then how come when
i go to my command line and type source it works fine?

Thats why i was initially confused. It worked manually but not inside a
script or in irb.

Many thanks for your replies again - most helpful and greatly
appreciated. Saved a few hours of my hitting my head against a brick
wall.

On Wed, Jan 27, 2010 at 2:04 AM, Ammar A. [email protected]
wrote:

shell and hands it the commands to run as a string (the -c option).
ammar

Another good tool to use is ‘type’ when trying to puzzle this stuff out:

[pdr@grace]$ type source
source is a shell builtin
[pdr@grace]$ type .
. is a shell builtin

On 2010-01-27, Adam A. [email protected] wrote:

Is it just me or is this something that just cant be done?

Ive found out that whenever system calls are made they open a child
shell process. And as soon as that call is finished the child shell is
closed and any changes that were made to the environment are lost with
it.

But i should still be able to execute source .bashrc (even though the
changes will be lost as soon as that call finishes). Instead I get
command not found. How come?

External shell almost always uses /bin/sh, which is usually more POSIXY,
and “source” is a bash-only feature. Try “. $HOME/.bashrc” or something
close to that – the “.” command often requires a path to reach things
in the current directory, to avoid certain obvious failure modes.

-s