I can define a function like:
myfunction () { ls -R "$1" ; }
And then
myfunction .
just works.
But if I do
echo "myfunction ." | sh
echo "myfunction ." | bash
the messages are:
sh: myfunction: not found
bash: line 1: myfunction: command not found
Why? And how can I call a function that comes from a string if not by piping it to sh or bash?
I know there is this command source
, but I am confused of when I should use source
and when sh
or bash
. Also, I cannot pipe through source
. To add to confusion, there is this command .
that seems to have nothing to do with the "." that means "current directory".
Instead of using
eval
, you canexport
your function so it is inherited by subshells:And then
just works.
echo "myfunction ." | sh
probably won't still, unless your /bin/sh is a symlink to bash.A function definition only has an effect in the current instance of bash. When you write
you run another instance of bash. You would need to define the function in that other instance.
If you have a string that contains a function name and arguments (quoted, if necessary), or more generally any string that contains some shell source code that you want to execute, use the
eval
builtin.If you define functions in your
.bashrc
, they are only available in interactive shells, not in scripts.The
.
command is (almost) equivalent tosource
, and has nothing to do with.
meaning the current directory.bash
andsh
expect their argument to be an executable file, not a string.You can execute the contents of a string with
When you run a program through the shell, it will normally invoke a new instance of
bash
(orsh
,csh
,zsh
, etc. as appropriate), inherit all the original shell's settings, and run itself in the new shell. This allows you to temporarily set variables or change settings without interfering with your environment.source
ing a command will make it run it your current shell, so any changes it makes to the environment will persist when the command exits..
is a synonym forsource
.In most circumstances, a script will specify what shell it is meant to run in (with
#!/bin/bash
in its first line, for example), and it isn't necessary for you to call bash explicitly.