I am calling a script2.sh from script1.sh without passing parameter. But I am passing parameter to script1.sh. I am trying to print first parameter of script2.sh.
script1.sh
#! /bin/bash
PRM1=$1
source script2.sh
script2.sh
#! /bin/bash
PRM1=$1
echo "$PRM1"
output is
# source script1.sh hello
#hello
#
But Ideally
# source script1.sh hello
#
Can any one tell me why script2.sh is taking script1.sh parameter as it's parameter?
From the bash(1) man page:
SHELL BUILTIN COMMANDS
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.
pass junk as parameter. so that the positional parameter will replace with it.
You are not giving your script1.sh any argument as it is expecting one. (A small note, I always close the white space in this line: #!/bin/bash - not #! /bin/bash). In your script1.sh, try this:
#!/bin/bash
PRM1=$1
./script2.sh $PRM1
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've encountered the following command:
source foo -c configs/foo.config
What is -c flag is actually may do here? foo is bash script, foo.config also looks like one.
The source command is a bash-specific alias for the POSIX-standardized command .. The specific usage you're asking about is mentioned by POSIX as an allowable extension:
The KornShell version of dot takes optional arguments that are set to the positional parameters. This is a valid extension that allows a dot script to behave identically to a function.
Thus, when code read from foo is invoked, its $1 will be -c and its $2 will be configs/foo.config.
This is also explicitly documented if you run help source in bash:
source: source filename [arguments]
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.
Exit Status:
Returns the status of the last command executed in FILENAME; fails if
FILENAME cannot be read.
Note the text above: If any ARGUMENTS are supplied, they become the positional parameters when FILENAME is executed.
I would like to know what does the command source do. I have tried:
whatis
$ whatis source
source: nothing appropriate.
man
$ man source
No manual entry for source
source (-h, --help, etc...)
$ source
source: not enough arguments
But it seems no documentation about it.
I commonly use it to save any changed on my dotfiles, but what does it exactly do? Why there is not documentation about it?
source is a bash shell built-in command that executes the content of the file passed as an argument, in the current shell. It has a synonym in . (period).
Syntax
. filename [arguments]
source filename [arguments]
From the source manual
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 short
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.
Be careful! ./ and source are not quite the same.
./script runs the script as an executable file, launching a new shell to run it
source script reads and executes commands from filename in the current shell environment
Note: ./script is not . script, but . script == source script
Is there any difference between source in bash after all?
I'm looking for a way to access the full command from shell script, e.g.
Assume I have a script called test.sh. When I run it, the command line is passed to ruby as is (except the script itself is removed).
$ test.sh print ENV['HOME']
Is equivalent to
$ ruby -e "print ENV['HOME']"
When you run:
test.sh print ENV['HOME']
...then, before test.sh is started, the shell runs string-splitting, expansion, and similar processes. Thus, what's eventually run is (assuming no glob expansion):
execvp("test.sh", {"test.sh", "print", "ENV[HOME]"});
If you have a file named ENVH in the current directory, the shell may treat ENV['HOME'] as a glob, expanding it by replacing the glob expression with the filename, and thus running:
execvp("test.sh", {"test.sh", "print", "ENVH"});
...in any event, what exists on the other side of the execv*-series call done to run the new program has no information which was local to the original shell -- and thus no way of knowing what the original command was before parsing and expansion. Thus, it is impossible to retrieve the original string unless the outer shell is modified to expose it out-of-band (as via an environment variable).
This is why your calling convention should instead require:
test.sh "print ENV['HOME']"
or, allowing even more freedom from shell quoting/escaping syntax, passing program text via stdin, as with:
test.sh <<'EOF'
print ENV['HOME']
EOF
Now, if you want to modify your shell to do that, I'd suggest a function that exposes BASH_COMMAND. For instance:
shopt -s extdebug
expose_command() {
export SHELL_COMMAND="$BASH_COMMAND"
return 0
}
trap expose_command DEBUG
...then, inside test.sh, you can refer to SHELL_COMMAND. Again, however: This will only work if the calling shell had that trap configured, as within a user's ~/.bashrc; you can't simply put the above content in a script and expect it to work, because it's only the interactive shell -- the script's parent process -- that has access to this information and is thus able to expose it.
This question already has answers here:
Global environment variables in a shell script
(7 answers)
Closed 5 years ago.
I am trying to export a variables through myDeploy.sh but the export is not getting set. When i am echoing it is not echoing. However, when i set the variable explicitly on command it sets properly and echoes too.Below is the snippet of my code.
myDeploy.sh
#!/bin/bash
# export the build root
export BUILD_ROOT=/tibco/data/GRISSOM2
export CUSTOM1=/tibco/data/GRISSOM2/DEPLOYMENT_ARTIFACTS/common/MDR_ITEM_E1/rulebase
export CLEANUP=$BUILD_ROOT/DEPLOYMENT_ARTIFACTS/common
cd $BUILD_ROOT/DEPLOYMENT_ARTIFACTS/common
When I echoes echo $BUILD_ROOT it is not echoing the path for me. But when I do it explicitly on command prompt like
[root#krog3-rhel5-64 GRISSOM2]# export BUILD_ROOT=/tibco/data/GRISSOM2
It sets properly and echoes too. What am I missing?
Running your script like
. ./script
or
source script
would execute your script in the current shell context (without creating a subshell) and the environment variables set within the script would be available in your current shell.
From the manual:
. filename [arguments]
Read and execute commands from the filename argument in the current
shell context. If filename does not contain a slash, the PATH variable
is used to find filename. When Bash is not in POSIX mode, the current
directory is searched if filename is not found in $PATH. 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 exit status of the last command
executed, or zero if no commands are executed. If filename is not
found, or cannot be read, the return status is non-zero. This builtin
is equivalent to source.