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

A

Adam Akhtar

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)
 
J

Jesús Gabriel y Galán

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)

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.
 
B

Brian Candler

Adam said:
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.

HTH,

Brian.
 
A

Adam Akhtar

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.
 
A

Ammar Ali

Adam said:
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.


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
 
B

Brian Candler

Adam said:
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.
 
B

Brian Candler

Ammar said:
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
 
P

Phil Romero

[Note: parts of this message were removed to make it a legal post.]

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
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
 
A

Adam Akhtar

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

Seebs

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top