I used this bash script here to download only short parts of long yt videos:
#!/bin/bash
#taken from https://unix.stackexchange.com/a/388148/48971
if [ $# -lt 4 ]; then
echo "Usage: $0 <youtube's URL> <HH:mm:ss.milisecs from time> <HH:mm:ss.milisecs to time> <output_file_name>"
echo "e.g.:"
echo "$0 https://www.youtube.com/watch?v=T1n5gXIPyws 00:00:25 00:00:42 intro.mp4"
exit 1
fi
echo "processing..."
from=$(date "+%s" -d "UTC 01/01/1970 $2")
to=$(date "+%s" -d "UTC 01/01/1970 $3")
from_pre=$(($from - 30))
if [ $from_pre -lt 0 ]
then
from_pre=0
fi
from_pre_command_print=$(date -u "+%T" -d #$from_pre)
from_command_print=$(date -u "+%T" -d #$(($from - $from_pre)))$(grep -o "\..*" <<< $2)
to_command_print=$(date -u "+%T" -d #$(($to - $from_pre)))$(grep -o "\..*" <<< $3)
command="ffmpeg "
for uri in $(youtube-dl -g $1)
do
command+="-ss $from_pre_command_print -i $uri "
done
command+="-ss $from_command_print -to $to_command_print $4"
echo "downloading with the following command:"
echo "$command"
$command
but the problem is its only precise to the full second.
I want to use it to download a bunch of very short clips (only one word long mostly) those are often below 1 second long.
I tryed to fix this by using milliseconds in the date.
But then i found out bash can only subtract with integers.
Here is what i tryed:
from=$(date "+%s.%3N" -d "UTC 01/01/1970 $2")
to=$(date "+%s.%3N" -d "UTC 01/01/1970 $3")
function diff {
diff="$(echo $from - 5 | bc)"
echo $diff
}
from_pre=$diff
echo $diff
but the workaround using bc didnt work because later in the script its again throwing errors because bash dosnt know what to do with non integers.
a sample command would look like this:
sh download_youtube.sh https://www.youtube.com/watch?v=dH3auOKyxio 00:06:28.230 00:06:28.740 clip004.mp4
and this works...if the the timeframe is more than 1 second.
Sadly i am out of knowlage here how to make it more precise.
This all is part of a project to make automated compilations of specific word from a youtube channel more on that here:
https://github.com/moeC137/video-recutter
I am very thankfull for every help
edit:
after a bit try an error i found out that this seams to work for me:
#!/bin/bash
#taken from https://unix.stackexchange.com/a/388148/48971
if [ $# -lt 4 ]; then
echo "Usage: $0 <youtube's URL> <HH:mm:ss.milisecs from time> <HH:mm:ss.milisecs to time> <output_file_name>"
echo "e.g.:"
echo "$0 https://www.youtube.com/watch?v=T1n5gXIPyws 00:00:25 00:00:42 intro.mp4"
exit 1
fi
echo "processing..."
from=$(date "+%s" -d "UTC 01/01/1970 $2")
to=$(date "+%s" -d "UTC 01/01/1970 $3")
from_pre=$(($from - 20))
#to_post=$(($to + 20))
if [ $from_pre -lt 0 ]
then
from_pre=0
fi
from_pre_command_print=$(date -u "+%T" -d #$from_pre)
from_command_print=$(date -u "+%T" -d #$(($from - $from_pre)))$(grep -o "\..*" <<< $2)
to_command_print=$(date -u "+%T" -d #$(($to - $from_pre)))$(grep -o "\..*" <<< $3)
#to_post_command_print=$(date -u "+%T.%3N" -d #$to_post)
command="ffmpeg "
for uri in $(youtube-dl -g $1)
do
command+="-ss $from_pre_command_print -i $uri "
done
command+="-ss $from_command_print -to $to_command_print $4"
echo "downloading with the following command:"
echo "$command"
$command
But i starting to think the orginal script actually works with milleseconds.
Because this:
sh download_youtube.sh https://www.youtube.com/watch?v=dH3auOKyxio 00:06:28.230 00:06:28.740 clip004.mp4
works, but when try to combine it with the script from here How to repeat a command for every line in a textfile with given arguments from the textfile (Bash?) it dosent use the milliseconds anymore.
Solved
The orginal Script worked. It just didnt like the "," in the timestamps, i replaced them with "." and now its working.
solved by replacing "," in timestamps with "."
Related
This question already has answers here:
Value too great for base (error token is "09")
(7 answers)
Value too great for base (error token is "08") [duplicate]
(1 answer)
Closed 5 months ago.
I have a script that looks at the current time, does some tasks and notifies me 1 minute before the timer ends. For some reason there is a problem and the script does not pass the condition "IF"
I read that it seems like bash interprets numbers not as a decimal number. I tried to solve the problem by removing the first zero from the string. Bash will understand this as a decimal number and perform a subtraction operation.
For example. Turn off the computer after 10 minutes. Now is 01:00:00. Shutdown at 01:10:00
The script makes a timecode file with name "T01H10M.shutdown" and takes all the necessary numbers of hour and minute from it.
When the time comes to 01:09:00, the script notifies me about the imminent completion of the work.
#Search shutdown time from file name
SearchFilenameDateWhenPCgotoShutdown="$(find /root/ -name '*.shutdown')"
SearchTimeHour=$(echo $SearchFilenameDateWhenPCgotoShutdown | cut -f2 -d "T"| cut -f1 -d "H")
SearchTimeMinute=$(echo $SearchFilenameDateWhenPCgotoShutdown | cut -f2 -d "H" | cut -f1 -d "M")
#Calculation of the penultimate minute and Ńorrection of the subtraction error.
SearchTimeMinuteMinus1=$(($SearchTimeMinute - 1 ))
if [ $SearchTimeMinuteMinus1 -eq -2 ]; then
SearchTimeMinuteMinus1=58;
fi
if [ $SearchTimeMinuteMinus1 -eq -1 ]; then
SearchTimeMinuteMinus1=59
fi
#Determining the current hour and minute
RealTimeHour=$(date "+%H")
RealTimeMinute=$(date "+%M")
if [ $RealTimeMinute = 00 ];
then
RealTimeMinute=0;
else
RealTimeMinute=`echo $RealTimeMinute |sed 's/^0*//'`
fi
#The condition matches the current hour
if [ $SearchTimeHour = $RealTimeHour ]; then
if [ $SearchTimeMinuteMinus1 = $RealTimeMinute ]; then
curl -s "https://api.telegram.org/bla bla bla bla &> /dev/null
fi
And here there is an error that when the current time is in minutes from 00-07 minutes, the condition IF = 00 then = 0 else remove "0" work fine and corrects the number to decimal with a condition. Output 1, 2, 3...7 And when the minute is already 08, the script stops at the stage of checking minutes.
if [ $SearchTimeMinuteMinus1 = $RealTimeMinute ]; then
And I don't understand why!
I tried to do it in a separate script.
B=08
if [ $B = 00 ];
B=0;
else
B=`echo $B |sed 's/^0*//'`
fi
echo $B
He works. Output 8. Why I can't do it in the main script, I don't understand.
Screenshot with each 2 min script run
Help please.
--------------------UPD 4.10.22--------------------
OK! Thank you all for your advice. I fixed the code and it works. But! Another problem :D When the time comes at 59 minutes. An error occurs in stage.
if [ $SearchTimeHour = $RealTimeHour ]; then
Problem
This is very strange! After all, all variables are defined correctly. Any ideas?
Full code:
#!/bin/bash
if ping -c 2 100.100.100.100 | grep "ttl"; then
if ping -c 2 192.168.10.1 | grep "ttl"; then
if ping -c 2 192.168.88.102 | grep "ttl"; then
#OMV name
NameOMV="Standart OMV"
#The option determines how many minutes to turn off the system
ShutDownParameterMinutes=2
#Defining the startmark file in the script
startmark=/root/startmark
#Checking the existence of the startmark file
if [ -f $startmark ]
then
#Recording when to switch off to a variable
SearchFilenameDateWhenPCgotoShutdown="$(find /root/ -name '*.shutdown')"
#Determination of the hour and minute of shutdown
SearchTimeHour=$(echo "$SearchFilenameDateWhenPCgotoShutdown" | cut -f2 -d "T"| cut -f1 -d "H")
SearchTimeMinute=$(echo "$SearchFilenameDateWhenPCgotoShutdown" | cut -f2 -d "H" | cut -f1 -d "M")
#Determination of the hour and minute of shutdown minus 1 minute for notification in telegrams
#Correction of the subtraction error of 2 minutes - 2 minutes becomes 58 minutes, and -1 = 59 minutes
SearchTimeMinuteMinus1=$((SearchTimeMinute - 1 ))
if [ "$SearchTimeMinuteMinus1" -eq -2 ]; then
SearchTimeMinuteMinus1=58
fi
if [ "$SearchTimeMinuteMinus1" -eq -1 ]; then
SearchTimeMinuteMinus1=59
fi
curl -s "https://api.telegram.org/blablabla&text=%F0%9F%93%B7 SearchTimeMinuteMinus1=${SearchTimeMinuteMinus1}" &> /dev/null
#Determining the current hour and minute
RealTimeHour=$(date "+%H")
RealTimeMinute=$(date "+%M")
RealTimeMinute=$((10#$RealTimeMinute))
curl -s "https://api.telegram.org/blablabla&text=%F0%9F%93%B7 RealTimeHour=${RealTimeHour}" &> /dev/null
curl -s "https://api.telegram.org/blablabla&text=%F0%9F%93%B7 RealTimeMinute=${RealTimeMinute}" &> /dev/null
curl -s "https://api.telegram.org/blablabla&text=%F0%9F%93%B7 TICK $(date "+%d.%m.%Y - %H:%M:%S")" &> /dev/null
#The condition matches the current hour
if [ "$SearchTimeHour" -eq "$RealTimeHour" ]; then
curl -s "https://api.telegram.org/blablabla&text=%F0%9F%93%B7 Hour OK" &> /dev/null
if [ "$SearchTimeMinuteMinus1" -eq "$RealTimeMinute" ]; then
curl -s "https://api.telegram.org/blablabla&text=%F0%9F%93%B7 Minute OK" &> /dev/null
rm "$SearchFilenameDateWhenPCgotoShutdown"
rm startmark
curl -s "https://api.telegram.org/blablabla&text=%F0%9F%93%B7 $NameOMV is less 1 minutes left before shutdown" &> /dev/null
fi
fi
else
#Creating a startmark
touch startmark
#Notification in telegram about the start of the shutdown procedure
echo "OrangePi is creating startmark to offline: $(date "+%d.%m.%Y - %H:%M:%S")" >> shutdownlog.txt
#We determine the time when to turn off
DateWhenPCgotoShutdown=$(date +"T""%H""H""%M""M" --date="$ShutDownParameterMinutes minute")
TimeStampStartName="${DateWhenPCgotoShutdown}.shutdown"
touch "$TimeStampStartName"
chmod +x "$TimeStampStartName"
#Notification in telegram when to turn off the computer
TelegramMessage="OrangePi $NameOMV is creating startmark to offline: $(date "+%d.%m.%Y - %H:%M:%S" --date="$ShutDownParameterMinutes minute")"
echo "${TelegramMessage}" >> shutdownlog.txt
curl -s "https://api.telegram.org/blablabla&text=%F0%9F%93%B7 $TelegramMessage" &> /dev/null
#/sbin/shutdown -h +$ShutDownParameterMinutes
echo "SHUTDOWN"
fi
fi
fi
fi
With respect.
I try to calculate time differences between two log, but when there is no log in logfile, unix takes own birthdate 1970. My script is below. I want to exit from script if there is no log in logfile.
#!/bin/bash
a=`tail -n 1 /var/log/nginx/error.log | awk -F" " '{print $1" "$2}' | cut -c12-20`
f=`date '+%Y-%m-%d %H:%M:%S' | cut -c12-19`
VAR1=$(date -u --date="$a sec UTC" +%s)
VAR2=$(date -u --date="$f sec UTC" +%s)
DIFF2=$(( $VAR2 - $VAR1 ))
if [ $DIFF2 -lt 59 ]; then
echo "ok"
else
echo "nok"
fi
I guess that with if there is no log in logfile, you mean that the logfile either does not exist or is empty. You can do this in bash with
logfile=/var/log/nginx/error.log
[[ -f $logfile && -s $logfile ]] || exit 1
-f tests that it is a plain file, and -s tests that it is not empty.
You can check fr the existence of a file using:
if [ ! -f '/var/log/ngnix/error.log' ]
then
exit
fi
Just check if file doesn't exist or is empty and exit code
LOG_FILE="/var/log/nginx/error.log"
[ ! -s $LOG_FILE -o ! -f $LOG_FILE ] && exit $?
I have a shell Unix running every hour (crontab on CentOS 7).
Inside that shell, a loop read and proceed treatment for all new files find in a defined folder.
At the end of each files's treatment a CURL command is send with some parameters, for example :
curl https://aaaaaa.com/website -d param1=value1 -d param2=value2 ....
Each time the shell is run by crontab, the 1st CURL is correctly converted to a true URL and received by Apache/Tomcat, but all the others are bad. In fact the 2nd and the following CURLs seem not converted in the correct format like
https://aaaaaa.com/website?param1=value1¶m2=value2
but they are sent like
https://aaaaaa.com/website -d param1=value1 -d param2=value2
So the website is unable to treat the parameters properly.
Why the 1st command is correctly converted to a correct URL format and not the following ?
EDIT - EDIT
The part of shell :
#!/bin/bash
...
#======================================================
# FUNCTIONS
#======================================================
UpdateStatus () {
CMD_CURL="${URL_WEBSITE} -d client=CLIENT -d site=TEST -d produit=MEDIASFILES -d action=update"
CMD_CURL="${CMD_CURL} -d codecmd=UPDATE_MEDIA_STATUS"
CMD_CURL="${CMD_CURL} -d idmedia=$4"
CMD_CURL="${CMD_CURL} -d idbatch=$3"
CMD_CURL="${CMD_CURL} -d statusmedia=$2"
if [[ ! -z "$5" ]]; then
CMD_CURL="${CMD_CURL} -d filename=$5"
fi
echo " ${CMD_CURL}" >> $1
CURL_RESULT=`curl -k ${CMD_CURL}`
CURL_RESULT=`echo ${CURL_RESULT} | tr -d ' '`
echo " Result CURL = ${CURL_RESULT}" >> $1
if [ "${CURL_RESULT}" = "OK" ]; then
return 0
fi
return 1
}
#======================================================
# MAIN PROGRAM
#======================================================
echo "----- Batch in progress : `date '+%d/%m/%y - %H:%M:%S'` -----"
for file in $( ls ${DIR_FACTORY_BATCHFILES}/*.batch )
do
...
old_IFS=$IFS
while IFS=';' read <&3 F_STATUS F_FILEIN F_TYPE F_CODE F_ID F_IDPARENT F_TAGID3 F_PROF F_YEARMEDIA F_DATECOURS F_TIMEBEGINCOURS F_LANG || [[ -n "$F_STATUS $F_FILEIN $F_TYPE $F_CODE $F_ID $F_IDPARENT $F_TAGID3 $F_PROF $F_YEARMEDIA $F_DATECOURS $F_TIMEBEGINCOURS $F_LANG" && $F_STATUS ]];
do
...
UpdateStatus ${LOG_FILENAME} ${STATUS_ERROR} ${F_ID} ${F_IDPARENT}
...
done 3< $file
IFS=$Old_IFS
...
done
You need to provide the "-d" flags and values before the URL so:
curl -d param1=value1 -d param2=value2 https://aaaaaa.com/website
Moreover, this command is going to send the parameters/values as POST parameters, not query parameters. You can use the "-G" flag, possibly combined with "--url-encode" to send as query parameters, see:
https://unix.stackexchange.com/questions/86729/any-way-to-encode-the-url-in-curl-command
I'm looking to trigger a command on xrdp session start and end, if /var/log/xrdp.log file get update with session started in last 10 minutes, I would like to trigger a shell script.
Example: Session Login Trigger.
[root#CentOS73-RDPDemo sp]# cat trigger-login.sh
#!/bin/bash
if [ $(( $(date +%s) - $(date +%s -r /var/log/xrdp.log) )) -le 180 ]; then
tail -n 4 /var/log/xrdp.log | grep -i "socket: 11"
sh /usr/src/sp/sql-login.sh
fi
Example: Session Logout Trigger
[root#CentOS73-RDPDemo sp]# cat trigger-logout.sh
#!/bin/bash
if [ $(( $(date +%s) - $(date +%s -r /var/log/xrdp.log) )) -le 180 ]; then
tail -n 4 /var/log/xrdp.log | grep -i "socket: 12"
sh /usr/src/sp/sql-logout.sh
fi
Write a script (say main.sh) which checks if there is any update in file (var/log/xrdp.log). If there is any update in file, call your desired scripts (trigger-login.sh and trigger-logout.sh).
You can do it using stat or md5sum
Example for reference (main.sh).
#!/bin/bash
touch /tmp/checkMD5
nchksum=`md5sum a.out | awk -F " " '{print $1}'`
ochksum=`cat /tmp/checkMD5`
if [ "$nchksum" == "$ochksum" ]; then
echo "both are same"
else
sh trigger-login.sh
sh trigger-logout.sh
fi
echo $nchksum >/tmp/checkMD5
schedule a crontab job which will run the main.sh script in every 10 minutes.
I am new to bash scripts and trying to work an if statement out.
I want to do a check to see if the date stamp of a file is + or - 5 minutes from the time now. I have so far:
#!/bin/bash
MODDATE=$(stat -c '%y' test.txt)
echo moddate= $MODDATE
MODDATE=$(echo $MODDATE |head --bytes=+16)
echo now = $MODDATE
currentdate2=$(date -d "+5 minutes" '+%Y-%m-%d %H:%M')
currentdate3=$(date -d "-5 minutes" '+%Y-%m-%d %H:%M')
echo currentdate2 = $currentdate2
echo currentdate3 = $currentdate3
So this gives me the datestamp of the file (MODDATE) and the date now + or - 5 minutes.
How can i do an IF statement to say "if $MODDATE is between $currentdate2 (+5 minutes from now) and $currentdate3 (-5 minutes from now)" then echo [1] > output.txt ELSE echo [0] > output.txt .
Thank you for all of your help in advance
I recommend you to use date %s to have the date in seconds since 1/1/1970 and make date comparison much easier.
currentdate2=$(date -d "+5 minutes" '+%s')
currentdate3=$(date -d "-5 minutes" '+%s')
Hence,
if [ $moddate -ge $currentdate2 ] && [ $moddate -le $currentdate3 ]; then
....
fi
should make it.
Or even shorter:
[ $moddate -ge $currentdate2 ] && [ $moddate -le $currentdate3 ] && echo "in interval!"
How about you don't try to parse the output of stat and directly take its output in seconds since Epoch with %Y? It would then be easier to use Bash's arithmetic.
Your script would look like this (with proper quoting, modern Bash constructs and lowercase variable names):
#!/bin/bash
moddate=$(stat -c '%Y' test.txt)
echo "moddate=$moddate"
now=$(date +%s)
if ((moddate<=now+5*60)) && ((moddate>=now-5*60)); then
echo "[1]" > output.txt
else
echo "[0]" > output.txt
fi