Showing posts with label program. Show all posts
Showing posts with label program. Show all posts

Friday, December 31, 2010

Command Line Init Script Generator For Linux Or Unix

Hey There,

To start this week off, we've got another updated script (now that we have over 600 some odd posts, we actually have about 400 some odd loose ends to finish up, as well ;) This script is an update of an earlier post we did to showcase a basic init script generator for Linux or Unix, again hearkening back to 2007. How time flies when you're not paying attention to what you're doing ;)

This script includes several updates (which haven't been tested to perfection - so feel free to write in with complaints ;) such as the ability to use command line arguments to specify a wider variety of options, set some to default and not even enter any (except three) if you don't want to. Actually, the only three required arguments are the name of the program you want to start with the init script you generate, the fully qualified name of the same program and the name of the init script itself. All the other options are easily displayed by just running the command without any arguments, like so:

host # ./rcscript.sh

Options -n -p and -f are required!

Usage: ./rcscript.sh [-h for this help screen]

Required switches:
[-n init script name] [-p name of program to control]
[-f controlled program's fully qualified name]

Optional switches:
[-i init directory] [-3 rc3.d directory] [-0 rc0.d directory
[-s start options for your program]
[-S stop options for your program]
[-k additional programs to kill on stop - space separated]
[-b common binary directory - defaults to /usr/bin]

Be sure to "double quote" any switch arguments with spaces!


Hope you enjoy the updates and this script helps you out in some way or fashion :)

Cheers,

Creative Commons License
rcscript.sh by Mike Golvach is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.
Based on a work at linuxshellaccount.blogspot.com.
Permissions beyond the scope of this license may be available at http://linuxshellaccount.blogspot.com.

#!/bin/sh
#
# Generic Init Script Creator
# 2009 - Mike Golvach - eggi@comcast.net
#
#Creative Commons License
rcscript.sh by Mike Golvach is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.
Based on a work at linuxshellaccount.blogspot.com.
Permissions beyond the scope of this license may be available at http://linuxshellaccount.blogspot.com.
#

trap 'rm -f ${init_dir}/${script_name} ${rc3_dir}/${script_name} ${rc0_dir}/${script_name} ${script_name}' 1 2 3 9 15

# Tips for a few command line arguments - setting an argument to zero will not be considered equivalent to not defining it
# a. set init_dir to 0 if you don't want any scripts and links setup - set rc3_dir, rc2_dir and/or init_dir to "0" to not create that link/script.
# b. If any of the init_dir, rc2_dir and/or rc3_dir variables are not set, they will default to the examples below.
# c. options that include 0 in the example do not need to be set and are entirely optional
#

# init_dir= /etc/init.d or 0
# rc3_dir= /etc/rc3.d or 0
# rc0_dir= /etc/rc0.d or 0
# script_name= myStartScript.sh
# program_name= testProgram
# fully_qualified_program_name= /usr/local/sbin/testProgram
# start_options= "start" or 0
# stop_options= "stop" or 0
# sure_kill= "space delimited list of extra programs to kill" or 0
# common_bin_directory= "place where common binaries are on your system" or defaults to /usr/bin
#

function usage()
{
echo
echo "Usage: $0 [-h for this help screen]"
echo
echo "Required switches:"
echo "[-n init script name] [-p name of program to control]"
echo "[-f controlled program's fully qualified name]"
echo
echo "Optional switches:"
echo "[-i init directory] [-3 rc3.d directory] [-0 rc0.d directory"
echo "[-s start options for your program]"
echo "[-S stop options for your program]"
echo "[-k additional programs to kill on stop - space separated]"
echo "[-b common binary directory - defaults to /usr/bin]"
echo
echo "Be sure to \"double quote\" any switch arguments with spaces!"
echo
exit 1
}

while getopts 0:3:b:f:hi:k:n:p:s:S: option
do
case $option in
'i')
if [[ "$OPT_ARG" == "0" ]]
then
init_dir=0
else
init_dir="$OPTARG"
fi
;;
'3')
if [[ "$OPT_ARG" == "0" ]]
then
rc3_dir=0
else
rc3_dir="$OPTARG"
fi
;;
'0')
if [[ "$OPT_ARG" == "0" ]]
then
rc0_dir=0
else
rc0_dir="$OPTARG"
fi
;;
'n')
script_name="$OPTARG"
;;
'p')
program_name="$OPTARG"
;;
'f')
fully_qualified_program_name="$OPTARG"
;;
's')
if [[ "$OPT_ARG" == "0" ]]
then
start_options=""
else
start_options="$OPTARG"
fi
;;
'S')
if [[ "$OPT_ARG" == "0" ]]
then
stop_options=""
else
stop_options="$OPTARG"
fi
;;
'k')
if [[ "$OPT_ARG" == "0" ]]
then
additional_kills=""
else
additional_kills="$OPTARG"
fi
;;
'b')
if [[ "$OPT_ARG" == "0" || -z "$OPT_ARG" ]]
then
common_bin_directory="/usr/bin"
else
common_bin_directory="$OPTARG"
fi
;;
'h')
usage
;;
*)
usage
;;
esac
done

if [[ -z $script_name || -z $program_name || -z $fully_qualified_program_name ]]
then
echo
echo "Options -n -p and -f are required!"
usage
fi

if [[ -z $common_bin_directory ]]
then
common_bin_directory="/usr/bin"
fi

if [[ -e $script_name ]]
then
rm $script_name
fi

cat << EOM >>$script_name

#!/bin/sh

#
# ${program_name} init script
# Usage: $script_name [start|stop|restart]
#

case \$1 in
'start')
echo
echo Starting ${program_name}....
echo
${fully_qualified_program_name} ${start_options} >/dev/null 2>&1 &
${program_name}_running=\`${common_bin_directory}/ps -ef|${common_bin_directory}/grep "${fully_qualified_program_name}"|${common_bin_directory}/grep -v grep|${common_bin_directory}/awk '{print \$2}'\`
if [ "\$${program_name}_running" == "" ]
then
echo "${program_name} start cannot be confirmed. Please check"
echo "system output and application logs for further detail"
else
echo "${program_name} started successfully"
fi
;;
'stop')
echo
echo Stopping ${program_name}....
echo
if [ "$stop_options" != " " ]
then
${fully_qualified_program_name} ${stop_options} >/dev/null 2>&1 &
fi
${program_name}_walking=\`${common_bin_directory}/ps -ef|${common_bin_directory}/grep "${fully_qualified_program_name}"|${common_bin_directory}/grep -v grep|${common_bin_directory}/awk '{print \$2}'\`
if [ "\$${program_name}_walking" == "" ]
then
echo "${program_name} does not appear to be running."
echo "Process not found. Not shut down."
else
counter=5
dead="alive"
echo "Shutting ${program_name} down."
echo "${fully_qualified_program_name} - pid ${program_name}_walking - stopping."
while [ \$counter -gt 0 ]
do
${program_name}_still_walking=\`${common_bin_directory}/ps -ef|${common_bin_directory}/grep "${fully_qualified_program_name}"|${common_bin_directory}/grep -v grep|${common_bin_directory}/awk '{print \$2}'\`
if [ "\$${program_name}_still_walking" != "" ]
then
echo "killing pid \$${program_name}_still_walking "
${common_bin_directory}/kill \$${program_name}_still_walking
counter=\`expr \$counter - 1\`
sleep 1
else
dead="dead"
echo "dead"
counter=0
fi
done
if [ \$dead = "alive" ]
then
echo "Could not kill process after 5 attempts."
echo "Process ${program_name}_walking still active."
${common_bin_directory}/ps -ef|${common_bin_directory}/grep "${fully_qualified_program_name}"|${common_bin_directory}/grep -v grep
fi
fi
EOM
if [[ $additional_kills && ! -z $additional_kills ]]
then
cat << EOM >>$script_name
for aks in `echo $additional_kills`
do
echo
echo Stopping \$aks....
echo
aks_walking=\`${common_bin_directory}/ps -ef|${common_bin_directory}/grep "\$aks"|${common_bin_directory}/grep -v grep|${common_bin_directory}/awk '{print \$2}'\`
if [ "\$aks_walking" == "" ]
then
echo "\$aks does not appear to be running."
echo "Process not found. Not shut down."
else
counter=5
dead="alive"
echo "Shutting \$aks down."
echo "\$aks - pid \$aks_walking - stopping."
while [ \$counter -gt 0 ]
do
aks_still_walking=\`${common_bin_directory}/ps -ef|${common_bin_directory}/grep "\$aks"|${common_bin_directory}/grep -v grep|${common_bin_directory}/awk '{print \$2}'\`
if [ "\$aks_still_walking" != "" ]
then
echo "killing pid \$aks_still_walking "
${common_bin_directory}/kill \$aks_still_walking
counter=\`expr \$counter - 1\`
sleep 1
else
dead="dead"
echo "dead"
counter=0
fi
done
if [ \$dead = "alive" ]
then
echo "Could not kill process after 5 attempts."
echo "Process \$aks_walking still active."
${common_bin_directory}/ps -ef|${common_bin_directory}/grep "\$aks"|${common_bin_directory}/grep -v grep
fi
fi
done
EOM
fi
cat << EOM >>$script_name
;;
'restart')
echo
echo ReStarting ${program_name}....
echo
\$0 stop
\$0 start
;;
*)
echo "Usage: \$0 [start|stop|restart]"
;;
esac
EOM

${common_bin_directory}/chmod 750 ${script_name};
${common_bin_directory}/cp ${script_name} ${init_dir}/${script_name}
${common_bin_directory}/ln -s ${init_dir}/${script_name} ${rc3_dir}/${script_name}
${common_bin_directory}/ln -s ${init_dir}/${script_name} ${rc0_dir}/${script_name}


, Mike


Banner for College Student-Oriented Sites (728 version 1)



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Tuesday, July 15, 2008

Converting Binary Numbers To Decimal The Hard Way On Linux Or Unix

Hey There,

If you recall a while back, we looked at using Perl's "unpack" function to easily convert binary values to decimal and convert decimal back to binary. Those were both (some folks may consider) relatively sophisticated methods of tackling the problem. Although, once you understand how "unpack" works, the first becomes incredibly simple to use and understand. The other one may always be a little awkward.

Today we're going to look at doing binary to decimal conversion using a less "worldly" method ;) The program we have for you today (and I refer to it as a program since it's written in C) attacks the problem more naturally. And, by naturally, I mean that it should make sense to anyone at its core (assuming they understand the C programming language). The method of execution is not the most efficient, but I think it's the most "human readable." In a future post, we'll definitely convert it to Perl, shell and Awk. And, maybe before then, we'll get to the next part in our ongoing series on Perl, shell and Awk porting. We'll get there eventually. If I didn't have so many different things to write about, I could bore you to tears with that stuff (if I haven't already ;)

Hope you enjoy the program. You can build it easily, using a compiler like gcc in this fashion:

host # gcc -o bin2dec bin2dec.c

and run it just as easily:

host # $ ./bin2dec

8 Digit Binary Number?
10010010
<-- I think there's a subtle homage to Rush in there - just forget about the ending 0 ;)

Binary 10010010 equals Decimal 146!

The only catch, which the executable program will prompt you with, is that (in order to keep it simple) it's limited to 8 digit binary numbers and expects an 8 digit binary number as input. This means that binary 1 would return 128 (10000000) instead of 1 (00000001). Both symptoms can be fixed by adding extra code to pad zeros on the left hand side, but I felt, after seeing the resulting code, that including it would take away from the basic gist of this post, which is that C, Perl, shell and Awk are totally accessible to "anyone" who wants to learn them. I wanted to put something out that looked as little like a completely foreign language as possible. It is my philosophy that anyone can learn how to code and/or use the Linux or Unix Operating System(s).

Of course, if "everyone" loses their irrational "fear of computers" and does start doing this stuff well, I'll end up being a fry-guy at McDonald's in about 10 years ;)

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

/********************************************
* bin2dec - Convert 8 digit binary numbers *
* to decimal numbers *
* *
* 2008 - Mike Golvach - eggi@comcast.net *
* *
********************************************/

/* Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

main()
{

char binnumber[8];
int length;
int difference;
int total = 0;

printf("\n8 Digit Binary Number?\n");
scanf("%s", &binnumber);
length = strlen(binnumber);
if ( length < 8 ) {
difference = -(length - 8);
}
if ( binnumber[7] == '1' ) {
total = total + 1;
}
if ( binnumber[6] == '1' ) {
total = total + 2;
}
if ( binnumber[5] == '1' ) {
total = total + 4;
}
if ( binnumber[4] == '1' ) {
total = total + 8;
}
if ( binnumber[3] == '1' ) {
total = total + 16;
}
if ( binnumber[2] == '1' ) {
total = total + 32;
}
if ( binnumber[1] == '1' ) {
total = total + 64;
}
if ( binnumber[0] == '1' ) {
total = total + 128;
}
printf("\nBinary %s equals Decimal %d!\n", binnumber, total);
return 0;
}


, Mike

Saturday, April 5, 2008

Further Dissection Of Paging And Swapping On Linux And Unix

Hey again,

Believe it or not, I actually got a few emails about our previous post on paging and swapping in Linux or Unix because it wasn't specific enough ;) While I can certainly understand the frustration, I was hoping to explain the main differences as completely and concisely as possible. I seem to have faltered a bit on each front: I glossed over two specifics which, I agree, deserve some attention and I wrote yet another novel ;)

With that in mind (and with a prayer that my fingers won't type any more than they have to ;) I'd like to address, and/or clarify, the level of depth I didn't descend to in my last post on the difference between paging and swapping and write about the difference between paging and swapping (The redundancy was intentional and any resulting confusion is expected, given the topic at hand and my writing style ;)

As I mentioned previously, the terms paging and swapping are used almost interchangeably these days. Some industry manuals will actually talk about "swapping out pages" which seems to be contradictory and, theoretically, impossible if swapping and paging are two separate concepts with distinct and unique definitions. This is where language and implied meaning become a barrier to actual definition. And, all the more reason to clarify this one last bit of the puzzle.

And here they come. The extra clarifications...

1. Difference in resident virtual memory management with paging and swapping.
When a system swaps a program, or process, it guarantees that it is resident (on disk or in memory) before it schedules it for execution, and will often hold onto the mapped resources reserved for that process from the time the process requests them until it notifies the scheduler that it is complete. When a system pages during the execution of a program, or process, there isn't any such direct correlation. You don't necessarily know (without specifically checking) how much of a process's virtual memory is resident or whether the process is entirely able to be scheduled for execution at the time paging begins. Pages can be selectively grabbed from a process (out of mapped physical memory) and never returned, unless re-requested by the process when it looks for the memory, can't find it and generates a page fault.

Phew... That's one down. Hopefully this isn't just becoming more confusing :)

2. More specific definition of paging and swapping with regard to page ins/outs and swap ins/outs.
In this instance, swapping specifically refers only to the transfer of memory pages from physical memory to dedicated swap devices or swap disk (on most systems this is now referred to as swapfs - or a unique swap filesystem) and vice versa. Paging, on the other hand, refers to the transfer of memory pages from physical memory to disk (regular disk or swap disk) and vice versa. So, really, the major difference is that swapping is limited to only transferring memory pages back and forth between the physical memory and a dedicated swap device or filesystem, while paging can transfer between physical memory and any sort of disk device.

Hopefully, we've reached a sufficient amount of explanation at this point, and this thing won't turn into the monster I'd hoped it wouldn't become ;)

Thank you, everyone who wrote in, for your helpful input. As many folks have also noted, we don't have comments set up on this blog (because of issues with "comment spam" and not wanting to get shut down). If you ever want to leave a comment, or an objection, we welcome you to email us directly at our most often-check email address or, if you have a lot to say (or want to attach video, etc), sign up (for free) on our sister Linux and Unix Menagerie Forum, and we'll get your remarks there, as well. We do our best to reply, personally, to everyone who takes the time to write us. So far, I think we're still batting a thousand in that regard ;)

Best wishes,

, Mike