Command Not Found when assigning an integer variable from another script - linux

To illustrate my issue and questions consider two scripts.
Script1.sh
#!/bin/sh
test=1
echo $test
Script2.sh
#!/bin/sh
$(Script1.sh)
When I run Script1.sh from the command line directly via ./Script1.sh it produces the desired output.
1
However when I run Script2.sh which calls Script1.sh, instead I get the following error message:
Script2.sh: line 1: 1: command not found
It thinks that the integer 1 is a command for some odd reason?
I found a cheap work around which is to set a variable from the first script and pass it to the second script as a parameter but I would like to understand why this is failing.
Also, when I changed my variables value from 1 to "some text", I would expect that my echo would print "some text" to the screen. But when I call Script2.sh (which ultimately just calls Script1.sh) it doesn't print the echo to the screen. Why is that, and how do I resolve it so I can see the echo output the same as if I would have called Script1.sh directly?
Any advice would be greatly appreciated.

You're calling it wrong by using command substitution. Just use source or a subshell if you want it:
. ./Script1.sh
( ./Script1.sh )
The second one is a bit redundant since it will always run in another shell anyway, so this would make more sense instead:
( . ./Script1.sh )

Related

Bash script : Storing command with spaces and arguments in variable and then executing

Been banging my head against the wall for a couple hours so time to call in the experts. Writing a small script to run some reports on one of my office's systems and I was asked to take care of a Bash script for it. The program called "auto_rep" takes various options such as "-t" to run one task (to generate one type of report) and a "-1" to exit after one task. The options are separated by spaces when running the command from command-line. The command works directly from command line but I cannot get it to work from a script...
Below is the snippet of code causing me issues:
cmd=$(auto_rep -t createfin1report -1)
echo "running ${cmd} command..."
echo
eval $cmd
The problem is when I run the script, only the "auto_rep" part of the command (from $cmd variable) is run; basically running the program without any options. And it creates tons of reports without the "-t createfin1report -1" part of the command (yikes!). Glad I only tried it on our test system.
Anyone have any tips to help me out? Is my approach way off? BTW - had tried just storing the command in a non-array (cmd="auto_rep -t createfin1report -1") and that was causing me other headache with a "command not found" errors :)...
Thanks in advance!
Save output to an array, then executing this array.
declare -a cmd
cmd=( $(auto_rep -t createfin1report -1) )
echo Executing: "${cmd[#]}"
"${cmd[#]}"
Please make sure the output is a valid command, and spaces have been correctly placed in double-quotes.

Self-defined bash command works in terminal but not in script

I have two scripts:
fail_def.sh:
#!/bin/bash -eu
function fail() {
echo -e "$(error "$#")"
exit 1
}
bla.sh:
#!/bin/bash -eu
fail "test"
After source fail_def.sh, I can use the fail command without any problems in the terminal. However, when I call bla.sh, I always get line 2: fail: command not found.
It doesn't matter whether I call it via ./bla.sh or bash bla.sh or bash ./bla.sh, the error remains.
Adding source fail_def.sh to the beginning of bla.sh solves the problem, but I'd like to avoid that.
I'm working on an Ubuntu docker container running on a Mac, in case that is relevant.
I tried to google that problem and found some similar problems, but most of them seem to be connected to either not sourcing the file or mixing up different shell implementations, neither of which seems to be the case here.
What do I have to do to get the fail command to work inside the script?
It is expected!
The shell runs the script run with an she-bang separator always as a separate process and hence on a different shell namespace. The new shell in which your script runs does not have the function source'd.
For debugging such information, add a line echo $BASHPID which prints the process id of the current bash process on the bla.sh script after the line #!/bin/bash -eu and a test result produced
$ echo $BASHPID
11700
$ bash bla.sh
6788
fail.sh: line 3: fail: command not found
They scripts you have run on separate process where the imported functions are not shared between. One of the ways would be to your own error handling on the second script and by source-ing the second script. On the second script
$ cat fail.sh
echo $BASHPID
set -e
fail "test"
set +e
Now running it
$ source fail.sh
11700
11700
bash: error: command not found
which is obvious as error is not a shell built-in which is available. Observe the process id's same on the above case.

Call one shell script from another script and store that output of that script in a variable

I have shell script1 1.sh. I have another shell script 2.sh where I need to use the functionality of the first script and store it in a variable to use in the second script.
None of these seem to work:
a=$(sh 1.sh)
a=sh 1.sh
a=`sh 1.sh`
The first solution is correct, try for example:
echo 'echo "hello, world"' > echohello.sh
hello=$(sh echohello.sh)
echo $hello
Maybe you have an error in 1.sh or it is in a different directory? Can you call it directly by running ./1.sh?

How to handle errors in shell script

I am writing shell script to install my application. I have more number of commands in my script such as copy, unzip, move, if and so on. I want to know the error if any of the commands fails. Also I don't want to send exit codes other than zero.
Order of script installation(root-file.sh):-
./script-to-install-mongodb
./script-to-install-jdk8
./script-to-install-myapplicaiton
Sample script file:-
cp sourceDir destinationDir
unzip filename
if [ true]
// success code
if
I want to know by using variable or any message if any of my scripts command failed in root-file.sh.
I don't want to write code to check every command status. Sometimes cp or mv command may fail due to invalid directory. At the end of script execution, I want to know all commands were executed successfully or error in it?
Is there a way to do it?
Note: I am using shell script not bash
/* the status of your last command stores in special variable $?, you can define variable for $? doing export var=$? */
unzip filename
export unzipStatus=$?
./script1.sh
export script1Status=$?
if [ !["$unzipStatus" || "$script1Status"]]
then
echo "Everything successful!"
else
echo "unsuccessful"
fi
Well as you are using shell script to achieve this there's not much external tooling. So the default $? should be of help. You may want to check for retrieval value in between the script. The code will look like this:
./script_1
retval=$?
if $retval==0; then
echo "script_1 successfully executed ..."
continue
else;
echo "script_1 failed with error exit code !"
break
fi
./script_2
Lemme know if this added any value to your scenario.
Exception handling in linux shell scripting can be done as follows
command || fallback_command
If you have multiple commands then you can do
(command_one && command_two) || fallback_command
Here fallback_command can be an echo or log details in a file etc.
I don't know if you have tried putting set -x on top of your script to see detailed execution.
Want to give my 2 cents here. Run your shell like this
sh root-file.sh 2> errors.txt
grep patterns from errors.txt
grep -e "root-file.sh: line" -e "script-to-install-mongodb.sh: line" -e "script-to-install-jdk8.sh: line" -e "script-to-install-myapplicaiton.sh: line" errors.txt
Output of above grep command will display commands which had errors in it along with line no. Let say output is:-
test.sh: line 8: file3: Permission denied
You can just go and check line no.(here it is 8) which had issue. refer this go to line no. in vi.
or this can also be automated: grep specific line from your shell script. grep line with had issue here it is 8.
head -8 test1.sh |tail -1
hope it helps.

call bash script and fill input data from another bash script

I have a bash script, a.sh
And when I run a.sh, I need to fill several read. Let's say it like this
./a.sh
Please input a comment for script usage
test (I need to type this line mannually when running the script a.sh, and type "enter" to continue)
Now I call a.sh in my new script b.sh. Can I let b.sh to fill in the "test" string automaticlly ?
And one other question, a.sh owns lots of prints to the console, can I mute the prints from a.sh by doing something in my b.sh without changing a.sh ?
Thanks.
Within broad limits, you can have one script supply the standard input to another script.
However, you'd probably still see the prompts, even though you'd not see anything that satisfies those prompts. That would look bad. Also, depending on what a.sh does, you might need it to read more information from standard input — but you'd have to ensure the script calling it supplies the right information.
Generally, though, you try to avoid this. Scripts that prompt for input are bad for automation. It is better to supply the inputs via command line arguments. That makes it easy for your second script, b.sh, to drive a.sh.
a.sh
#!/bin/bash
read myvar
echo "you typed ${myvar}"
b.sh
#!/bin/bash
echo "hello world"
You can do this in 2 methods:
$ ./b.sh | ./a.sh
you typed hello world
$ ./a.sh <<< `./b.sh`
you typed hello world

Resources