ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have over the past weeks been putting together certain ideas, I have currently a working idea that allows me process video files automatically to html5 WebM VP8 format, my primary language are shell scripts in bash. I want to know if there is better way in simplifying the coding to extremely small sections easy to understand and such.
I'm using nohup to loop every 60 seconds into another shell script, this nohup shell script fires grep and checks if ffmpeg is running or not, this way grep acts for me as a yes or no, from here i can fire ffmpeg to process the videos automatically without me doing anything. essentially grep when is active and checking for ffmpeg looking for 1 or 0, acts as a encoding queue because ffmpeg processes one file at a time.
so i fire nohup into
Quote:
nohup sh nohup.sh >/dev/null 2>&1 &
Quote:
#!/bin/sh
while true
do
#now we call second
/var/www/bash/grep_ffmpeg.sh
sleep 60
done
and grep checks
Quote:
SERVICE='ffmpeg'
if ps ax | grep -v grep | grep $SERVICE > /dev/null
then
echo "$SERVICE service running, will not bother ffmpeg yet because of current process"
else
echo "$SERVICE is not running"
echo "$SERVICE is not running!" | /var/www/bash/start_service.sh
fi
if grep finds that ffmpeg service is not running, it starts another shell script that automatically cleans the filenames, and starts the encoding process all over again.
I have around 8 sh scripts, whats the best way of merging them into maybe 2 or a single script that does everything
this is the main shell script, used to do the processing, here I'm in need of figuring a simpler way of doing everything better
cd /var/www/cache01
for f in *; do mv -- "$f" "${f//[][(){\}]}"; done
sleep 5
cd /var/www/cache01
for infile in *.*;
do
#replace " - " with a single underscore.
NEWFILE1=`echo $infile | sed 's/\s-\s/_/g'`;
#replace spaces with underscores
NEWFILE2=`echo $NEWFILE1 | sed 's/\s/_/g'`;
#replace "-" dashes with underscores.
NEWFILE3=`echo $NEWFILE2 | sed 's/-/_/g'`;
#remove exclamation points
NEWFILE4=`echo $NEWFILE3 | sed 's/!//g'`;
#remove commas
NEWFILE5=`echo $NEWFILE4 | sed 's/,//g'`;
mv "$infile" "/var/www/cache02/$NEWFILE5";
done;
so i fire nohup into (..) and grep checks (..) if grep finds that ffmpeg service is not running, it starts another shell script that automatically cleans the filenames, and starts the encoding process all over again.
I'd drive the main script from a crontab entry. It does away with the "nohup", the nohup.sh and grep_ffmpeg.sh script if at the top of your main script you just
Code:
pgrep ffmpeg >/dev/null 2>&1 && exit 0
and a crontab entry has the additional benefit that you'll be notified of any errors by email.
Quote:
Originally Posted by kendosan
i use sleep alot, because of 128mb memory limit, if there is something better please let me know.
If you need to run other processes then you could make ffmpeg run with a nice level (or you could renice the whole main script with
Code:
renice -n +20 $$
near the top) but the fact remains AFAIK ffmpeg is a RAM and CPU hog and 128 MB is not that much. I doubt 'sleep' helps much wrt that.
I agree using functions does help with accessing repetitive tasks, you should avoid "for" loops and use "while" ones instead and you could do things like
I’m still not sure about your intended setup. You want to drop files in a folder and they should be handled automatically once the copy/download processes finished? Or you want to start the next bunch of conversions once the old run is over?
Maybe it can also be handled by a queuing system like GNUbatch: if the copy/download completed, you submit a job for this particular file. This way you can also limit the number of executions of the jobs to avoid overloading of the machine.
#replace " - " with a single underscore.
NEWFILE1=`echo $infile | sed 's/\s-\s/_/g'`;
#replace spaces with underscores
NEWFILE2=`echo $NEWFILE1 | sed 's/\s/_/g'`;
#replace "-" dashes with underscores.
NEWFILE3=`echo $NEWFILE2 | sed 's/-/_/g'`;
#remove exclamation points
NEWFILE4=`echo $NEWFILE3 | sed 's/!//g'`;
#remove commas
NEWFILE5=`echo $NEWFILE4 | sed 's/,//g'`;
For that part at least you could use simplify it to these:
Code:
#replace " - " with a single underscore.
NEWFILE=${infile// - /_}
#replace spaces and dashes with underscores
NEWFILE=${NEWFILE//[:blank:]-/_}
#remove exclamation points and commas
NEWFILE=${NEWFILE//[\!,]}
I'm currently trying out whats been said here, slowly I'm putting everything into a single short shell script. thanks everybody to telling me some new tools i never heard of such as GNUbatch
I’m still not sure about your intended setup. You want to drop files in a folder and they should be handled automatically once the copy/download processes finished? Or you want to start the next bunch of conversions once the old run is over?
Maybe it can also be handled by a queuing system like GNUbatch: if the copy/download completed, you submit a job for this particular file. This way you can also limit the number of executions of the jobs to avoid overloading of the machine.
sorry to confuse you, my setup as of right now is like dropbox, i have a folder where i drop video files such as mkv mpg wmv etc, i used to loop a shell script every 60 seconds and check if ffmpeg is running, if it was not in the service, grep would start_service.sh to process the files. i was just asking if there was cleaner way of shorting my shell scripts and making things tidy
#!/bin/bash
SERVICE_PID=0
shopt -s extglob
function service {
# Do service stuffs here.
}
function service_start {
if service_check; then
echo "Service is still running."
return 1
else
echo "Starting service."
service &
SERVICE_PID=$!
sleep 1
if service_check; then
echo "Service started."
else
echo "Service failed to start."
return 1
fi
fi
}
function service_check {
[[ $SERVICE_PID == +([[:digit:]]) && SERVICE_PID -gt 0 ]] && kill -s 0 "$SERVICE_PID"
}
function service_stop {
echo "Stopping service."
if service_check; then
kill "$SERVICE_PID"
service_check && {
echo "Failed to stop service."
return 1
}
else
echo "Service is no longer running."
return 1
fi
}
function service_restart {
if service_check; then
service_stop || return 1
fi
service_start
}
function main {
service_start
for (( ;; )); do
read -p "Your command: " CMD
case "$CMD" in
c|C|check)
service_check && echo "Service is running." || "Service is not running."
;;
r|R|restart)
service_restart
;;
q|Q|quit)
if service_check; then
service_stop && break
else
break # or exit
fi
;;
esac
# Service checking could be automated along with read -t TIMEOUT but it depends on custom.
done
}
main "$@"
Last edited by konsolebox; 10-10-2012 at 02:08 PM.
thank you very much for that example, I'm reading stuff here glob and trying to figure it all out
i understand about maybe 80% of what you scripted lol but totally confused about ([[:digit:]]) what do the ([[: and :]]) do :O
i use this to check for 1 or 0
Quote:
#!/bin/sh
ffmpeg=0 # check if pid is running
CHECKINGPERIOD=60 # check in seconds
while [ 1=1 ];
do
if [ ! "$(pidof ffmpeg)" ]
then
if [ "$ffmpeg" = "0" ]; then
echo "WARNING! ffmpeg crashed!"
ffmpeg=1
fi
/var/www/bash/start_service.sh
else
if [ "$ffmpeg" = "1" ]; then
echo "ffmpeg was successfully restarted."
ffmpeg=0
fi
fi
sleep $CHECKINGPERIOD /dev/null
done
this one is with grep
Quote:
#!/bin/sh
SERVICE='ffmpeg'
if ps ax | grep -v grep | grep $SERVICE > /dev/null
then
echo "$SERVICE service running, will not bother ffmpeg yet"
else
echo "$SERVICE is not running!" | /var/www/bash/start_service.sh
fi
Last edited by kendosan; 10-10-2012 at 02:34 PM.
Reason: bad code
sorry to confuse you, my setup as of right now is like dropbox, i have a folder where i drop video files such as mkv mpg wmv etc, i used to loop a shell script every 60 seconds and check if ffmpeg is running, if it was not in the service, grep would start_service.sh to process the files. i was just asking if there was cleaner way of shorting my shell scripts and making things tidy
Aha, thanks for clarification. My first thought would be to use inotify events, but it would need a custom C program.
There is inotifyd to start a script or alike in case of an event in a directory:
I was wondering with your initial setup, that it might start a conversion although the file isnt’t written completely. The above can also be used to submit a batch job instead of a direct processing to any queuing system to avoid overloading.
yes i have looked into this inotify, i thought it was part of ubuntu 12.04 server by default, maybe im mistaking the utilities from ubuntu, but anyway that is good to know more tools , i'm looking also into ruby, as i have heard its pretty cool but thats for another thread
i will need to read much more to understand, the batch job with inotify or incrontab, right now grep_ffmpeg.sh acts as a service check and batch job creator. i mean ffmpeg wont get to execute because grep makes sure if it runs or not. and knows what to follow .
I'm pretty scared to mess with the code after all this i have spent nearly 4 weeks putting everything very slowly i will have to backup everything first.
i understand about maybe 80% of what you scripted lol but totally confused about ([[:digit:]]) what do the ([[: and :]]) do :O
It's in the bash manual. [:digit:] is just the same as 0-9, so [[:digit:]] == [0-9]. The first part of the statement checks if the PID is valid then the second part (with kill -s 0) does the actual check if the process still exists and running.
Quote:
this one is with grep
Like I said instead of listing processes and grepping with grep for an existing process name, you could instead just use 'killall -s 0' to check if the process exists. killall returns 0 if it does exist and 1 if doesn't. If you could save the PID with $! it could it even be more efficient so that you could just use 'kill', a builtin of bash, to check it instead of a multi-process and external command checker like killall. If you still prefer listing processes anyway, it's better to just use 'pgrep' instead.
Last edited by konsolebox; 10-10-2012 at 07:49 PM.
thanks kon, I'm still reading what Reuti posted lol,
Quote:
killall -s 0
sounds much shorter way of doing the checking ! im going to try it, I've already broken something in the process such as thumbnails getting created 2 times
To expand a bit more on konsolebox' last post, [::] represents a regular expression character class, preset ranges of characters that can be used inside [] bracket expressions. bash has also adapted them for use in globbing.
Note that the exact entries represented by the character classes can vary depending on the current system locale. The regular expressions section of info grep has a very readable description of all of them.
Edit: I think most of your find commands could be replaced with simple globbing patterns too, particularly if you use extended globbing. It would help to know if the search has to be recursive, however.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.