I have a bash script named test.sh with:
#!/bin/bash
var1=hello
sh test2.sh $var1="/var/log"
My test2.sh looks like this:
#!/bin/bash
function jumpto
{
label=$1
cmd=$(sed -n "/$label:/{:a;n;p;ba};" $0 | grep -v ':$')
eval "$cmd"
exit
}
start=${1:-"start"}
jumpto $start
start:
echo "variable -- " $var1
This does not work due to I used jumpto function. When execution, always $var1 assigned to the $1 variable in jumpto function.
Is there a different way to do this.?
We suggest to learn about environment variable and export command and their scope.
Try modify your test.sh
#!/bin/bash
export var1=hello
sh test2.sh $var1="/var/log"
Related
Objective is to create a script that give multiple choice to pick while executing
parameter1=$1
option1="ls -l"
option2="ls -R"
Execution command: sh script.sh option1 $1 or sh script.sh option2 $1
I tried with sh script.sh $option1 $1 but no luck
Don't use variables; use functions:
f=$1
# Ensure that f's value is only one of the predefined
# function names.
case $f in
option1|option2) : ;;
*) printf 'Invalid command\n' >&2; exit 1 ;;
esac
arg=$2
option1 () {
ls -l "$1"
}
option2 () {
ls -R "$1"
}
"$f" "$arg"
Then sh script.sh option1 foo will execute option1 foo, which will execute ls -l foo.
If I understand you correctly, you need to call the script script.sh with the optionX as an indirect references. For example sh script.sh option1 $1 would do ls -l $1. Is that really what you want ??
Here is an example
parameter1=$1
parameter2=$2
option1="ls -l"
option2="ls -R"
eval parameter1=\$$parameter1
$parameter1 $parameter2
Then simply just run sh script.sh option1 <something>
Say I have a bash script and I want some variables to appear when sourced and others to only be accessible from within the script (both functions and variables). What's the convention to achieve this?
Let's say test.sh is your bash script.
What you can do is extract all the common items and put them in common.sh which can be sourced by other scripts.
The BASH_SOURCE array helps you here:
Consider this script, source.sh
#!/bin/bash
if [[ ${BASH_SOURCE[0]} == "$0" ]]; then
# this code is run when the script is _executed_
foo=bar
privFunc() { echo "running as a script"; }
main() {
privFunc
publicFunc
}
fi
# this code is run when script is executed or sourced
answer=42
publicFunc() { echo "Hello, world!"; }
echo "$0 - ${BASH_SOURCE[0]}"
[[ ${BASH_SOURCE[0]} == "$0" ]] && main
Running it:
$ bash source.sh
source.sh - source.sh
running as a script
Hello, world!
Sourcing it:
$ source source.sh
bash - source.sh
$ declare -p answer
declare -- answer="42"
$ declare -p foo
bash: declare: foo: not found
$ publicFunc
Hello, world!
$ privFunc
bash: privFunc: command not found
$ main
bash: main: command not found
I have a script that I'd like people to source, but optionally so. So they can run it with or without sourcing it, it's up to them.
e.g. The following should both work:
$ . test.sh
$ test.sh
The problem is, test.sh contains exit statements if correct args aren't passed in. If someone sources the script, then the exit commands exit the terminal!
I've done a bit of research and see from this StackOverflow post that I could detect if it's being sourced, and do something different, but what would that something different be?
The normal way to exit from a sourced script is simply to return (optionally adding the desired exit code) outside of any function. Assuming that when run as a command we have the -e flag set, this will also exit from a shell program:
#!/bin/sh -eu
if [ $# = 0 ]
then
echo "Usage $0 <argument>" >&2
return 1
fi
If we're running without -e, we might be able to return || exit instead.
There may be better ways to do this, but here's a sample script showing how I got this to work:
bparks#home
$ set | grep TESTVAR
bparks#home
$ ./test.sh
Outputs some useful information to the console. Please pass one arg.
bparks#home
$ set | grep TESTVAR
bparks#home
$ . ./test.sh
Outputs some useful information to the console. Please pass one arg.
bparks#home
$ set | grep TESTVAR
bparks#home
$ ./test.sh asdf
export TESTVAR=me
bparks#home
$ set | grep TESTVAR
bparks#home
$ . ./test.sh asdf
bparks#home
$ set | grep TESTVAR
TESTVAR=me
bparks#home
$
test.sh
#!/usr/bin/env bash
# store if we're sourced or not in a variable
(return 0 2>/dev/null) && SOURCED=1 || SOURCED=0
exitIfNotSourced(){
[[ "$SOURCED" != "0" ]] || exit;
}
showHelp(){
IT=$(cat <<EOF
Outputs some useful information to the console. Please pass one arg.
EOF
)
echo "$IT"
}
# Show help if no args supplied - works if sourced or not sourced
if [ -z "$1" ]
then
showHelp
exitIfNotSourced;
return;
fi
# your main script follows
# this sample shows exporting a variable if sourced,
# and outputting this to stdout if not sourced
if [ "$SOURCED" == "1" ]
then
export TESTVAR=me
else
echo "export TESTVAR=me"
fi
Checkout this answer for better description and porper solution.
And here is how it is used in docker-entrypoint.sh in official Mysql image:
# check to see if this file is being run or sourced from another script
_is_sourced() {
# https://unix.stackexchange.com/a/215279
[ "${#FUNCNAME[#]}" -ge 2 ] \
&& [ "${FUNCNAME[0]}" = '_is_sourced' ] \
&& [ "${FUNCNAME[1]}" = 'source' ]
}
I have a tcl file with some variables set. I want to source this tcl file into my shell script to use them there.
When I do source <filename>.tcl, and echo the variable, it complains saying variable not found.
Any help would be appreciated.
It's ... convoluted
Here's Tcl script that sets a variable:
$ cat > vars.tcl
set var "this is a Tcl value"
Let's see if we can get Tcl to output that in shell syntax:
$ echo 'source vars.tcl; foreach _v {var} {puts "$_v=\"[set $_v]\""}' | tclsh
var="this is a Tcl value"
So far so good. Now, with bash:
$ echo "${var:-var is unset}"
var is unset
$ . <(echo 'source vars.tcl; foreach _v {var} {puts "$_v=\"[set $_v]\""}' | tclsh)
$ echo "${var:-var is unset}"
this is a Tcl value
with if you're using plain /bin/sh
$ echo "${var:-var is unset}"
var is unset
$ . <(echo 'source vars.tcl; foreach _v {var} {puts "$_v=\"[set $_v]\""}' | tclsh)
sh: 1: Syntax error: "(" unexpected
$ eval "$(echo 'source vars.tcl; foreach _v {var} {puts "$_v=\"[set $_v]\""}' | tclsh)"
$ echo "${var:-var is unset}"
this is a Tcl value
This assumes that your Tcl script does nothing beyond setting variables, or that you're OK with sourcing it to get the variables set; and the variable values do not contain double quotes.
You cannot use tcl variables in a shell script. Even though source seems to work, it is not going to do what you think it does. When you use the source command from a shell script, it will attempt to interpret the contents of the file as a shell script.
I have a bash function i would like to bsub. It is recursively called when i try to source the script, but if i don't source the script it doesn't seem to recognize my function. How do I correctly call besub on a function within the same script file?
my_script(should print "12345"):
#! /bin/sh
function myFunct {
echo $1
}
bsub -q myQueue "source ./my_script; myFunct 12345"
a.bash may look like this
#! /bin/bash
export input=$1
function myFunct {
echo "$input"
}
# This is if you want to call bsub outside the bash
# Use bsub -q Queue `./a.bash 12345`
myFunct "$input"
# Put bsub inside and call the script
# ./a.bash 12345
bsub -q myQueue `myFunct "$input"`
I've gotten it to work with
bsub [...] bash -rcfile my_script.sh -i -c "myFunct 12345"