There are rare situations where you will have to use the value of a variable as another variable name, bash provides a special construct for this purpose.
Create a variable and assign a value
safeer@penguin-power:~/temp$ MY_VAR1="MY_VALUE1"
Assign the variable name "MY_VAR1" to MY_VAR2.
safeer@penguin-power:~/temp$ MY_VAR2="MY_VAR1"
Now use MY_VAR2 to print the contents of MY_VAR1
safeer@penguin-power:~/temp$ echo ${!MY_VAR2}
MY_VALUE1
Let us try with an example where command line arguments ( $1,$2,$3 etc.... ) of a script are parsed using the argument numbers (1,2,3...) taken from another variable.
safeer@penguin-power:~/temp$ cat test.sh
#!/bin/bash
for((i=1;i<=$#;i++))
do
echo ${!i};
done
safeer@penguin-power:~/temp$ ./test.sh first second third fourth
first
second
third
fourth
safeer@penguin-power:~/temp$ ./test.sh first
first
Thursday, June 25, 2009
Monday, June 15, 2009
Working with files in perl
Opening a file for Read/Write/Append
You can open a file using the function open(). It takes three arguments: a file handle which is just a symbolic name of your choice for the file, a mode symbol which specifies the file operation mode in which the file should be opened, and third being the file to be opened itself.
Mode operators are as given below.
< : Read - Default if a mode is not specified at all.
> : Write -File is Created if not existing else Overwrites.
>> : Append - creates file if not existing.
If you want to combine read and write, prepend a "+" to the modes.
+< : Read/Write,Don't create file,Overwrites existing.
+> : Read/Write,Create file if not existing, else Overwrite.
+>> : Read/Append,Create file if not existing, no Overwrite
Let us take an example.
open ( MY_FILE_HANDLE,"<","/home/safeer/docs/accounts.txt");
This will open the file "/home/safeer/docs/accounts.txt" for reading and will be accessible through the file handle MY_FILE_HANDLE. We can use this handle to read data from the actual file.
The second and third arguments for open() can be combined into a single string as "< /home/safeer/docs/accounts.txt". In the case of mode, it is OK even if you skip the "<" symbol - since read is the default mode. So,
open ( MY_FILE_HANDLE,"<","/home/safeer/docs/accounts.txt");
open ( MY_FILE_HANDLE,"< /home/safeer/docs/accounts.txt");
open ( MY_FILE_HANDLE,"/home/safeer/docs/accounts.txt");
are all the same.
If you want to open this file for writing, use
open ( MY_FILE_HANDLE,">","/home/safeer/docs/accounts.txt"); OR
open ( MY_FILE_HANDLE,"> /home/safeer/docs/accounts.txt");
Reading data from a file
Open the file in read mode
open ( MY_FILE_HANDLE,"< /home/safeer/docs/accounts.txt");
You can assign the the entire file content to an array variable where each element of the array will correspond to a single line in the file.
@acounts_data = <MY_FILE_HANDLE>;
But this can be memory intensive if the file you are opening is very large. A better way is to read file line by line and process it as follows.
while ( $line = <MY_FILE_HANDLE> ){
#Process $line here
}
In every iteration $line will contain a single line of the file. Note that the last character of the $line will be newline (\n), so you may want to chomp $line before processing it. The following code will be equivalent to printing the file contents.
while ( $line = <MY_FILE_HANDLE> ){
chomp ($line);
print"$line\n";
}
Write/Append to a file:
We use print command to write/append (depends on the mode in which the file is opened) to a file.
Syntax: print $FILEHANDLE $STRING;
To start writing, first open file in write mode and then print using the file handle obtained from open().
open ( MY_FILE_HANDLE,"> /home/safeer/docs/newaccounts.txt");
$my_account = "safeer:/home/safeer/:usr/bin/bash" ;
print MY_FILE_HANDLE "$my_account\n";
Alternatively, write directly without using variable:
print MY_FILE_HANDLE "safeer:/home/safeer/:usr/bin/bash\n" ;
If the file was opened in append mode ( ">>" ) the string would have been appended to the end of file.
open ( MY_FILE_HANDLE,">> /home/safeer/docs/accounts.txt");
print MY_FILE_HANDLE "safeer:/home/safeer/:usr/bin/bash\n" ;
Closing the file
any file that is opened should be closed once the purpose of open is over.
close (MY_FILE_HANDLE);
You can open a file using the function open(). It takes three arguments: a file handle which is just a symbolic name of your choice for the file, a mode symbol which specifies the file operation mode in which the file should be opened, and third being the file to be opened itself.
Mode operators are as given below.
< : Read - Default if a mode is not specified at all.
> : Write -File is Created if not existing else Overwrites.
>> : Append - creates file if not existing.
If you want to combine read and write, prepend a "+" to the modes.
+< : Read/Write,Don't create file,Overwrites existing.
+> : Read/Write,Create file if not existing, else Overwrite.
+>> : Read/Append,Create file if not existing, no Overwrite
Let us take an example.
open ( MY_FILE_HANDLE,"<","/home/safeer/docs/accounts.txt");
This will open the file "/home/safeer/docs/accounts.txt" for reading and will be accessible through the file handle MY_FILE_HANDLE. We can use this handle to read data from the actual file.
The second and third arguments for open() can be combined into a single string as "< /home/safeer/docs/accounts.txt". In the case of mode, it is OK even if you skip the "<" symbol - since read is the default mode. So,
open ( MY_FILE_HANDLE,"<","/home/safeer/docs/accounts.txt");
open ( MY_FILE_HANDLE,"< /home/safeer/docs/accounts.txt");
open ( MY_FILE_HANDLE,"/home/safeer/docs/accounts.txt");
are all the same.
If you want to open this file for writing, use
open ( MY_FILE_HANDLE,">","/home/safeer/docs/accounts.txt"); OR
open ( MY_FILE_HANDLE,"> /home/safeer/docs/accounts.txt");
Reading data from a file
Open the file in read mode
open ( MY_FILE_HANDLE,"< /home/safeer/docs/accounts.txt");
You can assign the the entire file content to an array variable where each element of the array will correspond to a single line in the file.
@acounts_data = <MY_FILE_HANDLE>
But this can be memory intensive if the file you are opening is very large. A better way is to read file line by line and process it as follows.
while ( $line = <MY_FILE_HANDLE>
#Process $line here
}
In every iteration $line will contain a single line of the file. Note that the last character of the $line will be newline (\n), so you may want to chomp $line before processing it. The following code will be equivalent to printing the file contents.
while ( $line = <MY_FILE_HANDLE>
chomp ($line);
print"$line\n";
}
Write/Append to a file:
We use print command to write/append (depends on the mode in which the file is opened) to a file.
Syntax: print
To start writing, first open file in write mode and then print using the file handle obtained from open().
open ( MY_FILE_HANDLE,"> /home/safeer/docs/newaccounts.txt");
$my_account = "safeer:/home/safeer/:usr/bin/bash" ;
print MY_FILE_HANDLE "$my_account\n";
Alternatively, write directly without using variable:
print MY_FILE_HANDLE "safeer:/home/safeer/:usr/bin/bash\n" ;
If the file was opened in append mode ( ">>" ) the string would have been appended to the end of file.
open ( MY_FILE_HANDLE,">> /home/safeer/docs/accounts.txt");
print MY_FILE_HANDLE "safeer:/home/safeer/:usr/bin/bash\n" ;
Closing the file
any file that is opened should be closed once the purpose of open is over.
close (MY_FILE_HANDLE);
Labels:
Perl
Monday, June 1, 2009
Extracting .CAB files in Linux
First of all, what is .cab files?
From Wikipedia:
CAB is the Microsoft Windows native compressed archive format. It supports compression and digital signing, and is used in a variety of Microsoft installation engines: Setup API, Device Installer, AdvPack (for the installation of ActiveX components from Internet Explorer) and Windows Installer.
It was originally called Diamond. Its .CAB file extension and overall file format name comes from word cabinet, internally used by Microsoft tools dealing with CAB files to reference such files.
I got a couple of resume templates from Microsoft Web Site, but the downloaded copies where in .cab format. So googled to find a way to extract them and learned that there is something called "cabextract".
On my Ubuntu box:
safeer@penguinpower:~/Desktop/PPTS$ sudo apt-cache search cabextract
cabextract - a program to extract Microsoft Cabinet files
liborange-dev - development libraries for liborange
liborange0 - library to extract CAB files from self-extracting installers
orange - extracts CAB files from self-extracting installers
safeer@penguinpower:~/Desktop/PPTS$ sudo apt-get install cabextract
RPM based distros can get the package from Dag Wieers' Repositories (if they don't have a native package).
And then, extracted the cab files without errors.
safeer@penguinpower:~/Desktop/PPTS$ cabextract 06199720.cab
06199720.cab: WARNING; possible 6960 extra bytes at end of file.
Extracting cabinet: 06199720.cab
extracting 06199720.dot
extracting content.inf
All done, no errors.
safeer@penguinpower:~/Desktop/PPTS$ cabextract 10168650.cab
10168650.cab: WARNING; possible 1024 extra bytes at end of file.
Extracting cabinet: 10168650.cab
extracting 10168650.dotx
extracting content.inf
All done, no errors.
The extracted files where in good shape and I was able to open them in Open Office.
From Wikipedia:
CAB is the Microsoft Windows native compressed archive format. It supports compression and digital signing, and is used in a variety of Microsoft installation engines: Setup API, Device Installer, AdvPack (for the installation of ActiveX components from Internet Explorer) and Windows Installer.
It was originally called Diamond. Its .CAB file extension and overall file format name comes from word cabinet, internally used by Microsoft tools dealing with CAB files to reference such files.
I got a couple of resume templates from Microsoft Web Site, but the downloaded copies where in .cab format. So googled to find a way to extract them and learned that there is something called "cabextract".
On my Ubuntu box:
safeer@penguinpower:~/Desktop/PPTS$ sudo apt-cache search cabextract
cabextract - a program to extract Microsoft Cabinet files
liborange-dev - development libraries for liborange
liborange0 - library to extract CAB files from self-extracting installers
orange - extracts CAB files from self-extracting installers
safeer@penguinpower:~/Desktop/PPTS$ sudo apt-get install cabextract
RPM based distros can get the package from Dag Wieers' Repositories (if they don't have a native package).
And then, extracted the cab files without errors.
safeer@penguinpower:~/Desktop/PPTS$ cabextract 06199720.cab
06199720.cab: WARNING; possible 6960 extra bytes at end of file.
Extracting cabinet: 06199720.cab
extracting 06199720.dot
extracting content.inf
All done, no errors.
safeer@penguinpower:~/Desktop/PPTS$ cabextract 10168650.cab
10168650.cab: WARNING; possible 1024 extra bytes at end of file.
Extracting cabinet: 10168650.cab
extracting 10168650.dotx
extracting content.inf
All done, no errors.
The extracted files where in good shape and I was able to open them in Open Office.
Labels:
File System,
Linux,
Windows
Saturday, May 16, 2009
Manipulating the bash directory stack
There are occasions when you traverse through so many directories stopping in each directory to work on something. After a few stops you may want to go back to one or all of the direcoties you have traversed. I can't remember a generic example to give you but we all come across this scenario many times. Bash provides a facility for addressing such issues and that is called the "bash directory stack"
In simplest terms directory stack is a list of recently visited directories, like your browser's favorite list. It acts like a conventional stack where you can push and pop items, but you can manipulate it further to reorder and remove items from the middle of the stack. Bash provides three 'directory stack built-in' commands to manipulate this stack, wiz pushd,popd and dirs.
pushd:
With a directory as argument, pushd will save(push) the current directory to the stack and change to the directory given by the argument.
popd:
Without any arguments, popd will remove the top entry from the stack and move to that directory.
dirs:
Displays the stack entries. With optional arguments, it can display selected directories from the stack.
Example:
Am going to add a few directories to the stack first.
safeer@penguinpower:~/bin$ pushd /etc/apache2/
/etc/apache2 ~/bin
safeer@penguinpower:/etc/apache2$ pushd /etc/cvsd
/etc/cvsd /etc/apache2 ~/bin
safeer@penguinpower:/etc/cvsd$ pushd /etc/cups/
/etc/cups /etc/cvsd /etc/apache2 ~/bin
safeer@penguinpower:/etc/cups$ pushd /etc/ldap/
/etc/ldap /etc/cups /etc/cvsd /etc/apache2 ~/bin
In practice pusdhd is done after working in a directory and then moving to another directory. Now let us see the stack contents using dirs command.
safeer@penguinpower:/etc/ldap$ dirs -l -v
0 /etc/ldap
1 /etc/cups
2 /etc/cvsd
3 /etc/apache2
4 /home/safeer/bin
The number associated with each directory shows the index of the corresponding directory in the stack with index zero being the present working directory.
Now let us try moving through the stack with popd.
safeer@penguinpower:/etc/ldap$ popd
/etc/cups /etc/cvsd /etc/apache2 ~/bin
safeer@penguinpower:/etc/cups$ popd
/etc/cvsd /etc/apache2 ~/bin
safeer@enjoyfast-lx:/etc/cvsd$
So I popped two directories out of the stack and now the contents of the stack becomes:
safeer@penguinpower:/etc/cvsd$ dirs -v -l
0 /etc/cvsd
1 /etc/apache2
2 /home/safeer/bin
This will give you a basic idea about stack manipulation. To see the full options for pushd/popd/dirs visit the GNU page for directory stack built-ins
A few more shortcuts and shell variables exists for manipulating the stack.
"$PWD" OR "$DIRSTACK" OR "~+" - Present working directory - Stack index zero
"$OLDPWD" OR "~-" - Previous working directory - Stack index one.
"$HOME" OR "~" - User's home directory
cd : Move to user's home directory. Alternatively use cd ~.
cd - : Move to $OLDPWD - pushd without any arguments will do the same. Or use cd ~-
Examples
safeer@penguinpower:/etc/cvsd$ echo ~{,-,+}
/home/safeer /etc/apache2 /etc/cvsd
which is equivalent to:
safeer@penguinpower:/etc/cvsd$ echo $HOME $OLDPWD $PWD
/home/safeer /etc/apache2 /etc/cvsd
In simplest terms directory stack is a list of recently visited directories, like your browser's favorite list. It acts like a conventional stack where you can push and pop items, but you can manipulate it further to reorder and remove items from the middle of the stack. Bash provides three 'directory stack built-in' commands to manipulate this stack, wiz pushd,popd and dirs.
pushd:
With a directory as argument, pushd will save(push) the current directory to the stack and change to the directory given by the argument.
popd:
Without any arguments, popd will remove the top entry from the stack and move to that directory.
dirs:
Displays the stack entries. With optional arguments, it can display selected directories from the stack.
Example:
Am going to add a few directories to the stack first.
safeer@penguinpower:~/bin$ pushd /etc/apache2/
/etc/apache2 ~/bin
safeer@penguinpower:/etc/apache2$ pushd /etc/cvsd
/etc/cvsd /etc/apache2 ~/bin
safeer@penguinpower:/etc/cvsd$ pushd /etc/cups/
/etc/cups /etc/cvsd /etc/apache2 ~/bin
safeer@penguinpower:/etc/cups$ pushd /etc/ldap/
/etc/ldap /etc/cups /etc/cvsd /etc/apache2 ~/bin
In practice pusdhd is done after working in a directory and then moving to another directory. Now let us see the stack contents using dirs command.
safeer@penguinpower:/etc/ldap$ dirs -l -v
0 /etc/ldap
1 /etc/cups
2 /etc/cvsd
3 /etc/apache2
4 /home/safeer/bin
The number associated with each directory shows the index of the corresponding directory in the stack with index zero being the present working directory.
Now let us try moving through the stack with popd.
safeer@penguinpower:/etc/ldap$ popd
/etc/cups /etc/cvsd /etc/apache2 ~/bin
safeer@penguinpower:/etc/cups$ popd
/etc/cvsd /etc/apache2 ~/bin
safeer@enjoyfast-lx:/etc/cvsd$
So I popped two directories out of the stack and now the contents of the stack becomes:
safeer@penguinpower:/etc/cvsd$ dirs -v -l
0 /etc/cvsd
1 /etc/apache2
2 /home/safeer/bin
This will give you a basic idea about stack manipulation. To see the full options for pushd/popd/dirs visit the GNU page for directory stack built-ins
A few more shortcuts and shell variables exists for manipulating the stack.
"$PWD" OR "$DIRSTACK" OR "~+" - Present working directory - Stack index zero
"$OLDPWD" OR "~-" - Previous working directory - Stack index one.
"$HOME" OR "~" - User's home directory
cd : Move to user's home directory. Alternatively use cd ~.
cd - : Move to $OLDPWD - pushd without any arguments will do the same. Or use cd ~-
Examples
safeer@penguinpower:/etc/cvsd$ echo ~{,-,+}
/home/safeer /etc/apache2 /etc/cvsd
which is equivalent to:
safeer@penguinpower:/etc/cvsd$ echo $HOME $OLDPWD $PWD
/home/safeer /etc/apache2 /etc/cvsd
Labels:
Bash,
File System,
Linux
Thursday, May 7, 2009
Cisco kron - the Cisco job scheduler
Cisco provides a job scheduler called "kron" which is similar to the unix crontab service. It allows us to schedule and run certain exec mode commands once or recurringly. The feature was first introduced in IOS version 12.3(1). The prerequisite for using kron is that Cisco clock time must be set - either locally or using an NTP source.
Check your IOS version first:
R1_Balancer#show version | include ^Cisco IOS(.+)Version
Cisco IOS Software, 3700 Software (C3725-ADVENTERPRISEK9-M), Version 12.4(18), RELEASE SOFTWARE (fc1)
The "kron" configuration has two parts, configuring "Scheduler Policy List" and then setting "Scheduler Occurrences". A scheduler policy list is similar to a shell script in unix. Every policy list will have a name and will contain one or more exec cli commands added sequentially. A scheduler occurrence is the setting that tells you when a policy list should be executed. You can associate one or more policy lists to a policy schedule.
Now let us create a kron policy with policy name my_policy_1. The commands that can be added in a policy should not generate any prompt or have the ability to be terminated using keystrokes. The simplest command that I can remember is write, which will save the running config to startup config( you can't use "copy running-config startup-config" since it will ask you to confirm the destination file name )
R1_Balancer(config)#kron policy-list my_policy_1
R1_Balancer(config-kron-policy)#cli write
R1_Balancer(config-kron-policy)#exit
You can view the policy from running configuration.
R1_Balancer#sh run | section include kron
kron policy-list my_policy_1
cli write
Let us create a schedule called schedule_1 now. This is set to run once at next Sunday night 11.45
R1_Balancer(config)#kron occurrence schedule_1 at 23:45 sun oneshot
Clock currently not set it reads 02:58:44 UTC Fri Mar 1 2002
If the clock is not set properly you will get a message as above. So set the time.
R1_Balancer#clock set 22:14:20 may 10 2009
R1_Balancer#show clock
22:17:29.487 UTC Sun May 10 2009
R1_Balancer(config)#kron occurrence schedule_1 at 23:45 sun oneshot
R1_Balancer(config-kron-occurrence)#policy-list my_policy_1
R1_Balancer(config-kron-occurrence)#exit
In the schedule you can optionally specify a user under which the kron should run. Now let us see the full kron configurations.
R1_Balancer#show run | section include kron
kron occurrence schedule_1 at 23:45 Sun oneshot
policy-list my_policy_1
kron policy-list my_policy_1
cli write
To view the schedule you can run this command:
R1_Balancer#show kron schedule
Kron Occurrence Schedule
schedule_1 inactive, will run once in 0 days 01:24:51 at 23:45 on Sun
For detailed information on kron, visit this Cisco link.
Check your IOS version first:
R1_Balancer#show version | include ^Cisco IOS(.+)Version
Cisco IOS Software, 3700 Software (C3725-ADVENTERPRISEK9-M), Version 12.4(18), RELEASE SOFTWARE (fc1)
The "kron" configuration has two parts, configuring "Scheduler Policy List" and then setting "Scheduler Occurrences". A scheduler policy list is similar to a shell script in unix. Every policy list will have a name and will contain one or more exec cli commands added sequentially. A scheduler occurrence is the setting that tells you when a policy list should be executed. You can associate one or more policy lists to a policy schedule.
Now let us create a kron policy with policy name my_policy_1. The commands that can be added in a policy should not generate any prompt or have the ability to be terminated using keystrokes. The simplest command that I can remember is write, which will save the running config to startup config( you can't use "copy running-config startup-config" since it will ask you to confirm the destination file name )
R1_Balancer(config)#kron policy-list my_policy_1
R1_Balancer(config-kron-policy)#cli write
R1_Balancer(config-kron-policy)#exit
You can view the policy from running configuration.
R1_Balancer#sh run | section include kron
kron policy-list my_policy_1
cli write
Let us create a schedule called schedule_1 now. This is set to run once at next Sunday night 11.45
R1_Balancer(config)#kron occurrence schedule_1 at 23:45 sun oneshot
Clock currently not set it reads 02:58:44 UTC Fri Mar 1 2002
If the clock is not set properly you will get a message as above. So set the time.
R1_Balancer#clock set 22:14:20 may 10 2009
R1_Balancer#show clock
22:17:29.487 UTC Sun May 10 2009
R1_Balancer(config)#kron occurrence schedule_1 at 23:45 sun oneshot
R1_Balancer(config-kron-occurrence)#policy-list my_policy_1
R1_Balancer(config-kron-occurrence)#exit
In the schedule you can optionally specify a user under which the kron should run. Now let us see the full kron configurations.
R1_Balancer#show run | section include kron
kron occurrence schedule_1 at 23:45 Sun oneshot
policy-list my_policy_1
kron policy-list my_policy_1
cli write
To view the schedule you can run this command:
R1_Balancer#show kron schedule
Kron Occurrence Schedule
schedule_1 inactive, will run once in 0 days 01:24:51 at 23:45 on Sun
For detailed information on kron, visit this Cisco link.
Labels:
Automation,
Cisco
Subscribe to:
Posts (Atom)