Code request: sh script commands & syntax

Post new topic   Reply to topic    DD-WRT Forum Index -> Broadcom SoC based Hardware
Goto page 1, 2  Next
Author Message
mayday175
DD-WRT Novice


Joined: 11 Jan 2007
Posts: 23

PostPosted: Fri Aug 01, 2008 2:09    Post subject: Code request: sh script commands & syntax Reply with quote
I need some help with my scripting syntax. How could I structure the following "if" command to test the existence of interface ppp1?

if <interface ppp1 exists>
then
exit 0
else
do these commands
fi


Obviously, my question here refers to only one small part of my script, the rest I have cut and paste from other sources so should work fine.

In this scenario, ppp1 is the pptp_client's interface to a Win2003 VPN server. This script will be executed regularly by cron to test if this interface is up, if its not then restart vpn (cos I've found it tends to drop out when idle overnight).

Thanks for your help


Last edited by mayday175 on Tue Aug 05, 2008 0:08; edited 1 time in total
Sponsor
mayday175
DD-WRT Novice


Joined: 11 Jan 2007
Posts: 23

PostPosted: Mon Aug 04, 2008 1:59    Post subject: Reply with quote
No replies so far... I didn't think this question was that hard. I think I should be able to pipe the output from an ifconfig command into grep(?), but don't know how to keep the syntax neat and tidy in a one line statement. My knowledge of grep (or whatever I may need to use) is limited and so is my knowledge of options for the "if" command. Ideas anyone?
mayday175
DD-WRT Novice


Joined: 11 Jan 2007
Posts: 23

PostPosted: Tue Aug 05, 2008 1:15    Post subject: Found my own solution Reply with quote
Ok, I've figured out my own solution. I don't know if this is the most efficient code, but it does what I'm looking for. I havn't finished testing yet, but my script goes something like this:

Code:
#!/bin/sh
if [ "`ifconfig | grep -c ppp1`" = "0" ];
then
echo ppp1 is down
  if [ -f "/var/run/vpn.pid" ];
  then
    echo vpn.pid exists, waiting 30 for ppp1
    sleep 30
    if [ "`ifconfig | grep -c ppp1`" = "0" ];
    then
      echo ppp1 still down, restarting VPN
      /bin/sh /tmp/pptpd_client/vpn stop
      /bin/sh /tmp/pptpd_client/vpn go &
    fi
  else
   echo vpn.pid not exist, VPN has not started yet
  fi
else
  echo ppp1 up ok
fi

I'm still looking for better solutions/improvements to this script. Please post suggestions if you can tidy this up.
mayday175
DD-WRT Novice


Joined: 11 Jan 2007
Posts: 23

PostPosted: Tue Aug 05, 2008 1:52    Post subject: Arithmetic with variables Reply with quote
Another syntax question: how do I do arithmetic with variables. I have a script that accepts some command line options and I am trying to do the following:

VAR=`expr $2 * $3 * 1000`

From info I've gathered from other websites on shell scripting, I think this should work... but it doesn't (the variable VAR remains null). Is there something different about the BusyBox shell in DD-WRT? Can anyone offer advice here?

Thanks
mayday175
DD-WRT Novice


Joined: 11 Jan 2007
Posts: 23

PostPosted: Tue Aug 05, 2008 7:01    Post subject: Reply with quote
Ok, I finally figured this one out too... the answer is:

VAR=$(($2 * 500 * 1000))

And I've found that operations in groups of brackets (ie. to make different + - * / work in the desired order) works like a charm too.

So how about this question... How can I 'echo' a comment such that it will appear in the syslog?
DrRossi
DD-WRT Novice


Joined: 14 Nov 2006
Posts: 31
Location: Rotterdam, The Netherlands

PostPosted: Tue Aug 05, 2008 10:31    Post subject: Reply with quote
mayday175 wrote:

So how about this question... How can I 'echo' a comment such that it will appear in the syslog?


You can use 'logger' to write comments in the syslog.

logger "this is a comment"

For the manual page see 'man logger', but as you probable do not have access to a generic unix/linux machine you can look here:
http://linux.die.net/man/1/logger

BTW, your shell script doesn't look bad.
cdkiller
DD-WRT User


Joined: 26 Jun 2007
Posts: 262
Location: Trinidad & Tobago

PostPosted: Wed Aug 06, 2008 9:32    Post subject: Reply with quote
Hi, I admire your skills in figuring out your own problem. I hope you can help me out, I have a script problem. I want to make a startup script to check the status of the wan connection and wait till it has an IP then I want it to run inadyn with my parameters. I barely know scripts I know cron even less so I don't know what is the best method to run this.

This is the algorithm for what I want done.

while ppp0 = 0
sleep
done
if ppp0 = 1
inadyn
fi

And here is the code I thought up.

Code:
#!/bin/sh
while [ "`ifconfig | grep -c ppp0`" = "0" ]; do
sleep 5
done   
inadyn --username ??? --password ??? --alias ??? --dyndns_server_name updates.dnsomatic.com --dyndns_server_url /nic/update? --update_period_sec 120 --forced_update_period 86400 --background
#sleep 10
#killall -9 inadyn
# note "sleep 10" is required if "killall inadyn" is used.



Will this code work as it is? Ideally I would like this code to run each time a WAN IP is established but I don't know how to do that. If I put this in CRON to run every half hour then lets say the WAN IP is up (so ppp0=1), then it would try to run INADYN again. Is that possible to try to run a process that is already in memory then eventually it will use up all the memory? I have to use INADYN this way because the GUI is retarded and updates all my networks in dnsomatic whereas this way only updates the ones with the alias I set.

Is there any way to detect the event of when a WAN IP is established or renewed?

Help please, Thanks.

Update 1:
Ok I managed to fix the code on my own and it works. It works even if you change your wan ip without rebooting the router. This means starting and stopping INADYN is not absolutely necessary but if there is a way I would prefer to kill it after it runs and schedule it in CRON instead. Now I have a new problem. How can I kill INADYN after it runs? How do I figure out the PID to kill it from within the script?

Update 2:
I commented the line "#killall inadyn" and added "& sleep 5" at the end of the command which is supposed to kill inadyn after it updates dnsomatic with your ip address on the specified alias. Uncomment it if you wish to schedule this script to run in CRON else it will fill up the memory with INADYN instances. Please if anybody can optimize this code feel free, this is the first time I have tried to write a script and thus I am no expert. I did not have 100% success with using the custom.sh so I advise entering the entire inadyn command string, (somehow it does not work with custom.sh when you power cycle the router). Fix it till it works for you, I am no expert.

_________________
[everything is to be replicate]


Last edited by cdkiller on Sat Aug 09, 2008 14:07; edited 1 time in total
mayday175
DD-WRT Novice


Joined: 11 Jan 2007
Posts: 23

PostPosted: Thu Aug 07, 2008 0:16    Post subject: Reply with quote
DrRossi wrote:

You can use 'logger' to write comments in the syslog.

logger "this is a comment"


Thanks DrRossi. That hit the spot perfectly Smile
mayday175
DD-WRT Novice


Joined: 11 Jan 2007
Posts: 23

PostPosted: Thu Aug 07, 2008 0:48    Post subject: Reply with quote
cdkiller wrote:
Is there any way to detect the event of when a WAN IP is established or renewed?


cdKiller, you might be able to use something like the script in this wiki article to detect the up status of the interface...

or, I used the info from this wiki article to create a script that runs each and every time interface ppp0 goes up. Note: under General Information of this article, the list of locations this script can be placed should not include /tmp/etc/config as this location does not work. I read a forum post somewhere here showing the source code when this location was missing (sorry, I don't know who that was and can't seem to find it again). Anyway, I used /mmc/etc/config/ (after mounting /mmc/) to put my ppp0.wanup script into, and put it there using a startup script on the Administration-Commands page. You could always use jffs if you like.

Code:
mount ramfs /mmc -t ramfs
mkdir /mmc/etc
mkdir /mmc/etc/config

echo "#!/bin/sh
command 1
command 2
command 3
" > /mmc/etc/config/ppp0.wanup
chmod 700 /mmc/etc/config/ppp0.wanup

Using this technique, you could 'killall inadyn' then run 'inadyn etc' again without needing a 'while' loop or 'if' checks. I don't know what 'inadyn' is or how you need to use it, so I cannot offer any advice on how to make it work. But I do know this event triggered script trick works great... knowing those commands will happen each and every time interface ppp0 is activated.

Enjoy
Mayday175
mayday175
DD-WRT Novice


Joined: 11 Jan 2007
Posts: 23

PostPosted: Thu Aug 07, 2008 1:00    Post subject: Re: Found my own solution Reply with quote
mayday175 wrote:
I'm still looking for better solutions/improvements to this script.

I now have a better and improved script, with some syslog-ing built in.
Code:
#!/bin/sh
PPP_INT=ppp1
sh /tmp/cisco-LED.sh off
if [ "`ifconfig | grep -c $PPP_INT`" = "0" ]; then
 logger Interface $PPP_INT is down, checking VPN
 if [ -f "/var/run/vpn.pid" ]; then
  logger VPN should be running, waiting 30 seconds for $PPP_INT
  sh /tmp/cisco-LED.sh white 30 500 &
  sleep 30
  if [ "`ifconfig | grep -c $PPP_INT`" = "0" ]; then
   logger Interface $PPP_INT is still down, restarting VPN
   sh /tmp/cisco-LED.sh amber 20 100 &
   sh /tmp/pptpd_client/vpn stop
   sh /tmp/pptpd_client/vpn go &
  fi
 else
  logger VPN is not running, waiting 30 seconds for VPN
  sh /tmp/cisco-LED.sh amber 30 500 &
  sleep 30
  if [ ! -f "/var/run/vpn.pid" ]; then
   logger VPN is still not running, restarting VPN
   sh /tmp/cisco-LED.sh amber 20 100 &
   sh /tmp/pptpd_client/vpn stop
   sh /tmp/pptpd_client/vpn go &
  fi
 fi
else
 sh /tmp/cisco-LED.sh white
fi

This script is cron'd to run once a minute. Since this WRT is acting as a VPN router to extend a corporate WAN to a remote site, its important for this unit's VPN link to be self healing. Although I haven't had any problems lately, I have had some issues with the VPN interface going down (and staying down) but the VPN server still showing the router as connected.

The cisco-LED.sh script is another one I wrote (based on info from this wiki article) to help the remote site users' eye-ball the router's status when reporting problems to our IT department.

Mayday175
cdkiller
DD-WRT User


Joined: 26 Jun 2007
Posts: 262
Location: Trinidad & Tobago

PostPosted: Thu Aug 07, 2008 1:58    Post subject: Reply with quote
Thanks mayday175, I cannot use mmc or jffs here though, I am relying on the startup script and custom script for now. I am not prepared to do the SD card mod. I am going to take a look at your upgraded code and see what I could learn from it, I am not very learned in the ways of the script language as I tried for many hours last night to figure out how to make a function and call it but I could not do it. I realized too that it was more sensible to leave inadyn in memory instead of killing it and calling back with cron so it would faster detect WAN IP changes and update the dnsomatic server. I have actually removed the if checks from my code and testing it using a while loop only but I don't know how to know how many iterations it actually performs so I am going to look for code to light up an LED so I can count. All this trouble could be avoided if only the built in DDNS gui was working properly.
_________________
[everything is to be replicate]
mayday175
DD-WRT Novice


Joined: 11 Jan 2007
Posts: 23

PostPosted: Thu Aug 07, 2008 2:25    Post subject: Reply with quote
cdkiller wrote:
I am not prepared to do the SD card mod.
You don't need to. I didn't. Just run the mount command as provided and it will mount /mmc/ to system RAM. I got this snipit of code from here. This was the post I mentioned earlier... thanks go to p1mrx.

cdkiller wrote:
I am going to look for code to light up an LED so I can count.
The command "gpio disable #" will turn LEDs on and "gpip enable #" will turn them off (strange, I thought enable/disable would work the other way around!). #=2=white Cicso LED, #=3=amber Cisco LED. See that Useful_Scripts wiki article for more details. For this kinda debugging, I'd probably use "echo message >> log.file" or use "logger message" (thanks to DrRossi) to add events to the syslog file (/tmp/var/log/messages). Good luck...

Mayday175
cdkiller
DD-WRT User


Joined: 26 Jun 2007
Posts: 262
Location: Trinidad & Tobago

PostPosted: Thu Aug 07, 2008 5:32    Post subject: Reply with quote
Ok this is what I have accomplished. Do not try to run this code, it is missing parts, this is just for documentation.
Code:
#!/bin/sh
while [ "`ifconfig | grep -c ppp0`" = "0" ]; do
gpio disable 1 & sleep 1
gpio enable 1
done
inadyn

That code above is my .rc_startup script, from a router reboot it works ok and it blinks the LED 3 times so I could assume a minimum wait time of 3 seconds. I think I am on to the problem why it fails sometimes but I am still confused. For some reason if I change certain settings and click apply the router reboots but when it comes back up it does not use ppp0 but instead when I checked I found ppp1=1 and ppp0=0. Very strange because even if ppp0=0 then my script would just blink the LED forever but it does not happen, I can't tell if it even runs the startup script. For example if I enable SysLog, the router reboots and I am stuck in the situation above. I cat the messages log file but it has so many things I don't even know how to check if the startup script was executed or not. I could probably change the while condition to check for ppp0=0 && ppp1=0 but it would do no good if the startup script never runs. I guess I could work around this limitation and just power cycle the router after major changes via httpd. What are your thoughts?


If you don't mind could you explain a few things about the syntax of the code you gave me below please. I am really new to script programming.
Code:
mount ramfs /mmc -t ramfs
mkdir /mmc/etc
mkdir /mmc/etc/config

echo "#!/bin/sh
command 1
command 2
command 3
" > /mmc/etc/config/ppp0.wanup
chmod 700 /mmc/etc/config/ppp0.wanup

The first 3 lines I fully understand, you mount the ram to /mmc and type was ramfs then you made 2 folders. Moving along what is the purpose of the echo and the lines between ""? I thought echo only printed stuff on the screen or does it print and execute in this case?

Next I know that scripts are supposed to start with #!/bin/sh but is that really necessary and what does it signify? the hash in front implies it's a comment and not executed not so?

I understand the command 1 etc, I would assume 1 command per line as you have indicated.

Most importantly the last 2 lines confuses me the most. All I know is chmod is used for permissions but what is its use here?

_________________
[everything is to be replicate]


Last edited by cdkiller on Sat Aug 09, 2008 14:34; edited 1 time in total
mayday175
DD-WRT Novice


Joined: 11 Jan 2007
Posts: 23

PostPosted: Thu Aug 07, 2008 7:30    Post subject: Reply with quote
I am not a coding expert either, but I'll answer as best I know.

I believe the #!/bin/sh is a comment to signify this is a shell script and, although technically not needed, it is good manners/practice to include it (confirmation please from a more experienced scripter?).

The 'echo' command does normally send output to the screen, but when redirected ( > ) it can be sent somewhere else. 'echo xyz > file.name' will redirect to a file, creating it or overwriting everything that is already in it while 'echo xyz >> file.name' will redirect to a file, creating it or appending to it's existing content. In my example, you could 'echo command 1 >> file', 'echo command 2 >> file', etc, appending each line one at a time, or simply put the whole multi-line echo between double quotes ( " ). If necessary, you can use single quotes ( ' ),if a command needs to quoted, without prematurely ending the double quotes.

So this example redirects my echo'd commands into the file ppp0.wanup and then changes that file's permissions to make it executable. I think you can use the command 'chmod +x file.name' to achieve the same affect. If you don't make the script file executable, it will not run. Of course, once that file exists and is chmod'd, you can always test it manually by running 'sh file.name'

And since I've got these commands in the router's start-up script, this ppp0.wanup file will exist before the interface ppp0 does, and when ppp0 goes up, it runs all .wanup files (and a few others I think) located in those 3 special folders mentioned in that wiki article.

Good luck. I'm going offline for a few days... so won't be able to help again for a while.

Mayday175
cdkiller
DD-WRT User


Joined: 26 Jun 2007
Posts: 262
Location: Trinidad & Tobago

PostPosted: Thu Aug 07, 2008 7:48    Post subject: INADYN scripts for multiple DDNS Reply with quote
Thanks a million for that explanation, you have thought me many things there. I think I will practice a bit and get this working.

Update 1:
I think I have it working now. I have tested it and I found no flaws yet, I hope that means it will work for everyone. These are the startup scripts to use if you want to update specific networks (aliases) in dnsomatic server. In these example I have two --alias entries but you can use any number you need. I had to revise the code several times to get it working properly but still you should check to make sure it works on your router else you may have to adjust the sleep and killall parameters.


.rc_startup Buffalo (uses AOSS and Bridge LEDs)
-----------------------------------------------

Code:
#!/bin/sh
mount ramfs /mmc -t ramfs
mkdir /mmc/etc
mkdir /mmc/etc/config
echo "#!/bin/sh
gpio disable 6
inadyn --background --username ??? --password ??? --alias ??? --alias ??? --dyndns_server_name updates.dnsomatic.com --dyndns_server_url /nic/update? --wildcard
sleep 2
gpio enable 6
gpio disable 1
sleep 2
killall -9 -w inadyn
gpio enable 1
" > /mmc/etc/config/ppp0.wanup
chmod 700 /mmc/etc/config/ppp0.wanup


I realized that a reboot results in the ppp0.wanup script running at most 5 times within a very short period and some are multiple instances so they overlap, I don't know what triggers it but I know that it used to update the dnsomatic 3 times at each change of ip, (maybe the first 2 runs didn't have a real wan ip to report, I am not sure). I managed to fix the 3 updates by adding the -w switch to the killall statement. I realized that if it runs 3 times then inadyn will run in 3 different instances so luckily the -w switch would leave killall in memory and kill all instances of inadyn even if it reappears. The second killall line is commented because it is not always necessary unless you use multiple --alias then you could use the second killall. It really needs to be tested and tweaked on each router because it depends on timing and all cpu are not the same. I could live with this, even though it may run the ppp0.wanup script 5 times now inadyn only gets a chance to work 1 time so it does not spam the server with 3 updates.

Look at my log below from the server, see the first 2 runs below updates the server 3 times but after I put in the -w switch to killall, you can see the top 2 entries only updated 1 time which is good. Adding the -w switch to killall fixed the multiple updates but it failed to kill the process, I fixed that by adding the -9 switch which is the same as -s KILL to send the KILL signal instead of the default TERM. For some reason -s KILL did not work but the numeric equivalent -9 works.
Quote:
OpenDNS details:
History

190.59.85.104, Aug 7, 2008 10:32 pm, OK
190.59.64.15, Aug 7, 2008 10:26 pm, OK
190.59.95.210, Aug 7, 2008 10:19 pm, OK
190.59.95.210, Aug 7, 2008 10:19 pm, OK
190.59.95.210, Aug 7, 2008 10:19 pm, OK
190.59.92.195, Aug 7, 2008 7:39 pm, OK
190.59.92.195, Aug 7, 2008 7:39 pm, OK
190.59.92.195, Aug 7, 2008 7:39 pm, OK


Update 2:
Here is working code for Linksys routers.

.rc_startup Linksys (using Security LEDs)
-----------------------------------------

Code:

#!/bin/sh
mount ramfs /mmc -t ramfs
mkdir /mmc/etc
mkdir /mmc/etc/config
echo "#!/bin/sh
gpio disable 3
inadyn --background --username ??? --password ??? --alias ??? --alias ??? --dyndns_server_name updates.dnsomatic.com --dyndns_server_url /nic/update? --wildcard
sleep 2
gpio enable 3
gpio disable 5
sleep 2
killall -9 -w inadyn
gpio enable 5
" > /mmc/etc/config/ppp0.wanup
chmod 700 /mmc/etc/config/ppp0.wanup



Here is Generic code for any router.

.rc_startup Generic
---------------------
Code:

#!/bin/sh
mount ramfs /mmc -t ramfs
mkdir /mmc/etc
mkdir /mmc/etc/config
echo "#!/bin/sh
inadyn --background --username ??? --password ??? --alias ??? --alias ??? --dyndns_server_name updates.dnsomatic.com --dyndns_server_url /nic/update? --wildcard
sleep 3
killall -9 -w inadyn
" > /mmc/etc/config/ppp0.wanup
chmod 700 /mmc/etc/config/ppp0.wanup



Update 3:
Here is code that can be used if you wish to use "force_update_period" etc. (Taken from initial posts above).

.rc_startup Generic non wanup
(inadyn always running in memory)
----------------------------------
Code:
#!/bin/sh
while [ "`ifconfig | grep -c ppp0`" = "0" ]; do
sleep 5
done   
inadyn --background --username ??? --password ??? --alias ??? --dyndns_server_name updates.dnsomatic.com --dyndns_server_url /nic/update? --update_period_sec 120 --forced_update_period 86400 --wildcard



Only add the --wildcard option if you actually use it.
If anything else comes to mind I will update these scripts, as for now they work.
All code in ths post is working, use the one you prefer.
Last Edited: Wed 13th August 2008.
cdkiller

_________________
[everything is to be replicate]


Last edited by cdkiller on Wed Aug 13, 2008 9:34; edited 3 times in total
Goto page 1, 2  Next Display posts from previous:    Page 1 of 2
Post new topic   Reply to topic    DD-WRT Forum Index -> Broadcom SoC based Hardware All times are GMT

Navigation

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum