Automatically update all WordPress plugins from Bash

Automatically update all WordPress plugins from Bash

I’ve updated the script radically. WordPress had changed their site structure so that the older script would fail. With the latest updates, it should still work.

Latest version:
Writeup
Download

I was searching for an idea on how to automatically update all my WordPress plugins from Linux command line. Google introduced me to a script by Ventz Petkov. It worked very well with minor modifications. This script could automatically download all plugins from WordPress.org according to the subdirectories in the WordPress plugin directory.

However a minor drawback of the script is that it would overwrite all plugins without checking whether our plugins are already up to date. I thought this was a waste of resources, since the obvious use of such a script is to get it to run as a cron job at regular intervals. There is no need to keep downloading the same versions of plugins that you already have, countless number of times. Even Petkov has conceded as much, stating that such an addition would be quite useful.

So there you are, my first perl script. I would like to record due credits to Petkov for his method of parsing the wordpress.org website, and his framework. All that I’ve done is to add code for comparing the plugin versions that are in your plugins directory, with those on the website to see if there are available updates. If there are, only then are the files downloaded.

The latest version of the script can always be downloaded from here (New link).

The script can take command line argument. Argument #1 is the path to plugin directory. Argument #2 is the plugin to update (meaning you can manually update one plugin at a time), and is a remnant of the original script. For my purpose, I wont be using Argument #2, since I intend the script to be run automatically, updating as when updates are found.

Screenshots:

Script command line options:

--help or -h: Display this help message
--source=/path/to/plugindirectory or -s/path/to/plugindirectory
	Multiple folders can be specified at a time.
	Eg: ./updater.pl --source=/var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins,/var/www/virtual/joel.co.in/drjoel.in/htdocs/wp-content/plugins
--version or -v: Display script version information
--plugin=PluginName or -pPluginName: Specify one or more plugins to process instead of all plugins under source directory. To specify more than one plugin,
you can either repeat this option, like:
	Eg: ./updater.pl --plugin=nextgen-gallery --plugin=genesis-beta-tester
	  Or,
you can alternately specify a comma seperated list of plugins, like:
	Eg: ./updater.pl --plugin=nextgen-gallery,genesis-beta-tester
--wp-path= or -wp: Specify wordpress root directory instead of plugin directory
	Eg: ./updater.pl --wp-path=/var/www/virtual/joel.co.in/droidzone.in/htdocs,/var/www/virtual/joel.co.in/vettathu.com/htdocs

Examples:

/root/wordpress_plugin_updater/updater.pl -w/var/www/virtual/joel.co.in/droidzone.in/htdocs

/root/wordpress_plugin_updater/beta.pl -s/var/www/virtual/joel.co.in/droidzone.in/htdocs/wp-content/plugins

If running from cron:

/usr/bin/perl /path/to/updater.pl -s/var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins

An example crontab entry would be:

* */6 * * * /usr/bin/perl /root/bash-advanced-scripts/updater.pl -s/var/www/virtual/joel.co.in/drjoel.in/htdocs/wp-content/plugins >> /root/wordpress_update.log

Here the script is being run sixth hourly every day, and a log appended. You can have multiple entries for multiple blogs.

The following line will automatically flush log files, keeping last 6 days of backups:

0 0 */3 * * mv /root/wordpress_update.log /root/wordpress_update.log.old

You can see the list of updated plugins by:

[[email protected]] ~/temp #cat /root/wordpress_update.log | grep -in 'updating' --color
83:Processing plugin: easy-contact-forms | Local version 1.4 | Remote version 1.4.2 | Updating now..
158:Processing plugin: wordpress-importer | Local version 0.6 | Remote version 0.6.1 | Updating now..
68527:Processing plugin: fancier-author-box | Local version 1.0.5 | Remote version 1.0.6.1 | Updating now..
68910:Processing plugin: fancier-author-box | Local version 1.0.5 | Remote version 1.0.6.1 | Updating now..
90869:Processing plugin: simple-backup | Local version 2.7.1 | Remote version 2.7.2 | Updating now..
91357:Processing plugin: look-see-security-scanner | Local version 13.01 | Remote version 13.04 | Updating now..
91740:Processing plugin: look-see-security-scanner | Local version 13.01 | Remote version 13.04 | Updating now..
113638:Processing plugin: bulletproof-security | Local version .48 | Remote version .48.1 | Updating now..
113686:Processing plugin: bulletproof-security | Local version .48 | Remote version .48.1 | Updating now..
113718:Processing plugin: bulletproof-security | Local version .48 | Remote version .48.1 | Updating now..

 

The current version as of 31/03/13 is included below:

#!/usr/bin/perl -w
# Original Author: Ventz Petkov
# Last updated by Original Author on
# Date: 06-15-2011
# Last: 12-20-2012
# Version: 2.0
#
# Rewritten by: Droidzone
# Date 31-03-2013 www.droidzone.in
# Version 3.0.0.2
# Usage:
# ./update-wp-plugins.pl
#   or
# ./update-wp-plugins.pl registered-name-of-plugin
# (and this works to update an exiting plugin or download+install a new one)

$progversion="3.0.0.2";
$debugmode=0;
use Term::ANSIColor;
print color 'bold blue';
print "Wordpress Plugin Updater script v$progversion.\n";
print color 'reset';
&argparser(@$ARGV);

if(!defined($ARGV[0])) {
    dprint ("No arguments supplied for folder path");
	$path="/var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins";
	dprint ("Path was specified on the command line\n");
}
else {
	#my @values = split(',', $ARGV[0]);	
	#foreach my $val (@values) 
	$path=$ARGV[0];
	print "Working on directory: $path\n";	    
    if ( -d $path )
    {
		dprint ("Path verified\n");
    }
    else
    {
		dprint ("The path does not exist\n");
	exit;
    }
}

dprint ("The path was set as ".$path."\n");
print "Plugin directory:$path\n";
chdir($path);

use WWW::Mechanize;
#use File::Find;
my $mech = WWW::Mechanize->new();
$mech->agent_alias( 'Mac Safari' );
my $wp_base_url = "http://wordpress.org/extend/plugins";

################################################
# Add New plugins Here:
# Format:
#   'registered-name-of-plugin',
#
my (@plugins, @plugins_notfound, @filepath, @pluginversion);

use File::Find::Rule;
use File::Spec;

my @folders = File::Find::Rule->directory->maxdepth(1)
    ->in( $path )
    ;

foreach my $i (@folders){
    ( $volume, $directories, $file ) = File::Spec->splitpath( $i );
	undef $volume, $directories;
    if ( $file ne "plugins" )
    {
        push @plugins, $file;
		push @filepath, $i;
		#print "Path: ".$i."\t Name: ".$file."\n";
    }
}

for (my $i = 0; $i < @plugins ; $i++ ) 
{
    dprint ("Processing ".$plugins[$i]."...");
    #print "Filename:".$filepath[$i]."/".$plugins[$i].".php"."\n";
    $filename=$filepath[$i]."/".$plugins[$i].".php";
	$varfound=0;
    if ( -f $filename ) 
    {
		dprint ("Meta File found at default location.\n");				
		open("txt", $filename);
		while($line = <txt>) 
		{			
			if ( $line =~ /^\s*\**\s*\bVersion:(.*)/i )
			{
				$pluginversion[$i]=$1;
				dprint ("Version found in file ".$filename);						
				$varfound=1;										
				dprint ($pluginversion[$i]."\n");
				dprint ("Array Num ".$i." Stored plugin name:".$plugins[$i]." Version found and stored ".$pluginversion[$i]);
			}
		}
		close("txt");			
    }
    else
    {
		$searchpath=$path."/".$plugins[$i];
		@files = <$searchpath/*.php>;
		dprint ("Search path is ".$searchpath."\n");
OUT: 	foreach $file (@files) 
		{
			dprint ("Checking alternate php file: ".$file."\n");
			open("txt", $file);
			while($line = <txt>) 
			{
				#  $line =~ /^[\s\*]*Version:(.*)/i
				# Discussion on regex: http://stackoverflow.com/questions/15728671/perl-regex-logic-error
				if ( $line =~ /^\s*\**\s*\bVersion:(.*)/i )
				{
					$pluginversion[$i]=$1;
					dprint ("Version found in file ".$file);						
					$varfound=1;										
					dprint ($pluginversion[$i]."\n");
					dprint ("Array Num ".$i." Stored plugin name:".$plugins[$i]." Version found and stored ".$pluginversion[$i]);
					last OUT;
				}
			}
			close("txt");	
		}
    }
	push @plugins_notfound, $plugins[$i];
}

if ( ! $varfound) 
{
	print "\nCould not parse version no from the follwing plugins:\n";
	for (my $i = 0; $i < @plugins_notfound ; $i++ ) 
	{
		print $i." ".$plugins_notfound[$i]."\n";
	}
}
else 
{
	dprint ("We found all version numbers");
}
print color 'red';
#print colored("Summary of scanning plugin directory", 'red'), "\n";
print "Summary of scanning plugin directory\n";
print "------------------------------------\n";
printf("%-4s %-45s %3s\n", "No", "Name", "Version");
print color 'reset';
#print "No:\tName\tVersion\n";
for (my $i = 0; $i < @plugins ; $i++ ) 
{
	$v = $pluginversion[$i];
	$v =~ s/[^a-zA-Z0-9\.]*//g;	
	printf("%-4s %-45s %3s\n", $i, $plugins[$i], $v );
	#print "$i\t$plugins[$i]\t$pluginversion[$i]\n";
}
print "\n";

################################################
$pluginsdone=0;

if(defined($ARGV[1])) {
    my $name = $ARGV[1];
    &update_plugin($name);
}
else {
	$i=-1;
    for my $name (@plugins) {
		$i++;
        &update_plugin($name,$i);
    }
}

print "Plugin updation completed successfully.\n";

if ( $pluginsdone > 1 )
{
	print "$pluginsdone plugin(s) were updated.\n";
}
else
{
	print "Plugins were already up-to-date. Nothing done.\n";
}

sub update_plugin {

    my $name = $_[0];
	my $index = $_[1];
    my $url = "$wp_base_url/$name";
    $mech->get( $url );
    my $page = $mech->content;
	$url="";
    my ($version,$description,$file) = "";
    if($page =~ /.*<p class="button"><a itemprop='downloadUrl' href='(.*)'>Download Version (.*)<\/a><\/p>.*/) 
	{
		$url = $1;
		$version = $2;
		if($page =~ /.*<p itemprop="description" class="shortdesc">\n(\s+)?(.*  
	)(\s+)(\t+)?<\/p>.*/) 
		{
			$description = $2;
		}
		if($url =~ /http:\/\/downloads\.wordpress\.org\/plugin\/(.*)/) 
		{
			$file = $1;
		}
    }	
	$oldversion = $pluginversion[$index];
	$version =~ s/[^a-zA-Z0-9\.]*//g;	
	$oldversion =~ s/[^a-zA-Z0-9\.]*//g;

    print "Processing plugin: ";
	print colored($name, 'green');	
	print " | Local version ";
	print colored($oldversion, 'green');		
	print " | Remote version ";

	if ( $version eq $oldversion )
	{
		print colored($version, 'green');	
		print " | ";
		print colored("Already update\n", 'green');
	}
	else
	{
		print colored($version, 'red');	
		print " | ";
		$pluginsdone++;
		print colored("Updating now..\n\n", 'blue');
		#print "Updating plugin $name now";
		`/bin/rm -f $file`; print "Downloading: \t$url\n";
		`/usr/bin/wget -q $url`; print "Unzipping: \t$file\n";
		`/usr/bin/unzip -o $file`; 
		print colored("Installed: \t$name\n\n", 'green');		
		`/bin/rm -f $file`;
	}
}

sub read_extract
{
	my $pl_version="";
    open("txt", my $file=$_[0]);
    while($line = <txt>)
    {
		for ($line)
		{
		 s/^\s+//;
		 s/\s+$//;
		}			
        if ( $line =~ /^Version:|^version:|^\* Version:/ )
        {
            $pl_version=&extract_version($line);
        }
    }
    close("txt");
	$pl_version;
}

sub extract_version
{
    my $line=$_[0];
    $string=substr($line,rindex($line, ":")+1);
    for ($string)
    {
     s/^\s+//;
     s/\s+$//;
    }
    $string;
}

sub dprint
{
	$debugtext=$_[0];
	if ($debugmode) 
	{
		print $debugtext."\n";
	}
}	

sub print_help 
{
	print "\nCommand syntax:";
	print "\n";
	print "wpupdater [path/to/plugin dir] [plugin name]\n";
	print "\nBoth arguments are optional\n\n";
}

sub argparser
{
	foreach (@ARGV) {
		$argu=$_;
		#print "Argument:$argu";
		if ($argu eq "--help")
		{
			&print_help;
			exit;
		}
	}

}

You can add these as a cron job.


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

sed delete the nth line

Say you want to delete the nth line in a file

You do:

sed -i ‘4d’

which deletes the 4th line

I wanted to find the version of tar, and use it in a script.

#tar --version
tar (GNU tar) 1.23
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by John Gilmore and Jay Fenlason.

The first script I wrote was this:

 #tar --version | sed '2,$d' | awk '{print $4}'
1.23

Then, I modified it slightly:

tar --version | sed '2,$d' | awk '{print $NF}'

That was overkill. I could just have done:

#tar --version | head -1 | awk '{print $NF}'
1.23

 


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Add bash autocompletion for your own script

Let your script be named utstart, and accepts any of the following arguments: start, stop, install, uninstall.

As an example, you would perhaps run your script like this from bash:

./utstart start

You would like to autocomplete start, by pressing TAB key like this:

./utstart s[TAB]

This is easy.

Prerequisite:

Install bash-completion package.

apt-get install bash-completion

Now create a new script like this:

#!/bin/bash
_utstart()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="start stop install uninstall"

    if [[ ${cur} == * && ${COMP_CWORD} -eq 1 ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _utstart -o filenames utstart

Note that we have added the options “start stop install uninstall” in the script. Note also the last line contains the name of the function in our auto completion script, and also the name of our main bash script, which accepts autocompletion entries.

Once done, copy this file to /etc/bash_completion.d/utstart-auto.

Now you may change permissions on it to make it executable.

chmod +x /etc/bash_completion.d/utstart-auto

Source it with:

. /etc/bash_completion.d/utstart-auto

Now try the following:

./utstart s[TAB}

 

You will now be presented with start and stop as options.


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

How to start utorrent server at boot on Debian and OpenSuse

This post explains how to start a command/program at boot time, on Linux, especially Debian. This specifically deals with the example of how to start utorrent server -utserver at boot time.

Note: These scripts have been updated and refined. For a simple one-liner install on any Debian/Ubuntu VPS, check this page

Update: The script has been tested and works fine, and works even with OpenSuse 12.2. However note that the installation of utorrent itself requires a few configurations, described below.

Btw, you should never run utorrent as root. The example shows utorrent installed at /root/utorrent, but you’d probably want to change the location.
First, write a script to start and stop the utserver program at will. Mine is as follows, and I’ve named it as ‘utstart’

#!/bin/bash
### BEGIN INIT INFO
# Provides:          utserver
# Required-Start:    
# Required-Stop:     
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Interactive:     true
# Short-Description: Start/stop utserver
### END INIT INFO

case "" in
  start)
        echo Starting utorrent server
        cd /root/utorrent
        ./utserver &
        ;;
  stop)
        echo Stopping utorrent server
        killall utserver
        ;;
    *)
        echo Usage: start  stop
        exit 1
        ;;
    esac
exit 0

The initial comment-like text are what are known as LSB tags (something added in Debian 6). If these arent added, you get the following error when you start the server:

insserv: warning: script 'utstart' missing LSB tags and overrides[/code]
Note the points about linux runlevels:

0 – Shut down (or halt) the system 1 – Single-user mode; usually aliased as s or S 6 – Reboot the system The script needs to stop during the above runlevels. 2 – Multiuser mode without networking 3 – Multiuser mode with networking 5 – Multiuser mode with networking and the X Window System And of course it needs to start during the runlevels mentioned above.

Once you’ve written a script, copy it to /etc/init.d directory, and make it executable.

cp utstart /etc/init.d/utstart
chmod 755 /etc/init.d/utstart

Now,

To add it to the boot sequence:

On Debian6 or newer:

insserv utstart -dv[/code]
-d option means to setup the startup system so that utstart is started up with Defaults as defined in itself.

-v option stands for Verbose.

On older than Debian6:

update-rc.d utstart defaults

If stead of starting it up automatically at boot, you would rather like to start it up manually, you do:

/etc/init.d/utstart start

When you want to stop it,

/etc/init.d/utstart stop

You can remove it from the boot sequence with:

On Debian6 or newer:

insserv utstart -rv[/code]

On older than Debian6:

update-rc.d -f utstart remove

 Here, -r stands for remove; and -v for verbose.

Though maybe not as elegant, the easiest way to start a script is probably to include it in /etc/rc.local:

cat  /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

cd /root/utorrent
./utserver &
exit 0

Always remember to check whether your script is free of syntax errors. :smirk :wink

I have made a couple of modifications to make this script install and uninstall itself, without any need for manual copying or running innserv:

#!/bin/bash
### BEGIN INIT INFO
# Provides:          utserver
# Required-Start:
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Interactive:     true
# Short-Description: Start/stop utserver
### END INIT INFO
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
me=`basename `

case "" in
  start)
        echo Starting utorrent server
        cd /root/utorrent
        ./utserver &
        ;;
  stop)
        echo Stopping utorrent server
        killall utserver
        ;;
  install)
        echo Install

        echo Scriptname: $me
        echo Path: $DIR
        echo Installing utorrent server as a boot-time program..
        cp $DIR/$me /etc/init.d/
        insserv $me -dv
        echo utorrent server installed to boot-time..
        exit 0
        ;;
  uninstall)
        echo Uninstall
        echo Uninstalling utorrent server from boot init..
        insserv $me -rv
        echo Not deleting /etc/init.d/$me. You may delete it yourself. Leaving it there wont do any harm.
        echo utorrent server removed from boot init.
        ;;
  *)
        echo Usage: start  stop
        exit 1
        ;;
  esac
exit 0

I have now modifed it further, to add bash autocompletion (you need autocomplete package installed):

#!/bin/bash
### BEGIN INIT INFO
# Provides:          utserver
# Required-Start:
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Interactive:     true
# Short-Description: Start/stop utserver
### END INIT INFO

function install_autocomplete () {
echo '#!/bin/bash
_utstart()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="start stop install uninstall"

    if [[ ${cur} == * && ${COMP_CWORD} -eq 1 ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _utstart -o filenames utstart' > /etc/bash_completion.d/utstart
source /etc/bash_completion.d/utstart
chmod +x /etc/bash_completion.d/utstart
echo "Autocomplete entries for utstart added to bash. You may need to reboot or manually source the entry like this for this session:
      . /etc/bash_completion.d/utstart
"
}

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
me=`basename `
UTORRENT_LOCATION="/root/utorrent"
case "" in
  start)
        echo Starting utorrent server
        cd $UTORRENT_LOCATION
        ./utserver &
        ;;
  stop)
        echo Stopping utorrent server
        killall utserver
        ;;
  install)
        echo Install

        echo Scriptname: $me
        echo Path: $DIR
        echo Installing utorrent server as a boot-time program..
        cp $DIR/$me /etc/init.d/
        insserv $me -dv
        echo utorrent server installed to boot-time..
        install_autocomplete
        exit 0
        ;;
  uninstall)
        echo Uninstall
        echo Uninstalling utorrent server from boot init..
        insserv $me -rv
        echo Not deleting /etc/init.d/$me. You may delete it yourself. Leaving it there wont do any harm.
        echo utorrent server removed from boot init.
        ;;
  *)
        echo Usage: start  stop  install  uninstall
        exit 1
        ;;
  esac
exit 0

Additional Notes for installing utorrent server on OpenSuse 12.2 64 bit:

The following error message is shown on starting utorrent binary in OpenSuse 12.2:

 #./utserver
./utserver: error while loading shared libraries: libssl.so.0.9.8: cannot open shared object file: No such file or directory

Start yast, and search for packages in:

Search (P)hrase: libssl.so

[x]Provides (Alt-S)

And installed the following packages that turned up in search:

libopenssl0_9_8
libopenssl0_9_8-32bit

If it does not work, install all of these. Now, utorrent will start, but still give a message:

#./utserver
./utserver: /usr/lib/libcrypto.so.0.9.8: no version information available (required by ./utserver)
./utserver: /usr/lib/libssl.so.0.9.8: no version information available (required by ./utserver)
server started - using locale C

 

Update:
The same error “./utserver: error while loading shared libraries: libssl.so.0.9.8: cannot open shared object file: No such file or directory” recently appeared on a Debian dedicated server. Trying to install libssl apt packages from the wheezy repo didn’t help.

Solution: Download and manually install the .deb package from http://packages.debian.org/squeeze/libssl0.9.8

For a 64 bit Debian: http://packages.debian.org/squeeze/amd64/libssl0.9.8/download

wget http://ftp.us.debian.org/debian/pool/main/o/openssl/libssl0.9.8_0.9.8o-4squeeze14_amd64.deb
dpkg -i libssl0.9.8_0.9.8o-4squeeze14_amd64.deb

For 32 bit Debian:

wget http://droidzone.in/debian/libssl0.9.8_0.9.8o-4squeeze14_i386.deb
wget http://droidzone.in/debian/libssl0.9.8-dbg_0.9.8o-4squeeze14_i386.deb
dpkg -i *deb

Now try starting utorrent again. It works.


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Recursively Download a directory via ftp

I will be using lftp instead of regular ftp. Since I would like to automate the process using cron, I will be using a script file for the list of commands.

First create the script file:

#cat ../dforcescript.lftp
open -u username,password ftp.droid-force.com
mirror backups ./

Here, I have specified that once logged in, the directory backups is to be mirrored to a directory backups in the current directory. The trailing / indicates that the directory name is to be recreated here.

Now execute lftp with:

#lftp -f ../dforcescript.lftp
---- Connecting to ftp.droid-force.com (93.182.179.9) port 21
<--- 220 ProFTPD 1.3.3a Server (freja.c0urier.net) [::ffff:10.1.0.10]
<--- 230 User [email protected] logged in
<--- 250 CWD command successful

 


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Reorder grub2 menu

You’d have noticed that Windows (and any other custom OSes other than Linux) always gets to be the last option in the grub menu. If you were to change the order in /boot/grub/grub.cfg, the next time you reinstall grub or run update-grub, or upgrade your OS, the order gets messed up.

The solution is to rename the os-prober script which is responsible for inserting entries for Windows.

What I do is:

mv /etc/grub.d/30_os-prober /etc/grub.d/09_os-prober

The default OS is chosen from the file /etc/default/grub

Once you make your changes, update grub:

update-grub

 


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Php send mail example

The following script sends mail.

<?php
// The message
$message = "Line 1\r\nLine 2\r\nLine 3";

// In case any of our lines are larger than 70 characters, we should use wordwrap()
$message = wordwrap($message, 70, "\r\n");

// Send
mail([email protected]', 'My Subject', $message);
print('Executed mail function');
?>

 


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.
Using USB Mass storage mode on Galaxy Note 2

Using USB Mass storage mode on Galaxy Note 2

Update: This is the easiest way to enable Mass storage mode on the Note 2. You don’t need to install any third party apps. It also works on Jellybean 4.1.2 and later, as this re-enables the officially withdrawn USB Storage mode support by reversing the process by which Google had disabled it.

So, maybe you’ve noticed that your sweet beast of a phone no longer supports USB Mass storage mode (you know how you used to be able to access the whole sdcard on your PC while your phone was connected via cable). It’s a change that Google has mandated for newer Android versions. On Windows, you now have the MTP mode where you get partial access to both internal and external sd cards, however it’s a far limited option than Mass storage mode. On Linux, the situation is awful. You dont have access to anything.

Fret not! It’s easy to switch back to USB Mass storage mode. It’s as easy as tapping on a widget on your home screen. You just need to prepare your phone first.

You need to be rooted. You can either run the script as a widget shortcut, or can run the script by typing its name in a Terminal emulator on the phone.

Create the following script on your PC and name it mtpstorage:

#!/system/bin/bash
echo "" > /sys/devices/platform/s3c-usbgadget/gadget/lun0/file
vold
setprop persist.sys.usb.config mtp,adb

Create another file and name it usbstorage:

#!/system/bin/bash
setprop persist.sys.usb.config mass_storage,adb
echo /dev/block/vold/179:17 > /sys/devices/platform/s3c-usbgadget/gadget/lun0/file

When the second script  (usbstorage) runs, it allows mounting your sdcard on your PC as a mass storage device. The first script reverses the change, and makes MTP mode active again.

Download the scripts:

Download “usbstorage” usbstorage – Downloaded 319 times – 150 B


Download “mtpstorage” mtpstorage – Downloaded 195 times – 126 B

And run:

adb push usbstorage /sdcard/
adb push mtpstorage /sdcard/
su
mount -o rw,remount /system
cp /sdcard/usbstorage /system/xbin/
cp /sdcard/mtpstorage /system/xbin/
chmod 755 /system/xbin/usbstorage /system/xbin/mtpstorage

To get the ease of using a widget, install SManager from the Market.

Now, transfer the two scripts to a location on your phone. I used /system/scripts.

Now in SManager, choose the two files, one at a time. Click on the Skull and Bones icon to select Root mode (su mode). Now, choose to “Save”.

Screenshot_2013-02-17-21-23-56

Once done, you can now view the two scripts under the Menu>Scripts window.

Screenshot_2013-02-17-21-24-06

You’re all set. You can now drop widgets onto the Home screen to do this easily. For this, just long press your Homescreen, Swipe to select widgets and Choose SM Widget:

1Screenshot_2013-02-17-21-37-38

 

Drag to your homescreen.
1Screenshot_2013-02-17-21-29-25

Now, when you need USB Storage mode, simply tap on the “USB Storage” icon, and your sdcard will immediately show up in Windows Explorer or the Linux device notifier. When you’re done, tap the “MTP mode” shortcut.

 

Credits for technique:

d4fseeker‘s post on XDA

 


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Bash script for splitting a filename, extension and path from fullpath

Call the function split_filenames with the first argument as the full filename with path. Alternately, set the variable fullfile to this value.

#!/bin/bash

split_filenames() {
# echo "Called with Arg: $1"
if [ ! "$1" = "" ]
then
fullfile=$1

fi
# echo I got this filename for processing $fullfile
filename=$(basename "$fullfile")
fname=$(basename "$fullfile")
nameonly=${filename%.*}
ext=${fname##*.}

echo "filename $filename"

filename=${fullfile%.*}
pathonly=${fullfile%/*}

if [ "$pathonly" = "$fullfile" ]
then
pathonly="$pat"
fi

echo "Path $pathonly"
echo "Name $nameonly"

chkper=$(echo $fullfile | grep -c "\.")
# echo "Number of periods:$chkper"

if [ ! "$chkper" = "0" ]
then
echo "Extension $ext"
else
echo "No extension"
fi

#out_file=$pathonly/$nameonly"_signed."$ext

}

for i in ~/Dropbox/SSH\ Keys/*
do
echo
echo Path and Name: $i
split_filenames "$i"
#cp "$i" testssh/
done[/code]
In the example, the main event calls the function from a loop which cycles through all the files in the specified directory.


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Send mail from a bash script

Modify and use the following script:

#!/bin/bash
# script to send simple email 
# email subject
SUBJECT="SET-EMAIL-SUBJECT"
# Email To ?
EMAIL="[email protected]"
# Email text/message
EMAILMESSAGE="/tmp/emailmessage.txt"
echo "This is an email message test"> $EMAILMESSAGE
echo "This is email text" >>$EMAILMESSAGE
# send an email using /bin/mail
/bin/mail -s "$SUBJECT" "$EMAIL" < $EMAILMESSAGE

 


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.