Run bash script as a sudo user with some other computations - linux

I have some other piece of bash script calling some external other scripts and running as a sudo user. Below is an example which can be used as a sample to reproduce my problem.
#!/bin/bash
databaseName=${1}
tableNames=${2}
IFS=','
read -r -a tableNamesArray <<< "${tableNames}"
#sudo su <<WRAPPER
echo "Tables inside ${databaseName} are ::: ${tableNamesArray[#]}"
echo "-- SQL FILE --" > ${databaseName}_schema.hql
echo "$tableNames"
echo "${tableNamesArray[#]}"
for eachTable in "${tableNamesArray[#]}"
do
echo "$eachTable"
echo "MY_QUERY $databaseName.$eachTable;" >> ${databaseName}_schema.hql
done
#WRAPPER
This script is working fine. I want mydb_schema.hql with some records of SQL script. Assume I am calling this above as ./sample.sh db table1,table2 to get a SQL file with below queries-
-- SQL FILE --
MY_QUERY db.table1;
MY_QUERY db.table2;
Above is working fine and getting all as per my need.
Here is my problem-
#!/bin/bash
databaseName=${1}
tableNames=${2}
IFS=','
read -r -a tableNamesArray <<< "${tableNames}"
sudo su <<WRAPPER
#..Other scripts that I need to call as sudo..
echo "Tables inside ${databaseName} are ::: ${tableNamesArray[#]}"
echo "-- SQL FILE --" > ${databaseName}_schema.hql
echo "$tableNames"
echo "${tableNamesArray[#]}"
for eachTable in "${tableNamesArray[#]}"
do
echo "$eachTable"
echo "MY_QUERY $databaseName.$eachTable;" >> ${databaseName}_schema.hql
done
WRAPPER
I have used like this and I am able to call other scripts as a sudo user in between code. This WRAPPERis working fine to call other scripts as a sudo user but not able to call for loop inside the WRAPPER. Not sure what problem is for me? Any help is appreciated. Thanks

Related

How to run script multiple times and after every execution of command to wait until the device is ready to execute again?

I have this bash script:
#!/bin/bash
rm /etc/stress.txt
cat /dev/smd10 | tee /etc/stress.txt &
for ((i=0; i< 1000; i++))
do
echo -e "\nRun number: $i\n"
#wait untill module restart and bee ready for next restart
dmesg | grep ERROR
echo -e 'AT+CFUN=1,1\r\n' > /dev/smd10
echo -e "\nADB device booted successfully\n"
done
I want to restart module 1000 times using this script.
Module is like android device witch has linux inside it. But I use Windows.
AT+CFUN=1,1 - reset
When I push script, after every restart I need a command which will wait module and start up again and execute script 1000 times. Then I do pull in .txt file and save all output content.
Which command should I use?
I try commands like wait, sleep, watch, adb wait-for-device, ps aux | grep... Nothing works.
Can someone help me with this?
I find the solution. This is how my script actually looks:
#!/bin/bash
cat /dev/smd10 &
TEST=$(cat /etc/output.txt)
RESTART_TIMES=1000
if [[ $TEST != $RESTART_TIMES ]]
then
echo $((TEST+1)) > /etc/output.txt
dmesg
echo -e 'AT+CFUN=1,1\r\n' > /dev/smd10
fi
These are the steps that you need to do:
adb push /path/to/your/script /etc/init.d
cd /etc
cat outputfile.txt - make an output file and write inside file 0 ( echo 0 > output.txt )
cd init.d
ls - you should see rc5.d
cd .. then cd rc5.d - go inside
ln -s ../init.d/yourscript.sh S99yourscript.sh
ls - you should see S99yourscript.sh
cd .. return to init.d directory
chmod +x yourscript.sh - add permision to your script
./yourscript.sh

Using tee with bash hangs with some scripts

I have a simple script file startsql.sh to start mysql:
#!/bin/bash
#Script to Start MySQL
echo "Starting MySQL"
if sudo service mysqld start; then
echo "MySQL started successfully!"
else
echo "Error: Failure to start MySQL" 1>&2
exit 1
fi
I run it using:
bash startsql.sh |& tee -a scriptlogs.log
Though the service seems to start successfully, the command hangs after showing the messages on the command window. It works fine without hanging if I remove the tee. Interestingly I have a similar script to stop mysql and it works fine without issues. I checked and find no difference between the two scripts.
After searching a lot, I found that using the below works, but the side effect of this is that the tee process is still running in the background
bash startsql.sh > >( tee -a scriptlogs.log) 2>&1
Can someone please help me understand why does using tee hang on some occasions.
Will you teach me the version of bash?
If you use bash 3.2.57, the error occure like this.
$ bash ./startsql.sh |& tee -a output.txt
bash ./startsql.sh |& tee -a output.txt
bash: syntax error near unexpected token `&'

Start a Pythonscript in a Screen session

i am currently working on a little bash script to start a .py file in a Screen session and could use help.
I have these 2 Files:
test.py (located at /home/developer/Test/):
import os
print("test")
os.system("ping -c 5 www.google.de>>/home/developer/Test/test.log")
test.sh (located at /home/developer/):
#!/bin/bash
Status="NULL"
if ! screen -list | grep -q "foo";
then
Status="not running"
else
Status="running"
fi
echo "Status: $Status"
read -p "Press [Enter] key to start/stop."
if [[ $Status == "running" ]]
then
screen -S foo -p 0 -X quit
echo "Stopped Executing"
elif [[ $Staus == "not running" ]]
then
screen -dmS foo sh
screen -S foo -X python /home/developer/Test/test.py
echo "Created new Instance"
else
exit 1
fi
It works as intendet until it has to start the python script aka. this line:
screen -S foo -X python /home/developer/Test/test.py
when running it in my normal shell i get:
test
sh: 1: cannot create /home/developer/Test/test.log: Permission denied
MY Questions:
I understand the cause of the Permission denied case (works with sudo) but how do i give Permissions and more interestingly, to whom do i give the Permissions to? (python? | screen? | myuser?)
Is the line to create a new instance in which the script runs correct like that?
Can u think of a better way to execute a python script which has to run night and day but is start and stoppable and doesn't block the shell?
To answer your questions:
You should not need to use sudo at all if the proper user/group is set on the scripts.
$ chmod 644 <user> <group> <script name>
The line creating the new instance does not look correct, it should be more like:
screen -S foo -d -m /usr/bin/python /home/Developer/Test/test.py
While using full path to the python exec; remove useless preceding line: screen -dmS foo sh
Screen is more than adequte to prefer such tasks.
Other problems in your script:
Add a shebang to the python script (eg. #!/usr/bin/python)
Typo on line 20 of test.sh: should be $Status, not $Staus
You may need to initially create test.log before executing your script (eg. touch test.log)

shell save MySQL query result to a file

I have a script which runs a MySQL query, something like this:
#!/bin/sh
user="root"
pwd="test"
database="mydb"
command="long...
long... query in
multiple lines"
mysql -u $user -p$pwd << EOF
use $database;
$command
EOF
This query does a backup from a table to another. Is it possible to save the query result in a file without using mysql INTO OUTFILE? I only want to know if the query failed or succeeded.
If it succeeded something like 1 row(s) affected or if it failed Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ...
Update
Solution 1: () act as a chain of commands, so wrapping them in a variable gets the result of those commands. Then simply output the result of that variable in a file.
output=$( mysql -u $user -p$pwd << EOF
use $database;
$command
EOF
)
echo "$output" >> /events/mysql.log
Solution 2: use tee as system command to send the result of the commands into a file, but this needs to be done from the crontab, like this:
*/1 * * * * root sh /events/mysql.sh |tee -a /events/mysql.log
http://forums.mysql.com/read.php?10,391070,391983#msg-391983
My working solution:
user="root"
pwd="root12345"
database="mydb"
command="long ...long query"
mysql -u $user -p$pwd << EOF >> /events/mysql.log 2>&1
use $database;
$command;
EOF
This should work:
output=$( mysql -u $user -p$pwd << EOF
use $database;
$command
EOF
)
echo "$output" >> outfile
The correct way to handle error-messages is to through stderr. Use 2>&1 to catch the error.
So, add this to the end of your script:
>> install.log 2>&1
you can also do it like this:
#!/bin/sh
user="root"
pwd="test"
database="mydb"
command="long...
long... query in
multiple lines"
mysql -u$user -p$pwd -D$database -e "$command" > file
It's easier to use the MySQL tee command to send output.
To get the logging process started, just use the tee command,
tee /tmp/my.out;
#!/bin/sh
user="root"
pwd="test"
database="mydb"
$pathToFile = "/tmp/my.out"
command="long...
long... query in
multiple lines"
mysql -u $user -p$pwd << EOF
tee $pathToFile
use $database;
$command
EOF
EDIT
Since tee is reportedly not working inside script, you could also log output using Tee directly when running the script.
mysql_bash.sh > >(tee -a script.log)

Stop being root in the middle of a script that was run with sudo

There is a list of commands that only succeed when they are prefaced with sudo.
There is another list of commands that only succeed when the user runs them without sudo.
I want to execute all of these commands from the same script.
I'd like to avoid having to do the following:
#!/usr/bin/env bash
sudo sudo_command_one;
sudo sudo_command_two;
sudo sudo_command_three;
non_sudo_command;
sudo sudo_command_four;
The reason for this, is because sudo has a time-out, and these commands will likely take a long time. I don't want to be burdened with having to re-type the sudo password occasionally. I could perhaps extend the time-out of sudo indefinitely, but that is also something I would prefer to avoid if there is an easier way.
Therefore, I'm going to run the script like this:
sudo ./script
But this will prevent the non-sudo commands from working.
What are the missing commands I need:
#!/usr/bin/env bash
sudo_command_one;
sudo_command_two;
sudo_command_three;
[turn sudo off for a moment]
non_sudo_command;
[ok, turn sudo back on]
sudo_command_four;
Unfortunately, the order of the commands cannot be rearranged so that I run all the sudo commands first, followed by all the non-sudo commands(or vice versa).
In a script run by sudo, use:
su -c "shell command; shell command" $SUDO_USER
within that script to execute commands as the normal user who invoked sudo.
This works because sudo sets the environment variable SUDO_USER to the original username.
If you have a bunch of commands to run as the original user, you could use a hereis document.
Here is an example script file as proof of concept:
myscript.sh
#!/bin/bash
echo "Part 1"
echo "now running as:"
whoami
echo "SUDO_USER is:"
echo $SUDO_USER
su $SUDO_USER <<EOF
echo "Part 2"
echo "now running as:"
whoami
echo "SUDO_USER is:"
env | grep ^SUDO_USER
sleep 5
EOF
echo "Part 3"
echo "now running as:"
whoami
echo "SUDO_USER is:"
echo $SUDO_USER
And here's the output on sudo ./myscript.sh
Part 1
now running as:
root
SUDO_USER is:
paul
Part 2
now running as:
paul
SUDO_USER is:
SUDO_USER=paul
Part 3
now running as:
root
SUDO_USER is:
paul
Warning: This technique doesn't work so well with nested sudo. If sudo is nested twice, e.g.
sudo su
echo $SUDO_USER
---> me
sudo su
echo $SUDO_USER
---> root
SUDO_USER will return root, not the original username. su $SUDO_USER would then keep running as root. Be careful to avoid that scenario, and it should work ok.
Here is how I would run it in a script.
#! /bin/bash
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root";
exit 1;
else
NON_ROOT_USER=$(who am i | awk '{print $1}');
echo "root ran this echo.";
sudo -u $NON_ROOT_USER echo "$NON_ROOT_USER ran this echo.";
fi
sudo ./script.sh

Resources