How to run sql scripts serially in bash script? - linux

I have 2 DB2 sql scripts that I need to run. I have tried to put both of them in bash script and execute them.
here is script.sh:
#!/bin/bash
db2 -tf firstscript.sql;
db2 -tf secondscript.sql;
When I run this, I get the following error:
DB21034E The command was processed as an SQL statement because it was
not a valid Command Line Processor command. During SQL processing it
returned: SQL1024N A database connection does not exist.
SQLSTATE=08003
But I have made sure that the database connection already exists.
I think that the commands inside the sql scripts are not executed sequentially.
Because when I run each command individually, there is no error.
Also, when I run both the commands inline i.e. db2 -tf firstscript.sql;db2 -tf firstscript.sql, even then the code works.
I thought that it could have something to do with #!/bin/bash, so I removed it from the script.sh file and then executed it. Even then, it returned the same error.
What would be the possible problem and its solution?

When you have a establish connection, it is hold in your current environment. When you call a bash script, it will create a subshell, and that will not have any connection.
In order to solve this problem, you need to reuse the current environment by sourcing the script (as #jm666 said):
. ./script.sh
Make sure about the dot followed by a space before the scriptname.
db2 connect to sample
. ./script.sh
FYI, the commands inside the script will be executed sequentially, as you defined them.

Related

About script execution permissions on Linux shell

I've just created a script, let's say, "helloworld.sh".
The script doesn't yet have execution permissons: -rw-rw-r--
If I try to execute that script with: "./helloword.sh", I'll get an error message, as expected. But, if I try to execute that same script as: . helloword, it will execute with no problems.
How? Why does that happen?
This happens because on Linux the "." (dot) alone is a built-in command that execute the script within your current session with your current shell. This is the same as calling the script with source command (the BSD default method). It's almost the same than execute with bash helloworld.sh.
When you call the script with ./helloworld.sh or /root/helloworld.sh the shell will try to figure out how to execute it, if the file is a binary, it will simply run, if it is a script, the shell will read the first line looking for the interpreter. To do this, you'll need execution permission.
To simplify:
One is a command;
The other one is a path.
You can even run:
. --help
About . against bash:
This is why we use . or source to load variables from a file in our session, for example, when we change ~/.bashrc and reload it without login again.
You can see this happens when you execute:
. /etc/os-release
All variables defined inside this file will be loaded and available in your current shell session.
The same will not happen if you execute:
bash /etc/os-release
Because you opened a "new session" inside that bash that you called, the new bash executes and close, cleaning the session.
The same process happen if you give execute permission +x to the script, because when you call the script with ./ or something like that, a new session will be created too.

don't understand atquery command script

I'm using a big-data database. in one of it's tutorial it has recommended me to use below bash scripts if order to running queries:
#!/bin/sh
# this will launch the real atquery program with the given .sql file
# note: please adjust INSTALLNAME, HOST and PORT to reflect your installation
/home/lms/INSTALLNAME/atquery HOST:PORT $*
Then, start runnable .sql files like the following:
#!/usr/local/bin/runatquery
select count(*) from mytable during all
I don't understand $* part of the /home/lms/INSTALLNAME/atquery HOST:PORT $*. what will $* does?
this was suppose to create a shell script in order to run a query, but another problem is this is two file (I supposse because we two #! in that) so how will this two file help me to run queries? I suppose if we had a script with below code in it, it would do this work to me better and without confusion:
!/bin/sh
/home/lms/INSTALLNAME/atquery HOST:PORT -e 'select count(*) from mytable during all'
You have to create that script as recommended (you didn't include that, probably right before the script) as a file with the executable bit on, and changing INSTALLNAME, HOST and PORT as per your system requirements.
The $* expands to all parameters received by the script.
The second file is an example of how you can create scripts that are run by runatquery.

shell script run when I am root but I get a permission denied when it is invoked from a Makefile (still as root)

I need to run a Make script that invokes a shell script.
I can run the shell script directly as root but when running make on the makefile (still as root) make is denied permission to run the same shell script?
The offending line in the Makefile is that one:
PLATFORM=$(shell $(ROOT)/systype.sh)
I could go in and hardcode the value of every PLATFORM variable of every Makefile scrip on the system but that would be pointless fix, I'd like to understand why there is that Permission Denied error:
make[1]: execvp: ../systype.sh: Permission denied
PS: The content of the shell script is not the issue even if the shell script only contain ls or echo linux the Permission is Denied to the Make utility to run the shell script.
PS: I am not a make expert by an mean so if the explanation is related to Make please be as specific as you can.
In your comments above you say when you "run it manually" you use . scriptname.sh, is that correct? You use . followed by scriptname.sh?
That does not run the script, that sources the script. Your statement that scriptname.sh will execute with and without the x permission since it is a shell script is wrong. You can source the script if you have read permissions. But you cannot execute the script unless you have execute permissions.
"Sourcing" means that a new shell is not started: instead your current shell (where you type that command) reads the contents of the script and runs them just as if you'd typed them in by hand, in the current shell. At the end all the side-effects (directory changes, variable assignments, etc.) that were performed in that script are still available in your current script.
"Executing" means that the script is treated like a program, but the program is a new shell that's started, which then reads the contents of the script and executes it. Once the script ends the shell exits and all side-effects are lost.
The $(shell ...) function in make will not source your script (unless you also use . there, which you did not). It will try to run your script. The error you show implies that either systype.sh did not have the execution bit set, or else that it had an invalid #! line. There's no other explanation I can think of.
If sourcing the file really does what you want then why not just use the same method in $(shell ...) that you use in your own personal use:
PLATFORM=$(shell . $(ROOT)/systype.sh)
If changing the user permission didn't work, are you sure that whatever user owns the script is the same user you're using to invoke make? You say you're "running as root"; is the script owned by root? Or is it owned by you and you're running sudo make or similar?
I don't know why you don't just use:
chmod +x systype.sh
and call it a day.
Adding execution permission to the file Group rather that the file User fixed the issue.
PS: I wonder why? It seems the Make utility run shell scripts not with the same user that started Make...

change directory command in my script is not being recognize when i run the script using plink

I'm running a batch file (export.bat) in Windows 7 using plink to execute a script in a remote Linux server machine, but I get this error:
./test.sh: line 3: back.sh: command not found
Batch file:
#echo off
cls
plink 1.1.10.11 -l user -pw pass "bash ./test.sh"
Script in the remote server:
#!/bin/sh
cd /path/path/path
script --table filename--filebase /path/path/path/path
exit
I'm assuming script in your remote script is actually back.sh, and that it exists in /path/path/path.
To execute a script back.sh in the directory you cd to (i.e. the current directory), use ./back.sh instead of just back.sh.
PS: You should generally try to avoid sanitizing input and output of things you post on StackOverflow. It often ends up confusing. For example, you say you get the error line 3: back.sh: command not found, but your remote script does not contain the command back.sh on line 3 or anywhere.
Instead, invest 15 minutes in making a runnable test case with no sensitive data, that you can actually execute and copy files and errors from verbatim. The bash tag wiki has tips for this.

Difference between different ways of running shell script

Recently I have been asked a question. What are the different ways of executing shell script and what is the difference between each methods ?
I said we can run shell script in the following methods assuming test.sh is the script name,
sh test.sh
./test.sh
. ./test.sh
I don't know the difference between 1 & 2. But usually in first 2 methods, upon executing, it will spawn new process and run the same. Whereas in the last method, it won't spawn new process. Instead it runs in the same one.
Can someone throw more insight on this and correct me if I am wrong?
sh test.sh
Tells the command to use sh to execute test.sh.
./test.sh
Tells the command to execute the script. The interpreter needs to be defined in the first line with something like #!/bin/sh or #!/bin/bash. Note (thanks keltar) that in this case the file test.sh needs to have execution rights for the user performing this command. Otherwise it will not be executed.
In both cases, all variables used will expire after the script is executed.
. ./test.sh
Sources the code. That is, it executes it and whatever executed, variables defined, etc, will persist in the session.
For further information, you can check What is the difference between executing a bash script and sourcing a bash script? very good answer:
The differences are:
When you execute the script you are opening a new shell, type
the commands in the new shell, copy the output back to your current
shell, then close the new shell. Any changes to environment will take
effect only in the new shell and will be lost once the new shell is
closed.
When you source the script you are typing the commands in your
current shell. Any changes to the environment will take effect and stay in your current shell.

Resources