We have a shell script in the following location.
/opt/shellscript/test1.sh
Content of test1.sh file.
USERVALUES = P1321,testusername#example.com
USERVALUES1 ="$USERVALUES"
echo "Value of USERVALUES1 is $USERVALUES1"
We need to execute another script
/opt/shellscript/test2.sh
Content of the test2.sh file.
chmod +x /opt/shellscript/test1.sh
sh /opt/shellscript/test1.sh
echo "Value of USERVALUES1 from script test1.sh is $USERVALUES1"
We need to get the output as below.
Value of USERVALUES1 from script test1.sh is P1321,testusername#example.com
Could someone help on the same, how we can achieve this use case.
Edit test1.sh (remove spaces)
USERVALUES=P1321,testusername#example.com
USERVALUES1=$USERVALUES
echo "Value of USERVALUES1 is $USERVALUES1"
To fetch vars in test2.sh form test1.sh you need to:
source test1.sh
cat test2.sh
chmod +x /opt/shellscript/test1.sh
# source /opt/shellscript/test1.sh
. /opt/shellscript/test1.sh
sh /opt/shellscript/test1.sh
echo "Value of USERVALUES1 from script test1.sh is $USERVALUES1"
You can not access internal data of another process. The other process has to expose the data. Typically by writing the data to a file descriptor: standard output, a pipe or a temporary file.
Related
I have a doubt about running multiple scripts from a third one:
first.sh
#!/bin/bash
echo "script 1"
#... and also download a csv file from gdrive
second.sh
#!/bin/bash
echo "script 2"
third.awk
#!/usr/bin/awk -f
BEGIN {
print "script3"
}
I would like a 4th script that run them in order, I've tried the following but only runs the first script.
#!/bin/bash
array=( first.sh second.sh )
for i in "${array[#]}"
do
chmod +x $i
echo $i
. $i
done
But only runs the first script and nothing else.
Thank you very much for the support!
Santiago
You can't source an awk script into a shell script. Run the script instead of sourcing it.
. (aka source) executes commands from the file in the current shell, it disregards the shebang line.
What you need instead is ./, i.e. path to the script, unless . is part of your $PATH (which is usually not recommended ).
#!/bin/bash
array=( first.sh second.sh )
for i in "${array[#]}"
do
chmod +x "$i"
echo "$i"
./"$i" # <---
done
Why is the second script not running? I guess the first script contains an exit, which when sourced exits the shell, i.e. it doesn't continue running the outer wrapper.
In reference to https://stackoverflow.com/a/11886837/1996022 (also shamelessly stole the title) where the question is how to capture the script's output I would like to know how I can additionally capture the scripts input. Mainly so scripts that also have user input produce complete logs.
I tried things like
exec 3< <(tee -ia foo.log <&3)
exec <&3 <(tee -ia foo.log <&3)
But nothing seems to work. I'm probably just missing something.
Maybe it'd be easier to use the script command? You could either have your users run the script with script directly, or do something kind of funky like this:
#!/bin/bash
main() {
read -r -p "Input string: "
echo "User input: $REPLY"
}
if [ "$1" = "--log" ]; then
# If the first argument is "--log", shift the arg
# out and run main
shift
main "$#"
else
# If run without log, re-run this script within a
# script command so all script I/O is logged
script -q -c "$0 --log $*" test.log
fi
Unfortunately, you can't pass a function to script -c which is why the double-call is necessary in this method.
If it's acceptable to have two scripts, you could also have a user-facing script that just calls the non-user-facing script with script:
script_for_users.sh
--------------------
#!/bin/sh
script -q -c "/path/to/real_script.sh" <log path>
real_script.sh
---------------
#!/bin/sh
<Normal business logic>
It's simpler:
#! /bin/bash
tee ~/log | your_script
The wonderful thing is your_script can be a function, command or a {} command block!
I have the following test.sh script:
#!/bin/sh
echo "MY_VARIABLE=$MY_VARIABLE"
Well, if I execute the following:
export MY_VARIABLE=SOMEVALUE
/bin/bash test.sh
it prints:
MY_VARIABLE=
Why the MY_VARIABLE is not read in the test.sh script?
You can reproduce the context here using the following script:
touch test.sh
chmod a+x test.sh
echo "#!/bin/sh" >> test.sh
echo "echo "MY_VARIABLE=$MY_VARIABLE"" >> test.sh
export MY_VARIABLE=something
/bin/bash test.sh
In your script to create the context, the line
echo "echo "MY_VARIABLE=$MY_VARIABLE"" >> test.sh
creates the following line in test.sh:
echo MY_VARIABLE=
if MY_VARIABLE was unset before. The expansion of $MY_VARIABLE is done in the shell that prepares your context.
If you use single quotes
echo 'echo "MY_VARIABLE=$MY_VARIABLE"' >> test.sh
the script test.sh contains the correct line
echo "MY_VARIABLE=$MY_VARIABLE"
and prints MY_VARIABLE=something as expected.
Everything works well but if you want your parent process to keep environment update, you must source your script:
source test.sh
Otherwise, changes will only have effect during the execution of your script.
You can consider it the same as sourcing your ~/.bashrc file.
I'm a beginner. :)
I'm trying to ask the name of file from prompt in a shell
and edit that file in another shell like this:
test.sh
echo "enter file name"
read word
sh test2.sh
test2.sh
read number
echo "$number" >> $word
I get an error
Test2.sh: line 1: $mAmbiguous redirect
Any suggestion?
If you want a variable from test.sh to be visible to its child processes, you need to export it. In your case, you would seem to want to export word. Perhaps a better approach would be for test2.sh to accept the destination file as a parameter instead, though.
test.sh
echo "enter file name"
read word
test2.sh "$word"
test2.sh
#!/bin/sh
: ${1?must have destination file name} # fail if missing
read number
echo "$number" >> "$1"
#!/bin/bash
echo "Content-Type: image/gif"
echo
cat x.gif
OUTPUT=" $QUERY_STRING,$REMOTE_ADDR,$HTTP_USER_AGENT,$HTTP_REFERER,`date`"
echo $OUTPUT >> log.txt
sleep 2.5
You can try this:
save the script into some file, for example script.sh
go to the directory, where the file exists, like cd my_folder
change file mode to executable with command: chmod +x script.sh
run the file: ./script.sh
That should work for you.
I remember, once I was also looking for the answer on exactly the same question.