LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Desktop (http://www.linuxquestions.org/questions/linux-desktop-74/)
-   -   Need to run a script for any user logged in every minute (http://www.linuxquestions.org/questions/linux-desktop-74/need-to-run-a-script-for-any-user-logged-in-every-minute-864165/)

unassassinable 02-21-2011 06:37 PM

Need to run a script for any user logged in every minute
 
Please read carefully, because I need something more than just a simple crontab.

I have a script, gsm-convert.sh:

Code:

#!/bin/bash
#CONVERT ALL .gsm FILES IN USERS Download FOLDER TO .mp3 AND DELETE THE .gsm
LIST=$(ls $HOME/Download/*.gsm)
for i in $LIST; do
  DEST=$(ls $i | cut -d "." -f 1).mp3
  lame -V 9 $i $DEST
  echo "done converting $i, removing.."
rm $i
done;
rm -f $FILE

Basically it converts any file with a .gsm extension into a .mp3. You'll notice that I use the $HOME variable. I am in an office with dozens of users and new users come and go every week. Each user has their own machine. I need this script to run for any user who logs in on any workstation.

WHAT I AM THINKING:
I was trying to append the following little bit to the end of the /etc/profile (OpenSuSE 11.2) file:

Code:

#IF THEY HAVE THE PLACE MARKER, DONT ADD ANOTHER CRONTAB
TEMPNAME="$HOME/.youHaveANewCrontab
if [ -f "$TEMPNAME" ]; then
  echo "";

#IF THEY DONT HAVE PLACEMARKER, ADD A NEW CRONTAB FOR THAT USER
else
  #echo this to the user who just logged in's personal crontab (I dont know how to do this) 0/1 * * * * gsm-convert.sh

  touch "$HOME/.youHaveANewCrontab
fi

I just dont know how to echo text to the logged in users personal crontab. For example, user Ron logs in. It creates a placeholder file, and then adds 0/1 * * * * gsm-convert.sh to his personal crontab. Then User Shelly logs in on her computer, and it does the same thing for her crontab...and the same for future new users. Can anyone give me a pointer in the right direction?

Rich

Kenny_Strawn 02-21-2011 06:49 PM

Here's what I am thinking:

Code:

[root@host:~]$ cp -f gsm-convert.sh /usr/bin
[root@host:~]$ cd /usr/bin
[root@host:/usr/bin]$ mv gsm-convert.sh gsm-convert
[root@host:/usr/bin]$ chmod a+x gsm-convert

This way, you move the script to a location that is already under the PATH variable, giving everyone execute permissions, and removing the .sh suffix so that other users can just type:

Code:

gsm-convert
and the command is run.

unassassinable 02-21-2011 07:17 PM

having normal users (sales guys) run a command from the command line every minute is unacceptable. I need this automated, without the user doing anything.

corp769 02-21-2011 07:28 PM

If anything, you could put the command into either /etc/profile or /etc/bashrc.

unassassinable 02-21-2011 08:28 PM

Put what command?

soplin 02-21-2011 08:43 PM

You use what Kenny Strawn said to place the command globally.

You take that command and put gsm-convert at the bottom of .bashrc locally or /etc/bashrc or /etc/bash.bashrc as mentioned by corp769. Every time someone will login the script will run.

corp769 02-21-2011 08:47 PM

To add to that though, mainly to help with echoing to the crontab thing... You can do something like the following:

Code:

touch dir/file
echo "this" >> dir/file

Use the >> to append the file. Or you could just echo "blah" > dir/file to create the file, and if it is already there, it will overwrite the file.

unassassinable 02-22-2011 02:51 PM

I dont think I explained exactly what I need very well. Linux as far I as I know does not play .gsm files through a GUI very well (yes, I could install quicktime with wine, and yes I have tried this...its not stable) and cannot be used in our environment), I know it will play it in the command promt, but that is not an option for me to suggest sales guys to open the command promt, navigate to the folder they need, and run sox or sndfile, so please dont suggest this. I've resolved to just convert the gsm's to mp3's so my users in the business can listen to past calls when they download them. This convert needs to happen throughout the day, all day because they constantly download and listen to calls. In other words...

@Sopin - That would only convert files when they login. I need it to run for every user, converting gms files in the users home directory, every minute.
@corp 769 - I know how to echo text to a file, but this is different than echoing text to a users crontab. I need to know how to echo to THEIR crontab.

So again, I just need to know how to echo text to a user's crontab. This is frustrated by the fact that it is not a good idea to edit the crontab file directly, but through using crontab -e. So it's like, I need a way for each user to run each time they log in:

IF THEY DO NOT HAVE THE FILE .youHaveDefaultCron IN HOME DIRECTORY THEN RUN:
crontab -e
insert the following: 0/1 * * * * gsm-convert.sh
save crontab and exit

IF THEY DO HAVE THE FILE .youHaveDefaultCron THEN DO NOTHING

TB0ne 02-22-2011 03:14 PM

I see where you're going, but I'd approach it from a different path. I'd not use cron for this, but rather put a script somewhere on the system, and put it in the users .profile (or .bashrc), so that it runs automatically every time they log in.

All you've got to do then is put a "sleep 60" in the script, and it'll pause for 60 seconds, then have it loop through from the beginning. Might not work for what you've got in mind, though, but for execution times less than 5 minutes, I usually go the sleep route, rather than cron.

stress_junkie 02-22-2011 03:17 PM

I can see some room for improvement in the original idea. First I would not use cron. That is for jobs that repeat on a regular schedule. You want to run ad hoc jobs. Either at or batch would be more appropriate but I wouldn't use them either.

It seems to me that you really want to create a daemon to watch for new .gsm files. This can be a bash script that is launched in the system startup or manually, just like all of the other system daemons.

One problem that I see if that if all of the .gsm files are in each user's home directory then scanning them for .gsm files will create a heavy workload on the disks. This will slow down the scan and it will slow down the overall system responsiveness. I would put new .gsm files in a common directory. Each .gsm file would be owned by the correct user account. The converted files would be created in each user's home directory. This approach would greatly reduce the amount of work required to detect the new .gsm files.

Overall design:
I would have a bash script based daemon running under root. It would scan for .gsm files in a common directory. If it detected a .gsm file it would spawn a new process under the user account of the owner of that file (using su -c convert_gsm <filename>). That process would create the .mp3 file in the home directory of the user account that it was running under and then delete the .gsm file. You could put in a wait command in the daemon process that scans for new files. That would reduce the disk i/o when there are no new .gsm files. The daemon should not start a new scan for .gsm files until all of the jobs that it has spawned on the current scan complete. This can be done by monitoring those jobs' status at the end of the scan/spawn procedure.

This approach will convert multiple .gsm files concurrently. You may want to include some code to limit the number of concurrent conversions to prevent overwhelming the computer when a lot of new files appear in a short time.

unassassinable 02-22-2011 04:41 PM

Quote:

Originally Posted by TB0ne (Post 4267687)
I'd not use cron for this, but rather put a script somewhere on the system, and put it in the users .profile (or .bashrc), so that it runs automatically every time they log in.

So instead of putting the code in the /etc/profile that I posted in my original post, you suggest adding this instead (at the bottom)

Code:

#
#CALL THE SCRIP THAT WILL CONVERT .gms FILES TO .mp3 FILES IN USER'S /home/Download DIRECTORY
#
convertfromgsm  <==(This assumes that I place a script called convertfromgsm into the /usr/local/bin directory and give it executible perms for all users)

Then the convertfromgsm file would have the convert script that I originaly posted with a loop surrounding it? Can you help me with the loop problem? What kind of loop would you suggest? It would need to run every minute while they are logged in. A while loop would work I suppose as long as the condition is never met...so something like while 1 = 2 run this code, right? This seems like a viable solution to me.

unassassinable 02-22-2011 05:12 PM

heh! ok so I tried this...putting a loop around the script and calling the script from /etc/profile....and it works, BUT....it never gets to loading the desktop because it's still in a loop. Likewise, if I try to login through a term, it sais, error no *.gsm files and aI have to hit ctrl+c to break out of that and get to a prompt. Any work arounds?

Reuti 02-22-2011 06:05 PM

As usual with Linux: there are many ways to implement it. Putting it in the system wide crontab would mean to have there an entry for each user, or (as mentioned) in each user's crontab. A background process which is started when they log in would also have to check whether the users logs in a second time.

A completely different approach: there is a small queuing system called GNUbatch which is meant as a cron replacement. When you define yourself there as an admin user, you are allowed to submit jobs for any user with:
Code:

$ gbch-r -u foobar -r Minutes:1 /opt/convert.sh
This you have to do one time for each new user in the system. And you notice the option -r to define the repeat interval. The conversion script would check whether the user is logged in right now and convert.

TB0ne 02-23-2011 08:27 AM

Quote:

Originally Posted by unassassinable (Post 4267808)
heh! ok so I tried this...putting a loop around the script and calling the script from /etc/profile....and it works, BUT....it never gets to loading the desktop because it's still in a loop. Likewise, if I try to login through a term, it sais, error no *.gsm files and aI have to hit ctrl+c to break out of that and get to a prompt. Any work arounds?

Yep..don't put the looping code itself into the users .profile, but rather put the whole thing into a separate script file, and call it from .profile, putting it into the background, like:
Code:

nohup myscript.sh >/dev/null 2>&1&
This will fire up a new process running just that script.

Reuti 02-23-2011 08:34 AM

Annotations:

a) This will start the script for each login. Will the users login twice? Then you would have two or more instances for each user.

b) Will the scripts ever be stopped again? Especially with nohup they will survive the logout AFAIK.


All times are GMT -5. The time now is 07:33 AM.