How can I make my screen locker script work? - bash

I've been having some problems with my screenlocker program. Spent a day trying to solve it but nothing worked, so I decided to write a program that locks my screen:
LOCKTIME=60
lastIdleTime=0
extra=0
while [ 1 ]; do
sound=$(pacmd list-sink-inputs | grep -c "state: RUNNING")
idleTime=$(($(xprintidle) / 1000))
lock=$(gnome-screensaver-command -q | grep -c " active")
if [[ $lock != 0 ]]; then
extra=$idleTime
else
if [[ $sound != 0 || $idleTime -lt $lastIdleTime ]]; then
extra=$idleTime
fi
if [[ $(($idleTime - $extra)) -gt $LOCKTIME ]]; then
gnome-screensaver-command -l
fi
fi
lastIdleTime=$idleTime
sleep 1
done
If I execute it manually, everything goes well. But I want to run it at startup, so I tried to use crontab and create a desktop entry at ~/.config/autostart folder. But it seems that crontab doesn't execute the program, or it executes but the script can't lock my screen, and it runs with desktop entry, but xprintidle doesn't update and gnome-screensaver-command -q | grep -c " active" returns 0 all the time, so after 60 seconds it stays locking my screen every second.
I also wrote it in python, and it doesn't work either. The only diference is that gnome-screensaver-command -q | grep -c " active" returns 1 all the time.
Is there a better way to execute and keep it running (and working) every startup?
Btw, I'm using Antergos with GNOME and GDM.

Related

monitoring and searching a file with inotify, and command line tools

Log files is written line by line by underwater drones on a server. TWhen at surface, the drones speak slowly to the server (say ~200o/s on a phone line which is not stable) and only from time to time (say every ~6h). Depending on the messages, I have to execute commands on the server while the drones are online and when they hang up other commands. Other processes may be looking at the same files with similar tasks.
A lot can be found on this website on somewhat similar problems but the solution I have built on is still unsatisfactory. Presently I'm doing this with bash
while logfile_drone=`inotifywait -e create --format '%f' log_directory`; do
logfile=log_directory/${logfile_drone}
while action=`inotifywait -q -t 120 -e modify -e close --format '%e' ${logfile} ` ; do
exidCode=$?
lastLine=$( tail -n2 ${logFile} | head -n1 ) # because with tail -n1 I can got only part of the line. this happens quite often
match =$( # match set to true if lastLine matches some pattern )
if [[ $action == 'MODIFY' ]] && $match ; then # do something ; fi
if [[ $( echo $action | cut -c1-5 ) == 'CLOSE' ]] ; then
# do something
break
fi
if [[ $exitCode -eq 2 ]] ; then break ; fi
done
# do something after the drone has hang up
done # wait for a new call from the same or another drone
The main problems are :
the second inotify misses lines, may be because of the other processes looking at the same file.
the way I catch the time out doesn't seem to work.
I can't monitor 2 drones simultaneously.
Basically the code works more or less but isn't very robust. I wonder if problem 3 can be managed by putting the second while loop in a function which is put in background when called. Finally, I wonder if a higher level language (I'm familiar with php which has a PECL extension for inotify) would not do this much better. However, I imagine that php will not solve problem 3 better than than bash.
Here is the code where I'm facing the problem of abrupt exit from the while loop, implemented according to Philippe's answer, which works fine otherwise:
while read -r action ; do
...
resume=$( grep -e 'RESUMING MISSION' <<< $lastLine )
if [ -n "$resume" ] ; then
ssh user#another_server "/usr/bin/php /path_to_matlab_command/matlabCmd.php --drone=${vehicle}" &
fi
if [ $( echo $action | cut -c1-5 ) == 'CLOSE' ] ; then ... ; sigKill=true ; fi
...
if $sigKill ; then break; fi
done < <(inotifywait -q -m -e modify -e close_write --format '%e' ${logFile})
When I comment the line with ssh the script can exit properly with a break triggered by CLOSE, otherwise the while loop finishes abruptly after the ssh command. The ssh is put in background because the matlab code runs for long time.
monitor mode (-m) of inotifywait may serve better here :
inotifywait -m -q -e create -e modify -e close log_directory |\
while read -r dir action file; do
...
done
monitor mode (-m) does not buffer, it just print all events to standard output.
To preserve the variables :
while read -r dir action file; do
echo $dir $action $file
done < <(inotifywait -m -q -e create -e modify -e close log_directory)
echo "End of script"

Checking for status of qsub jobs running within shell script

I have been given a c shell script that launches 800 individual qsubs for a sample. I need to run this script on more than 500 samples (listed in samples.txt). To automate the process, I thought about running the script (named SrchDriver) using the following bash shell script:
#!/bin/sh
for item in $(cat samples.txt)
do
(cd dir_"$item"/MAPGAPS && SrchDriver "$item"_Out 3)
done
This script would launch the SrchDriver script for all samples one right after another which would result in too many jobs on the server at one time. I would like to run only one sample at a time by waiting for all qsubs to finish for a particular sample.
What is the best way to put in a check for running/waiting jobs for a sample and holding the launch of the Srchdriver script for additional samples until all jobs are finished for the current sample?
I was thinking to first wait for 30 seconds and then check status of the qsubs (name of jobs is mapgaps). Next, I wanted to use a while loop to check the status every 30 seconds. Once the status is no longer 0, then proceed to the next sample. Would this be correct?
sleep 30
qstat | grep mapgaps &> /dev/null
while [ $? -eq 0 ];
do
sleep 30
qstat | grep mapgaps &> /dev/null
done;
If correct, how would I combine it with my for-loop? Would the following code below be correct?
#!/bin/sh
for item in $(cat samples.txt)
do
(cd dir_"$item"/MAPGAPS && SrchDriver "$item"_Out 3)
sleep 30
qstat | grep mapgaps &> /dev/null
status=$?
while [ $status = 0 ]
do
sleep 30
qstat | grep mapgaps &> /dev/null
status=$?
done
done
Thanks in advance for help. Please let me know if more information is needed.
Your script should work as is, indeed. The logic is sound and the syntax is correct.
A small improvement: the while statement can take the return status of a command directly, without using $?, so you could write your script like this:
#!/bin/sh
for item in $(cat samples.txt)
do
(cd dir_"$item"/MAPGAPS && SrchDriver "$item"_Out 3)
sleep 30
while qstat | grep mapgaps &> /dev/null
do
sleep 30
done
done

On closing the Terminal the nohupped shell script (with &) is stopped

I'm developing a simple screenshot spyware which takes screenshot every 5 seconds from start of the script. I want it to run on closing the terminal. Even after nohupping the script along with '&', my script exits on closing the terminal.
screenshotScriptWOSleep.sh
#!/bin/bash
echo "Starting Screenshot Capture Script."
echo "Process ID: $$"
directory=$(date "+%Y-%m-%d-%H:%M")
mkdir ${directory}
cd ${directory}
shotName=$(date "+%s")
while true
do
if [ $( date "+%Y-%m-%d-%H:%M" ) != ${directory} ]
then
directory=$(date "
+%Y-%m-%d-%H:%M")
cd ..
mkdir ${directory}
cd ${directory}
fi
if [ $(( ${shotName} + 5 )) -eq $(date "+%s" ) ]
then
shotName=$(date "+%s" )
screencapture -x $(date "+%Y-%m-%d-%H:%M:%S" )
fi
done
I ran the script with,
nohup ./screenshotScriptWOSleep.sh &
On closing the terminal window, it warns with,
"Closing this tab will terminate the running processes: bash, date."
I have read that the nohup applies to the child process too, but i'm stuck here. Thanks.
Either you're doing something really weird or that's referring to other processes.
nohup bash -c 'sleep 500' &
Shutdown that terminal; open another one:
ps aux | grep sleep
409370294 26120 1 0 2:43AM ?? 0:00.01 sleep 500
409370294 26330 26191 0 2:45AM ttys005 0:00.00 grep -i sleep
As you can see, sleep is still running.
Just ignore that warning, your process is not terminated. verify with
watch wc -l nohup.out

How to exit bash script after while loop gets true?

i'm new at bash scripting and i am trying to write a script to check if an ethernet device is up and if so exit the script.
That doesn't work as intended, maybe someone can give me a hint.
I start the script, then plug in my device and the script just seems to hang up in the terminal. It is not getting back to the command line.
When the device is plugged in already and the ethernet dev is up the script just runs perfectly. It then echoes 'Connected' and throws me back to command line.
#! /bin/sh
t1=$(ifconfig | grep -o enxca1aea4347b1)
t2='enxca1aea4347b1'
while [ "$t1" != "$t2" ];
do
sleep 1;
done
echo "Connected"
exit 0
You don't even need to make the comparison; just check the exit status of grep.
t2='enxca1aea4347b1'
until ifconfig | grep -q "$t2"; do
sleep 1;
done
echo "Connected"
exit 0
In fact, you don't even need grep:
until [[ "$(ifconfig)" =~ $t2 ]]; do
sleep 1
done
You've made an infinite loop, since you're not updating the value of $t1 inside the while statement.
Instead, try:
#! /bin/sh
t1=$(ifconfig | grep -o enxca1aea4347b1)
t2='enxca1aea4347b1'
while [ "$t1" != "$t2" ];
do
sleep 1;
t1=$(ifconfig | grep -o enxca1aea4347b1)
done
echo "Connected"
exit 0

Bash script if else execute once cronjob every minute

I have a bash script in crontab that runs every minute.
In this bash script i have a sql query which goes and check for the number
If the number is greater than predefined number then I want to move files and replace files.
This works absolutely fine, the problem is that since this script runs every minute via crontab, when the script runs next time it overwrites the file.
Is there any logic that I can put that this code is only run once but let the cron run every minute.
here is the code
#!/bin/bash
count=`mysql -B -u root -ppassword -e 'select count(*) from column' table | tail -n +2`
allowed="500"
if [ "$count" -ge "$allowed" ]
then
mv /netboot/var/www/html /usr/html/
mv /netboot/var/www/back /netboot/var/www/html
echo "Not Allowed - Disable Code goes here"
else
echo "all is good for now $count"
fi
exit 0
Your help is appreciated.
I have managed to fix this by creating another if statement within the parent if.
See below.
#!/bin/bash
count=`mysql -B -u root -ppassword -e 'select count(*) from column' table | tail -n +2`
allowed="500"
if [ "$count" -ge "$allowed" ]
then
if
html folder exists in /usr/
then
mv /netboot/var/www/html /usr/html/
mv /netboot/var/www/back /netboot/var/www/html
else
echo " "
fi
echo "Not Allowed - Disable Code goes here"
else
echo "all is good for now $count"
fi
exit 0

Resources