Listen sharp time to run a command inside a script

Hello,
Just wondered if there is any possibility to run a command at sharp time inside a script in linux. My question is not about crontab

Example:

#!/bin/bash

cd /home/database

for i in *
do
command 1
if time is 19:00, day is Monday then run command2
if time is 20:00, day is Tuesday, then run command3
if time is 22:00, day is Friday, then run command4
if time is 00:00, day is Thursday, then run command5
done

sleep 2
exit 0

many thanks
Boris

I'm not sure what you mean by "sharp time" but does this help?

#!/bin/bash

cd /home/database

for i in *
do
   command 1
   case $(printf "%(%H:M_%u)T" -2) in
       19:00_1) command2 ;;
       20:00_2) command3 ;;
       22:00_5) command4 ;;
       00:00_4) command5 ;;
   esac
done

sleep 2
exit 0

The -2 argument to printf tells bash to substitute the time the shell (in this case the script) was invoked. You need bash 4.2 or later for this I believe.

Andrew

2 Likes

Hello Andrew,
My fault, I meant just "sharp". The word "sharp" itself is already indicating the time.
I am gonna check it and leave my comment here after then.

Many thanks
Boris

It depends on what you mean by "sharp" - the desired point in time on the nose, within a second, a few seconds, a (few) minutes?
For performance and system resources' reasons, I'd abstain from running a tight loop, checking the time within and, if met, run your command.
You could calculate the time difference from NOW, sleep for the delta seconds, an then run the command, eventually in a background subshell.
Did you consider the at command?

1 Like

Hello Rudic,
Thanks for your feedback.
How may I integrate time controller into main script?

main script

#!/bin/bash
cd /home/database1

for i in *.mp4
do
/usr/bin/ffmpeg -i $i -c copy -f mpegts pipe:1
done

time_controller

#!/bin/bash
cd /home/database1
find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc > total_duration
sleep $(cat total_duration) && 
cd /home/database2 
for i in *.mp4
do
/usr/bin/ffmpeg -i $i -c copy -f mpegts pipe:1
done

Thanks
Boris

Not sure I understand how "time_controller" works and what you want it to do... above example gravely deviates from the one in your post#1.

Hello Rudic,
I could not find any example explaining how to run at command +x seconds later. Tutorials are showing only how to run x hours later or days later etc. That's why I calculated total duration of all files inside database1. I am not sure how to use at command while there is pipe inside main script. .

Thanks for your patience
Boris

#!/bin/bash  cd /home/database
  command 1
if [ today is monday ]
then
    nohup monday &
fi
repeat for other days of the week.
...... 
 exit 0
#monday
current_time=hour * 3600 +min *60 +sec
runtime=19*3600
if current_time less than runtime
 sleep (runtime - current_time)
  do stuff
else
echo too late for today
fi

---------- Post updated at 10:35 PM ---------- Previous update was at 10:16 PM ----------

1 Like

Hello,
I am sorry for my delayed return
I will test it tomorrow and keep you posted about the result

Thanks
Boris

Not sure if you are still after this or in the meantime something else. (It might be beneficial to describe in plain text what exactly you want to do and maybe we find a better solution with a completely different way of attacking this.)

This can easily be done with several cron jobs and you don't need a script for it. Put the following in crontab:

0 19 * * 1 command1 >/dev/null 2>&1 ; command2 >/dev/null 2>&1
0 20 * * 2 command1 >/dev/null 2>&1 ; command3 >/dev/null 2>&1
0 22 * * 5 command1 >/dev/null 2>&1 ; command4 >/dev/null 2>&1
0 0 * * 4 command1 >/dev/null 2>&1 ; command5 >/dev/null 2>&1

"0 19 * * 1" i.e. means: at 19:00 every Monday, "0 0 * * 4" means at 00:00 every Thursday, and so on. See man crontab or man cron for details.

I hope this helps.

bakunin

Hello Bakunin,
Thanks for the info you shared. I am a bit familiar with crontab. I am not sure that I can do what I am trying to do exactly. Let me go in deeper to make it more clear:

my script

cd folderA
For i in *.mp4
do
ffmpeg -i $i -c copy -f mpegts pipe:1
done

if time is 19:00, go to folder B
ffmpeg -i 1.mp4 -c copy -f mpegts pipe:1
mv 1.mp4 /played_video/1.mp4
when 1.mp4 ends, 
ffmpeg -i 2.mp4 -c copy -f mpegts pipe:1
mv 2.mp4 /played_video/2.mp4

if time is 21:30 go to folder A
for i in *.mp4
do
ffmpeg -i *.mp4 -c copy -f mpegts pipe:1
done

Here is the explanation of my aim in text plain.
I need to make the script running in FolderA and play all video files, one by one, without interruption. When time is 19:00, it should suddenly stop playing the mp4 files in FolderA and should go to FolderB . Then stream 1.mp4 and pipe it. when 1.mp4 finishes, move it to the folder played_video , then stream 2.mp4 with ffmpeg in pipe mode. When stream process of 2.mp4 is finished, move it to played_video folder etc..
Then go back to folderA and keep streaming all files.
As I am piping in folder B, for some reason, I am also unable to move processed file at the end of each process.

Kind regards
Boris