-1

On Asterisk boot/reboot I want a PowerShell file to be executed.

I have created a .ps1 file on /var/spool/ which is supposed to copy new files from an asterisk directory and transfer them to an Azure storage container. This file is supposed to get each last recording file and transfer it to the Azure's container. When I run the command manually on root, it works. This is an output of a recording file successfully uploaded on Azure's container.

Name                 BlobType  Length          ContentType                    L
                                                                              a
                                                                              s
                                                                              t
                                                                              M
                                                                              o
                                                                              d
                                                                              i
                                                                              f
                                                                              i
                                                                              e
                                                                              d
----                 --------  ------          -----------                    -
out-067…9249.0.wav BlockBlob 44              application/octet-stream       2
uploaded!

To get every new recordings it has to be run endlessly ( check for new files every one minute). To do this I have used a cycle do/while($true), with a commandsleep 60 inside it. In case of any system reboot or power outage I want this file (ps1) to start running again after OS boot.

To do this I tried adding the command pwsh /var/spool/transferrecordings.ps1 on /etc/rc.local to make it work in case of a system reboot. I edited this directory with vi /etc/rc.local as below:

This is the script I'm using in the directory /etc/rc.local .


# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.

pwsh /var/spool/transferrecordings.ps1
exit 0

But nothing seems to happen on server boot.

I tried editing crontab with crontab -e by adding command: @reboot pwsh /var/spool/transferrecordings.ps1. Nothing again.

I'm using Sangoma Linux (CentOS 3.10.0).

Any suggestions please?

10
  • Please provide further information. What is the .ps1 supposed to do? What is your OS and version? I am also confused about that whole line sudo chmod systemctl enable rc-local ... What do you think that command is supposed to do? – C. M. Apr 26 at 14:19
  • @C.M. .ps1 is supposed to copy new files from an asterisk directory and transfer them to an Azure storage container. I'm using Sangoma Linux (CentOS 3.10.0). That command is supposed to look if there’re is any problem with root, so the command on /etc/rc.local can be executed on the root as default; and to not be executed on the default user. – admiri Apr 27 at 7:01
  • I will need to use more then one comment for all this.. So read them all first. First, Edit your question to reflect any changes needed. (Usually, when a comment asks you for more information, you should edit the question to include the information, such as copy/pasting he relevant parts of the .ps1 file.) But that may not be needed after all.. read the next comments(s).. – C. M. Apr 27 at 8:54
  • Regarding that last command, the first part, sudo basically means "run as root" (I.E., the System account, if you're used to Windows accounts, which is even more powerful than the Administrator account). the second part is the command to run, chmod, which changes file level permissions of the filenames listed. So the final parts, systemctl enable and rc-local are not being treated as commands--they're being treated as three filenames for chmod to operate on. Which does not match what you say you think it does. – C. M. Apr 27 at 8:55
  • So back to your original problem... As you describe what the .ps1 file does, you need to keep one (or more) directories/files synchronized between Asterisk and your Azure storage, correct? Have you looked in to the command rsync for this? It has many options to do exactly that in many different ways. And the las part, you wan to make sure i is run continuously. How do you define continuously? Each microsecond? Each millisecond? Each second? Or is once a minute good enough? – C. M. Apr 27 at 8:59
1

(I am writing this in a way that other users who come across this answer can hopefully use it, not just the OP.)

There are multiple methods available for this kind of problem, as well as issues and trade-offs for each. Typically, you do no want a process running constantly that is using up all your CPU/RAM, or you won't be able to use the system!

You can write the code as a daemon, which will loop "forever", but in between iterations of the loop it will go idle/inactive/sleep so that other processes/programs get serviced as well. There are many things to be aware of in daemon mode, such as concurrency, race conditions, deadlocks, handling restarts if it exits unexpectedly, and even ensuring that you are not running the same daemon multiple times unless you do so intentionally and understand how to do it safely. I will not detail this further here--search the web for "writing daemons".

Another method is using various system monitoring tools that are triggered by system events such as new file creation, modification, access, and so on. This method also has some issues that can bring he system down if you do not understand how to use it safely. Likewise, I will not detail his method further here. Search for something "file system event notification" if this kind of method is the one you think would suit you best.

Yet another method (and there are still more ways) is to use the cron daemon common to most (all?) un*x systems, to run a command or more likely a shell script periodically, such as once per minute. This method also has pitfalls, but they are usually easier to take steps to avoid. The biggest issue to adjust for is typically that your shell script (or powershell, or perl/pythen/other command/script) should be designed to process only once each time it is executed, not in an infinite loop. Let cron deal with executing it again and again repeatedly (cron itself is carefully designed to run as a daemon and handles all the details and many of he issues of of being a daemon, so you do not have to.) Once it is done processing, have it exit as soon as possible so the system and you can go back to doing other things, such as playing your favorite game. ;-)

Usually, the biggest issues you will need to be aware of with "cron jobs" are:

1: Set the intervals far enough apart to avoid overlap, and avoid repeatedly looping (especially infinite loops!) within the command/script. Otherwise, cron will start a new process even while the previous one is still looping. Before long, you will have hundreds or thousands of the same script running, looping, and colliding with each other, using up CPU, RAM, etc.

2: Related to the previous, you want your script to do--and finish--what it needs to do as quickly as possible, before cron triggers the scrip to run again, as sated above. IF there is a chance two iterations will overlap (which may happen when copying a large file over the network, for example), you will need to plan for potential concurrency problems, deadlocks, etc. (Many scripts handle this by keeping track of the latest PID (process id) in a *.pid file, to detect if the previous iteration is still in progress and abort the "new" execution if the previous is still executing.)

3: Also related in this case, you will need to ensure that if multiple processes of the script do get triggered, only one of them does the copy operation. Othherise, they will clash with both trying to copy they exact same file/data. (This is why the *.pid method is used to abort when it detects that a previous execution has not yet completed. I leave the details of how to do all that as an exercise for the reader... to practice their searching and researching skills...)

4: The last issue you will probably need to account for is user access rights and permissions. The cron tool runs in different modes--one is the system mode where the 'crontab' configuration needs to be told which user account to execute the command/script as and thus has that user account's permissions; And the other mode is per-user, where cron already knows which user account to execute the command/script as because it is already implied. (Note that cron does not execute the users ~/.bashrc or anything so you will need to include that in command/script if it is needed.)

There are other issues to be aware of in certain cases, so be certain to learn about them and how to deal with them when they occur. There is already a lot of information on cron on the web, so I will not repeat it all here. Go search the web for it.

As a final note to he OP, I strongly suggest you learn to use the rsync command if you can. It has a lot of options to control how/what it copies, detect if a file already exists, detect if one is older/newer than the other, and many more features you may find useful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.