I've got a function that I want to reference and use across different scripts. Is there any way to do this? I don't want to be re-writing the same function for different scripts. Thanks.
Sure - in your script, where you want to use the function, you can write a command like
source function.sh
which is equivalent to including the contents of function.sh in the file at the point where the command is run. Note that function.sh needs to be in one of the directories in $PATH; if it's not, you need to specify an absolute path.
Yes, you can localize all your functions in a common file (or files). This is exactly what I do with all my utility functions. I have a single utility.shinc in my home directory that's used by all my programs with:
. $HOME/utility.shinc
which executes the script in the context of the current shell. This is important - if you simply run the include script, it will run in a subshell and any changes will not propagate to the current shell.
You can do the same thing for groups of scripts. If it's part of a "product", I'd tend to put all the scripts, and any included scripts, in a single shell directory to ensure everything is localized.
Yes..you can!
Add source function_name in your script.
I prefer to create variable eg.VAR=$(funtion_name),if you add the source function_name after #!/bin/bash then your script first execute imported function task and then your current script task so its better to create variable and used anywhere in script.
thank you..Hope its work for you:)
Related
I want to add some helper commands to my shell. There are several commands I want to add, and they need to share some information between them. However, since I want a different state for each shell, I can't use files to store the shared information, but have to use environment variables.
This opens up the problem of setting environment variables: to change a variable in my shell and not only in a subprocess, I either need to put my commands in scripts and always source the scripts, or define them as functions and source the file via .bashrc.
I have also defined some auxiliary functions that are used by several of my commands, which I would prefer NOT to have in the scope of my main shell process.
I'm somewhat inexperienced with bash, so my question is:
What is the cleanest way to implement this? Should I put my commands into scripts or into functions? Can I prevent my auxiliary functions from being sourced into the main shell? Is there an easier way to manipulate environment variables?
you can store put your environment variables inside shell file (myEnv.sh). then you can use
source myEnv.sh
to load your env variables according to your need.
you can also use inject this into your main shell scripts
I would recommend you to have .profile files instead of .sh files.
case1.profile , case2.profile and source them whenever needed.
use any one of below method to source the files.
source ~/.case1.profile
or
. ~/.case1.profile
I would like to write a script that has several commands of the kind
> export PATH=$PREFIX/bin
Where
> $PREFIX = /home/usr
or something else. Instead of typing it into the the Shell (/bin/bash) I would run the script to execute the commands.
Tried it with sh and then with a .py script having the line,
> commands.getstatusoutput('export PATH=$PREFIX/bin')
but these result into the error "bad variable name".
Would be thankful for some ideas!
If you need to adjust PATH (or any other environment variable) via a script after your .profile and equivalents have been run, you need to 'dot' or 'source' the file containing the script:
. file_setting_path
source file_setting_path
The . notation applies to all Bourne shell derivatives, and is standardized by POSIX. The source notation is used in C shell and has infected Bash completely unnecessarily.
Note that the file (file_setting_path) can be specified as a pathname, or if it lives in a directory listed on $PATH, it will be found. It only needs to be readable; it does not have to be executable.
The way the dot command works is that it reads the named file as part of the current shell environment, rather than executing it in a sub-shell like a normal script would be executed. Normally, the sub-shell sets its environment happily, but that doesn't affect the calling script.
The bad variable name is probably just a complaint that $PREFIX is undefined.
Usually a setting of PATH would look something like
export PATH=$PATH:/new/path/to/programs
so that you retain the old PATH but add something onto the end.
You are best off putting such things in your .bashrc so that they get run every time you log in.
I have a shell script on a mac (OSX 10.9) named msii810161816_TMP_CMD with the following content.
matlab
When I execute it, I get
./msii810161816_TMP_CMD: line 1: matlab: command not found
However, when I type matlab into the shell directly it starts as normal. How can it be that the same command works inside the shell but not inside a shell script? I copy-pasted the command directly from the script into the shell and it worked ...
PS: When I replace the content of the script with
echo matlab
I get the desired result, so I can definitely execute the shell script (I use ./msii810161816_TMP_CMD)
Thanks guys!
By default, aliases are not expanded in non-interactive shells, which is what shell scripts are. Aliases are intended to be used by a person at the keyboard as a typing aid.
If your goal is to not have to type the full path to matlab, instead of creating an alias you should modify your $PATH. Add /Applications/MATLAB_R2014a.app/bin to your $PATH environment variable and then both you and your shell scripts will be able to simply say
matlab
This is because, as commenters have stated, the PATH variable inside of the shell executing the script does not include the directory containing the matlab executable.
When a command name is used, like "matlab", your shell looks at every directory in the PATH in order, searching for one containing an executable file with the name "matlab".
Without going into too much detail, the PATH is determined by the shell being invoked.
When you execute bash, it combines a global setting for basic directories that must be in the PATH with any settings in your ~/.bashrc which alter the PATH.
Most likely, you are not running your script in a shell where the PATH includes matlab's directory.
To verify this, you can take the following steps:
Run which matlab. This will show you the path to the matlab executable.
Run echo "$PATH". This will show you your current PATH settings. Note that the directory from which matlab is included in the colon-separated list.
Add a line to the beginning of your script that does echo "$PATH". Note that the directory from which matlab is not included.
To resolve this, ensure that your script is executed in a shell that has the needed directory in the PATH.
You can do this a few ways, but the two most highly recommended ones would be
Add a shebang line to the start of your script. Assuming that you want to run it with bash, do #!/bin/bash or whatever the path to your bash interpreter is.
The shebang line is not actually fully standardized by POSIX, so BSD-derived systems like OSX will happily handle multiple arguments to the shebanged executable, while Linux systems pass at most one argument.
In spite of this, the shebang is an easy and simple way to document what should be used to execute the script, so it's a good solution.
Explicitly invoke your script with a shell as its interpreter, as in bash myscript.sh or tcsh myscript.sh or even sh myscript.sh
This is not incompatible with using a shebang line, and using both is a common practice.
I believe that the default shell on OSX is always bash, so you should start by trying with that.
If these instructions don't help, then you'll have to dig deeper to find out why or how the PATH is being altered between the calling context and the script's internal context.
Ultimately, this is almost certainly the source of your issue.
Let's say a script is called with /bin/sh. Is it possible to source another script from that script and to have it be interpreted with #!/bin/bash?
It would appear that the #!/bin/bash doesn't do anything...
And by source, at this point I am meaning the functionality of manipulating the parent environment.
No. The whole point of sourcing a script is that the script is interpreted by the shell doing the sourcing. If, as is often the case, /bin/sh is bash, then you will get the desired behavior. Otherwise, you are out of luck.
Try the source command, or dot operator. You might also try the env command. Note, make sure you export if you're using source (or dot).
I am new at bash and trying to solve some issues for a code I'm trying to make.
I am at the terminal under my user name and connect to bash
USER$
USER$ bash
bash$
now in the bash I am saving some variables f.e:
i=2
k=2
let p=$k*$i
now I want to use those variables outside the bash function
bash$exit
USER$
but now the variables are not there
I try using export, but it did not really work, could use ur help, tnx
Not possible. You cannot set environment variables in a parent process like this.
Unlike a DOS batch file, a Unix shell script cannot directly affect the environment of its calling shell.
You could consider using the . (dot) or source command to read and execute the script in the context of the calling shell. This means that changes made in the script do affect the environment (in general; you can still run into issues with sub-shells).
The other alternative is to have the script that sets the variables write the values in name=value format into a file which the calling script then reads (with . or source again).
The conventional solution is to add the settings to your .profile or . bashrc -- which you should use depends on your specific needs and your local Bash configuration; my first recommendation would be .profile, but then you have to avoid any bashisms because this file is shared with sh (so, no let, for example).
For more specific needs, put the commands in a file, and source it when you need it. You might also want to create a simple script to update the file with your current values.
# source this file to update $HOME/stuff
cat<<HERE>$HOME/stuff
i='$i'
k='$k'
p='$p'
export i k p
HERE
The syntax here is quite simple, but assumes you don't have values which can contain single quotes or otherwise free-form content. How to safely store arbitrary values which you don't have complete control over is a much more complex discussion; I am providing a simple solution for the basic use case where you merely need to save a few simple scalar values, like numbers.
To keep your variables when you connect to a remote system, look at the documentation for the tool you are using to connect. For example, ssh has configuration options for importing environment variables from the local system when starting a remote session.