If I run a custom bash function under shell console:
~/w/dotfiles/ruby [g:master-] ΒΆ repository_root
/Users/tian/Documents/workspace/dotfiles
And if I run the custom bash function under IRB:
irb(main):001:0> `repository_root`
(irb):1: command not found: repository_root
=> ""
How could I get the same result in IRB?
# declare
repository_root () {
if git_is_repository ; then
git_show_repository_root
fi
}
Assuming your function is in one of your bash profile files, you want to start up an interactive (-i) login (-l) shell to execute (-c) your function:
output = %x{bash -lic 'repository_root'}
One way to do this is to make a command out of the function.
Here's a short how-to
Create a shell script file that calls the function.
Create a .bin directory in your HOME and add it to $PATH in .bash_rc.
Place the shell script file in .bin.
source .bash_rc to update the $PATH variable you just changed.
Assuming you named the file fnx, just use the back tick operator or exec to run
the command - exec("fnx")
where is repository_root declared?
.bash_profile? .bashrc?
try to source that file before using repository_root
`. /path/to/file/declaring/repository_root; repository_root`
Related
How to set a global environment variable in a bash script?
If I do stuff like
#!/bin/bash
FOO=bar
...or
#!/bin/bash
export FOO=bar
...the vars seem to stay in the local context, whereas I'd like to keep using them after the script has finished executing.
Run your script with .
. myscript.sh
This will run the script in the current shell environment.
export governs which variables will be available to new processes, so if you say
FOO=1
export BAR=2
./runScript.sh
then $BAR will be available in the environment of runScript.sh, but $FOO will not.
When you run a shell script, it's done in a sub-shell so it cannot affect the parent shell's environment. You want to source the script by doing:
. ./setfoo.sh
This executes it in the context of the current shell, not as a sub shell.
From the bash man page:
. filename [arguments]
source filename [arguments]
Read and execute commands from filename in the current shell
environment and return the exit status of the last command executed
from filename.
If filename does not contain a slash, file names in PATH are used to
find the directory containing filename.
The file searched for in PATH need not be executable. When bash is not
in POSIX mode, the current directory is searched if no file is found
in PATH.
If the sourcepath option to the shopt builtin command is turned off,
the PATH is not searched.
If any arguments are supplied, they become the positional parameters
when filename is executed.
Otherwise the positional parameters are unchanged. The return status
is the status of the last command exited within the script (0 if no
commands are executed), and false if filename is not found or cannot
be read.
source myscript.sh is also feasible.
Description for linux command source:
source is a Unix command that evaluates the file following the command,
as a list of commands, executed in the current context
#!/bin/bash
export FOO=bar
or
#!/bin/bash
FOO=bar
export FOO
man export:
The shell shall give the export attribute to the variables corresponding to the specified names, which shall cause them to be in the environment of subsequently executed commands. If the name of a variable is followed by = word, then the value of that variable shall be set to word.
A common design is to have your script output a result, and require the cooperation of the caller. Then you can say, for example,
eval "$(yourscript)"
or perhaps less dangerously
cd "$(yourscript)"
This extends to tools in other languages besides shell script.
In your shell script, write the variables to another file like below and source these files in your ~/.bashrc or ~/.zshrc
echo "export FOO=bar" >> environment.sh
In your ~/.bashrc or ~/.zshrc, source it like below:
source Path-to-file/environment.sh
You can then access it globally.
FOO=bar
export FOO
I have a bash script like this with a function
_launch()
{
${1}
}
testx()
{
_launch "TESTX=1 ls -la"
}
testx
I get error "TESTX=1 command not found" in _launch function. Why?
When I run TESTX=1 ls -la directly on shell it works fine.
It's not a good idea to use variables to hold commands. See BashFAQ/050
As long as you are dealing with executables and not shell built-ins, you could do this:
_launch() {
env $1
}
This won't play well in case you have literal spaces in values used in var=value pairs or arguments to the command being launched.
You can overcome this problem by just passing the command to the launch function and setting your variables in function invocation itself, like this:
_launch() {
# your launch prep steps here...
"$#" # run the command
# post launch code here
}
TESTX=1 TESTY=2 TESTZ=3 _launch ls -la
The variables would be passed down to the launched command as environment variables.
You get the error because first looks at the statement to see whether we have a variable assignment, and then does parameter expansion. In your case, bash doesn't recognize that you want to extend the environment for your ls command, and treats TESTX=1 as command to be executed.
For the same reason, the following does not set the bash variable ABC:
x='ABC=55'
$x
This would print ABC=55: command not found.
I need to source a few environment variables in another file. If I use the source command with system() function, it's complaining about "No such file or directory". Am I missing something?
My code looks like below. In my code, I have only the system() function running the source command. The source file has just only one command: pwd (Present working directory).
perl_system.pl
#!/usr/bin/perl
system "source env.mk"
env.mk (contents of env.mk which I want to source has just pwd for now"
pwd
When I run this command, I see the below error
$ perl -w perl_system.pl
Can't exec "source": No such file or directory at perl_system.pl line 2.
source is a shell built-in that executes a shell script using the current shell interpreter. So it doesn't work as an external command and won't change the environment of your perl process even if you change your system call to invoke a shell instead of it trying to run an external program directly.
You could run your env.mk and then output the resulting environment and update perl's environment accordingly, though:
for my $env (`bash -c 'source env.mk;env'`) {
chomp $env;
my ($var,$val) = split /=/, $env, 2;
$ENV{$var} = $val;
}
(with obvious problems if environment variables contain newlines).
Update: just read all of your question, not just the beginning. If all you want to do is execute a shell script, just do:
system "sh env.mk";
source is completely unnecessary for this.
I tried 3 internet examples to write a bashe shell function and call it via my xterm terminal with no success.
1-my functions are saved in a file "example" and this file is inexecutable mode.
2-inside this example file i wrote:
#!/bin/bash
function quit {
exit
}
function hello {
echo Hello!
}
3- in xterm terminal, in the folder that this file is located i called these two functions in these ways:
$./quit $./hello
and in this way:
$quit $hello
none of them work.but if i change the following function to a script (without function word) and call the FILE, it works.
Any idea, what is going on?
Thanks
You need to source your script to load function definitions to current shell environment:
# source script
. example
# call function
hello
# call function
quit
You need to make the function definitions available to the outside shell. For this, you need to source the example file:
. example
quit
hello
You can also do source example.
Once you've written the functions, they only visible inside the script file itself. For them to be visible outside it, you need to tell the script to export the functions to the environment.
Try adding export -f quit and export -f hello after your function definitions.
Let's clear up confusion with the ./ and $ operators.
The first operator ./ is used when you want to call a script in the current directory. For example, if you've defined your script in some file script.sh, then you could call it with ./script.sh (make sure you have execute permissions - you can add them with chmod +x script.sh).
The second operator $ is used to look at environment variables. These are variables which are defined by default in the bash shell, or variables which you have defined and exported to the shell. Try entering the following into your shell.
pi=3.14
echo $pi
3.14
Here, the $ prefix allows you to access the variable you created.
./quit Or ./hello means that you have files named quit and hello and you want to execute them.
and $quit and $hello means that quit and hello are predefined commands (executable files in $PATH folders e.g /usr/bin)
when you define a function in shell file, you should use it in that file too!
How to set a global environment variable in a bash script?
If I do stuff like
#!/bin/bash
FOO=bar
...or
#!/bin/bash
export FOO=bar
...the vars seem to stay in the local context, whereas I'd like to keep using them after the script has finished executing.
Run your script with .
. myscript.sh
This will run the script in the current shell environment.
export governs which variables will be available to new processes, so if you say
FOO=1
export BAR=2
./runScript.sh
then $BAR will be available in the environment of runScript.sh, but $FOO will not.
When you run a shell script, it's done in a sub-shell so it cannot affect the parent shell's environment. You want to source the script by doing:
. ./setfoo.sh
This executes it in the context of the current shell, not as a sub shell.
From the bash man page:
. filename [arguments]
source filename [arguments]
Read and execute commands from filename in the current shell
environment and return the exit status of the last command executed
from filename.
If filename does not contain a slash, file names in PATH are used to
find the directory containing filename.
The file searched for in PATH need not be executable. When bash is not
in POSIX mode, the current directory is searched if no file is found
in PATH.
If the sourcepath option to the shopt builtin command is turned off,
the PATH is not searched.
If any arguments are supplied, they become the positional parameters
when filename is executed.
Otherwise the positional parameters are unchanged. The return status
is the status of the last command exited within the script (0 if no
commands are executed), and false if filename is not found or cannot
be read.
source myscript.sh is also feasible.
Description for linux command source:
source is a Unix command that evaluates the file following the command,
as a list of commands, executed in the current context
#!/bin/bash
export FOO=bar
or
#!/bin/bash
FOO=bar
export FOO
man export:
The shell shall give the export attribute to the variables corresponding to the specified names, which shall cause them to be in the environment of subsequently executed commands. If the name of a variable is followed by = word, then the value of that variable shall be set to word.
A common design is to have your script output a result, and require the cooperation of the caller. Then you can say, for example,
eval "$(yourscript)"
or perhaps less dangerously
cd "$(yourscript)"
This extends to tools in other languages besides shell script.
In your shell script, write the variables to another file like below and source these files in your ~/.bashrc or ~/.zshrc
echo "export FOO=bar" >> environment.sh
In your ~/.bashrc or ~/.zshrc, source it like below:
source Path-to-file/environment.sh
You can then access it globally.
FOO=bar
export FOO