Page 3 of 3 FirstFirst 123
Results 21 to 30 of 30

Thread: Using bash to conditionally stop an application.

  1. #21
    Join Date
    Mar 2006
    Beans
    112

    Re: Using bash to conditionally stop an application.

    I copy and pasted the script, but even after correcting the single quotes ( ' ), I still got some strange error messages (Base connection for VPN connection not active). In short, the script did not recognize, that the VPN connection was already established and tried to reconnect the whole time.

    So played around with the script and tried to simplify it. Now it is working correctly!

    CHANGES:
    - Fixed established VPN connection not being recognized.
    - Program is not not started at the beginning of the script. However, it can be started independently at any time, since the script now continually checks, if it is running or not.

    Code:
    #!/bin/bash
    #This program automatically re-establishes your VPN connection and pauses a predefined program.
    
    #Monitor the VPN connection
    date
    while true; do
    	#Define a string to test VPN connection: 0 = no connection, 1 = connected.
    	programID=$(pidof PROGRAM)
    	connected=$(nmcli -t -f VPN con status|grep -c yes)	
    	case $connected in
    	"0")
    		date
    		echo "VPN disconnected."
    		#Connection lost. Stop the VPN dependency, if running.
    		if [ "$programID" != "" ]; then
    			kill -SIGSTOP $programID
    			echo "Program stopped."
    		else
    			echo "Program not running."
    		fi
    		echo "Reconnecting VPN."
    		#Give the VPN time to recover.
    		sleep 15
    		#Retry the VPN
    		nmcli -p con up uuid CONNECTION-ID-NUMBER	
    	;;
    	"1")
                    date
    		echo "VPN connected."
    		#Connection is fine. Restart the VPN dependency, if it was running.
    		if [ "$programID" != "" ]; then
    			kill -SIGCONT $programID
    			echo "Program running."
    		else
    			echo "Program not running."
    		fi
    	;;
    	esac
    sleep 5
    done
    Note: As in the original script, please replace PROGRAM with the application name (e.g. transmission-gtk) and the CONNECTION-ID-NUMBER with the uuid of your vpn connection (e.g. 83335b7a-789a-411e-8140-135126fa4701)

  2. #22
    Join Date
    May 2012
    Beans
    17

    Re: Using bash to conditionally stop an application.

    This is an Awesome scritpt. I tried the original, but it kept trying to kill the wrong PID, not sure why, and it was doing it when the VPN was connected.

    This version works perfectly! Thanks so much!

  3. #23
    Join Date
    Jun 2013
    Beans
    1

    Re: Using bash to conditionally stop an application.

    If I understand this script correctly it waits 5 seconds after checking the vpn and then checks again. Won't the program that is supposed to be stopped from leaking my isp ip be able to leak my ip in the time between vpn failure and next vpn check? If so, using this script only, to protect against vpn failure seems reckless.

    Am I wrong?

  4. #24
    Join Date
    Dec 2009
    Location
    germany
    Beans
    1,020
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: Using bash to conditionally stop an application.

    hi folks
    there was given a nice solution but !!!!!!
    i figured out (poor experince) - singnal handling in linux is not every time the butter on the bead. sure it happens me (seldom) that the SIGCONT, wasn't afer a SIGSTOP (that means that the process is never come back - try again in your script -> hint is --> just give'm 2 or three CONT after stop - computer are hig speed idots - told my students long time ago)
    you can see this in a "ps" command with staus "T" (or check the /proc/.... for status) . seldom but it can happen - for sure !
    be careful
    ciao
    richi
    Last edited by rnerwein; June 24th, 2013 at 09:15 PM.
    "What is the robbing of a bank compared to the FOUNDING of a bank?" Berthold Brecht

  5. #25
    Join Date
    Jan 2008
    Beans
    93

    Re: Using bash to conditionally stop an application.

    tiaret,

    You bring up a great point. I've tested this script by manually stopping the VPN to see how the script would react and from what I've seen the program appears to be stopped very quickly (as in not 5 seconds later). However I'm not sure how long it actually takes because I'm not sure how to use code to test the latency between when the VPN looses its connection and when the "program being monitored by this script" is stopped.

    As such you are correct in posting this cautionary observation, but it is not clear weather or not the observation is correct.
    Does any one know how to test tiaret's observations of the code?

  6. #26
    Join Date
    Jan 2008
    Beans
    93

    Re: Using bash to conditionally stop an application.

    Quote Originally Posted by rnerwein View Post
    hi folks
    there was given a nice solution but !!!!!!
    i figured out (poor experince) - singnal handling in linux is not every time the butter on the bead. sure it happens me (seldom) that the SIGCONT, wasn't afer a SIGSTOP (that means that the process is never come back - try again in your script -> hint is --> just give'm 2 or three CONT after stop - computer are hig speed idots - told my students long time ago)
    you can see this in a "ps" command with staus "T" (or check the /proc/.... for status) . seldom but it can happen - for sure !
    be careful
    ciao
    richi
    I apologize for this, but it is difficult for me to understand your use of the English language. Where you state "seldom but it can happen - for sure !" I'm not clear on what "it" is that you are referring to.
    I think what your saying is that SIGCONT is sometimes happening before the SIGSTOP occurs.
    Is that a correct understanding of what you're conveying?

    If so, I'm not sure why that matters. If the program is already running and we tell it to continue running, why does that cause a problem?

  7. #27
    Join Date
    Jan 2008
    Beans
    93

    Re: Using bash to conditionally stop an application.

    Quote Originally Posted by sgleo87 View Post
    I copy and pasted the script, but even after correcting the single quotes ( ' ), I still got some strange error messages (Base connection for VPN connection not active). In short, the script did not recognize, that the VPN connection was already established and tried to reconnect the whole time.

    So played around with the script and tried to simplify it. Now it is working correctly!
    Very good point. I'm sorry I didn't respond sooner. I had gotten the impression that this thread was dead after I posted my last version of the script which is why I wasn't checking it any more.

    As far as single quotes go, the script uses two different types of single quotes. One is the kind you find on the upper left hand side of a standard US keyboard just above the TAB key (on the same key with the character ~ on it) and the other is to the right of the semicolon ; key (on the same key with the double quote " on it). So for example to input a program name into a variable I use the single quote that is on the same key as the double quote " key on the keyboard.
    Example:
    Code:
    progID='qbittorrent'
    This takes the command line input [qbittorrent] and passes it to the variable progID which can now be called as $progID anywhere else in the script.

    ...but for a command line output I will use the single quote on the same key as the ~ key on the keyboard such as:
    Code:
    btID=`pgrep $progID`	#Where pgrep has changed from 'pidof' because 'pidof' appears to have quit working.
    This takes the output of the command [pgrep $progID] which gives the programs job process number, and passes it into btID which can now be called as $btID any where else in the script.

    I forgot to mention this in my original post because I was under the impression that these nuances were preserved when copying and pasting the code that I had posted. I also was under the impression that a bash script written for one Linux environment would also work exactly the same in another Linux environment. For example, I wrote this script for use in the terminal running bash as its command interpreter on a computer running Ubuntu as its OS and Gnome as its desktop, and I was under the impression that someone else would be equally able to run this script in a terminal that was using bash as its command interpreter if they were running Fedora, or Mint, or Arch or whatever OS, but from the feedback I've seen on this thread I'm not so sure thats true any more...

    As far as the code you have posted is concerned, it looks as if you are only looping to see if the VPN has been lost and to stop a program if the connection is lost. The intention of the original scrip was to make it so you could use a single click to start the VPN and the program you wanted to depend on that VPN as well as to manage how the two play with each other. In you're script, do you have to manually start the program that depends on the VPN being connected?

    I appreciate you're input and contributions. Really cool!
    Last edited by landstander; November 19th, 2013 at 09:44 PM.

  8. #28
    Join Date
    Jan 2008
    Beans
    93

    Re: Using bash to conditionally stop an application.

    [UPDATE]
    Here is the latest incarnation of the script. It will now automatically determine the VPN UUID for you (provided you only have one VPN setup on you're system, see lines 12 through 15 if you have more then one VPN).
    Now the only thing you will need to change in this script is line 8, where you would replace "myprogram" with whatever program you want to be stopped when the VPN looses its connection.
    I've also added more comments (lines preceded with a # symbol are comments) in the script to try and help explain some things as best I can given my current low skill level.

    Caution: As previous poster's have pointed out, please use this script at your own discretion as I am a novice at writing scripts and do not know how to check for latencies in this script between when the VPN fails and when the program that depends on that vpn is stopped. It has been my experience that this script "appears" to stop the program instantly (via manual visual inspection) when the VPN looses its connection. However as stated I'm not sure how to test this aspect of the script using code to get an accurate measure of any latency that might be present. If any one knows how to test this please provide a comment.

    To use this script:
    1.) Copy the code below into a file and name it whatever you want with an extention ".sh", for example "vpnmon.sh"
    2.) Open a text editor and replace the word "myprogram" on line 8 with the name of the program you wish to have stopped when the VPN fails or looses its connection.
    Example: If using qbittorrent, then line 8 would look like this:
    progID='qbittorrent'
    3.) Save and close the file.
    4.) To run it from the command line, type bash "pathtofile/filename.sh" where pahttofile is the path to your file, and filename.sh is the name of the file you gave in step 1.
    Example: If you named your file vpnmon.sh and placed it in a directory called Programs which resides in your home directory then you would execute the script by the following on a command line:
    bash "~/Programs/vpnmon.sh"

    Script:
    Code:
    #!/bin/bash
    # This script monitors a VPN connection and stops a program when that connection
    # is lost, then restarts that program when the connecton is re-established.
    
    #Attmept an initial connection until connected
    #------------------------------------------------------------------------------
    # Set progID to whatever program you need stopped when VPN fails.
    progID='myprogram'
    
    # Get the UUID of the only vpn on the system.
    # Note if you have more then one VPN configured on your system, you will need to
    # comment out line 14 and uncomment line 15 replacing "your-vpn-name-here" with 
    # the name of the vpn you want to use with this script.
    uuid_str=`nmcli -t -f TYPE,UUID con list |grep vpn |sed s/vpn://g`
    # `nmcli -t -f NAME,UUID con list |grep your-vpn-name-here |sed s/your-vpn-name-here://g`
    
    function connectVPN()
    {
    			# If the connection is just started or lost, try to reconnect then break out once connected.
    			while :
    				do
    	  		connected=`nmcli -t -f VPN con status |grep yes`      #Store the current state of the VPN connection.
    				if [ "$connected" = "yes" ]; then
    #					echo "VPN connection active"
    					break
    				else
    					echo "Attempting VPN connection in 5 seconds."       	   
    					sleep 5		#Give the VPN time to recover so we don't abuse it with reconnection requests.
    					nmcli -p con up uuid $uuid_str		#Retry the VPN
    				fi
    			done
    }
    connectVPN
    sleep 5				#Give the connection time to stabelize before continueing.
    
    
    # Run the program and get its process ID number.
    #------------------------------------------------------------------------------
    # Note: Here a string can not be used to represent the program because the name
    # of the string will be stored as the job name instead of the program name. So 
    # instead a variable is used to store the name of the program (see line 8).
    $progID &
    sleep 5
    btID=`pgrep $progID`	#changed from 'pidof' because 'pidof' quit working.
    sleep 2
    
    
    date
    #Monitor the connection for discconnections and secure VPN dependancies.
    #------------------------------------------------------------------------------
    while true; do
    	vpnstring=$(nmcli -t -f VPN con status|grep -c yes)		#Define a string to test, 0 = no connection, 1 = connected.
    
    	case $vpnstring in				#Test the connection string.
    		"0")
    	    date
    			echo "VPN disconnected. Stoping VPN dependancies"
    			kill -SIGSTOP $btID		#Connection lost stop the VPN dependancy.
    			echo "VPN dependancies stopped."
    			jobs
    
    			connectVPN
    			echo "VPN dependencies restarted."		#Placed here so it wont be endlessly repeated in the outer loop.
    			date
    	;;
    		"1")
    			kill -SIGCONT $btID
    	;;
    	esac
    
    sleep 5
    done
    Notes:
    Each section of the above code is delimited by a commented out dashed line as:
    #------------------------------------------------------------------------------
    There are 3 sections in the above code:
    1.) The VPN is connected if it isn't connected already.
    2.) The program that is dependent on the VPN's connection status is started and its process ID is captured.
    3.) The VPNs connection status is monitored via a simple loop, and if it ever looses the connection, the dependent program is stopped until the connection can be re-established.
    Also note there are two different types of single quotes being used in this script as stated in an earlier post.

    In earlier comments it was reported that this code throws an environment variable error message. I'm not sure why that would happen. I have a default Ubuntu 12.04 system and this code works fine when I tested it in terminal. If you're testing this script and you get an error, can you please include how you were using the script and what command interpreter your terminal is using?

    To find out what command interpreter you are using you could try doing the following from a command line:
    ps h -p $$ -o args='' | cut -f1 -d' '

    The above command was obtained from: "How to detect command interpreter from within a shell"
    Here is a description of each part of the above command (there is probably a much faster / more simple to do this query but, I just grabbed one of the first google results which worked for me):
    ps: gives a process list
    h: do not print column headers
    -p: list only the process id (PID) of each program that is running.
    $$: replaced by the shell with current PID
    -o args: print the command line, no other information
    cut: cut the output into parts
    -f1: print only the first field
    -d' ': use a space as a field separator

    If you get "bash" as the output of the command described above then the script in this post should work.
    I'm not familiar with other command interpreters so I can't be sure as to how this script will behave when used with anything other then bash.

    Launcher Icon Creation: (very step by step instructions for Gnome3).
    If you are using Ubuntu with a Gnome3 desktop (or possibly any other OS with a Gnome3 desktop) here are the steps I used to create an icon to launch this script in a terminal with one click.
    You should only do this step if you have determined that this script will work for you. (Check "To use this script" earlier in this post to see if it will work).
    1.) I did a search for an icon for the program that depends on the VPN connection.
    2.) I opened up gimp and edited this icon to look the way I wanted it to look.
    3.) I saved the program someplace logical where I could find it if I thought to look for it again later.
    4.) I opened up Alacarte ([sudo apt-get install alacarte] if you don't have it installed already, or [ALT+F2] then "alacarte" if you already have it installed).
    5.) Select an appropriate group to place the launcher in (in my case I selected the "Internet" group (left hand panel)).
    6.) Select [New Item] button (second button down from the top, on the right hand side of the window).
    7.) In the window that opens there is an icon in the upper left. Clicking on this allows you to select an icon to associate with the program. Here I selected the icon that was saved in step 3 above.
    8.) Type: "Application in Terminal".
    9.) Name: Here I used whatever name I wanted to associate with the script. So for example if you are using a bit torrent client you could type "qbtscript" or something like this for the name here.
    10.) Command: Here we enter what we used for step 4 from "To use this script" earlier in this post.
    11.) Comment: This is optional and just serves as a short description of the icon.
    12.) Click save and close alacarte.
    13.) Open the overview screen (again this short tutorial is for Gnome3, moving the mouse to the upper left corner opens the overview screen).
    14.) Type the name you gave in step 9. You should see the icon you created and saved in steps 2 and 3 of this list of steps. Click hold, drag, and drop this icon into your list of favorites (left hand side of the screen for a default Gnome3 desktop in Ubuntu 12.04) and from this point on all you need to do is click on this icon, to start the script. A terminal window will automatically open and run the script.

    Thanks again for all you're comments and help in creating this script.
    Last edited by landstander; November 19th, 2013 at 09:20 PM. Reason: fixed a miss quoted line number in the code.

  9. #29
    Join Date
    Mar 2011
    Beans
    9

    Re: Using bash to conditionally stop an application.

    Quote Originally Posted by landstander View Post
    [Final Update:]
    As far as I can tell the script seems to be working fine now.

    There is still no way to check if it actually stops the program since "jobs" doesn't produce any output, but since the program appears to be frozen during the time period when it should be stopped I'm assuming its stopped.

    Here is the final version of the script as a reference in case any one cares to use it:
    Code:
    #!/bin/bash
    #This program stops a program when your VPN connection is lost then restarts it after the connection is re-established.
    
    #Attmept an initial connection until connected
    function connectVPN()
    {
        while :        #If the connection is just started or lost, try to reconnect then break out once connected.
        do
            connected=`nmcli -t -f VPN con status |grep yes`    #Store the current state of the VPN connection.
            if [ "$connected" = "yes" ]; then
                break
            else
                echo "Attempting VPN connection in 10 seconds."
                sleep 10    #Give the VPN time to recover so we don't abuse it with reconnection requests.
                nmcli -p con up uuid 07d345f0-3cb4-4b59-ba2b-7fdf9717e50a    #Retry the VPN
            fi
            done
    }
    connectVPN
    
    myprogram01 &    #Note: can not use a string to represent the program because the name of the string will be stored as the job name instead of the program name.
    programID=`pidof myprogram01`
    
    #Monitor the connection for discconnections and secure VPN dependancies.
    date
    while true; do
        vpnstring=$(nmcli -t -f VPN con status|grep -c yes)    #Define a string to test, 0 = no connection, 1 = connected.
        case $vpnstring in    #Test the connection string.
        "0")
            date
            echo "VPN disconnected. Stoping VPN dependancies"
            kill -SIGSTOP $programID    #Connection lost stop the VPN dependancy.
            echo "VPN dependancies stopped."
            jobs
    
            connectVPN
            echo "VPN dependencies restarted."    #Placed here so it wont be endlessly repeated in the outer loop.
            date
        ;;
        "1")
            kill -SIGCONT $programID
        ;;
        esac
    sleep 5
    done
    Note: if you use this code, just change myprogram01 to whatever program you want stopped when your VPN connection is lost, and change the UUID of the VPN connection to match whatever UUID your computer assigns to your VPN connection.

    Thanks again to CynicRus and all the others who helped me on this project. It would have taken a lot longer to complete without your help. Thank you.

    While "pidof transmission-gtk" works just fine "pidof btsync-gui" fails because in a ps aux it shows up as "python /usr/bin/btsync-gui" so how do I get it to give me the correct pid to kill the task?

  10. #30
    Join Date
    Aug 2010
    Location
    Lancs, United Kingdom
    Beans
    1,588
    Distro
    Ubuntu Mate 16.04 Xenial Xerus

    Re: Using bash to conditionally stop an application.

    Quote Originally Posted by famewolf View Post
    While "pidof transmission-gtk" works just fine "pidof btsync-gui" fails because in a ps aux it shows up as "python /usr/bin/btsync-gui" so how do I get it to give me the correct pid to kill the task?
    "pidof -x btsync-gui" should do it.

Page 3 of 3 FirstFirst 123

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •