Pages

Finding the string length in scripting

Here are three scripts for finding the length of string using scripting

1. Using bash string operation



2. Using grep



3. Using wc



Save them and give them execute permission e.g.

Execute it



Thus giving the correct length of the input string.

pthreads-2: Creating a detachable thread

In the post "pthread creation" we saw how to create a simple thread and we had used the default attributes for the thread.
One of the default attribute is that the thread is creates always as a joinable i.e. the parent thread has to call pthread_join for the thread to successfully terminate.
On the other hand if we do not want to call pthread_join from the parent, but let the child thread finish and in then inform the parent, then we will have to change the attribute to "detachstate".
If we create a thread in the "detachable" state, then the parent thread need not call pthrea_join, it will just have to wait till the thread exits and informs about it .
The two states supported by POSIX are



To set the attributes to default value we can use



Now to modify the detachstate from joinable we will use the function:



Arguments:



Thus to modify the default initialization we will use



Now we can create a thread using the above attribute variable and we need not call pthread_join on this thread.



Note: hello is the same function we defined in the post "pthread creation"
The full code will look as follows.
detachable_thread.c



Please note that the function "hello" has the statement



This is because the parent is waiting for the child to exit and does not call join to check the child's status.
Now compile it using the options -pthread



Execute it :



Output:



To see the effect of creating a detachable thread, remove the exit from the function "heelo" and the execute the program. We will see that the process goes into an infinite wait as the parent thread keeps waiting for the child thread to call the exit.

Highlighting the output of grep

grep is used for searchin for a string or a pattern in a given input stream. By default the grep ouputs the whole line in which the search string is found.
For e.g. if we have a file "info" as below
info



If we want to search for the string "linux" we would do it as follows



output



Note: By default grep is case sensitive.
In the above line, the search string is not differentiated from the whole line in any way. But if we want to hightlight the search string in the result of the grep we can do it by passing the option --color i.e



output :
Welcome to linux, a free operating system

In the above output the search string "linux" has been hightlighted, thus differentiating the search string clearly from the rest of the text.

pthreads-1 :Creation of a thread using pthreads

pthreads are posix threads supported by the unix based systems. The pthread library allows us to create multiple threads in the user space and execute varions operations in each of the thread. Let us see how we can create a thread using posix thread library.
The function to create a thread is



Arguments:



Thus to create a thread
Declare a variable of kind pthread_t



Declare a variable of kind pthread_attr_t



Create a function which needs to be executed in the thread.
For e.g.



We will need pass a pointer to the above funtion to pthread_create and as we are not sending any arguments to the function we can pass NULL in the arg field of pthread_crate. Thus to create thread with default attributes and which will execute the function hello will look as follows



Once the thread is created by the parent thread should wait for the completion of the child thread Because if the parent thread gets killed, the child thread will automatically be killed and hence the operations of the child thread will never be executed.
To make the parent thread wait for the children threads we make use of the function pthread_join .



Arguments:



Thus to make the parent thread to wait for the child thread
We will need a variable



ptread_join will look as follows.



Thus the whole code to create a thread using pthread create will look as follows.
create_thread.c



To compile a program that used the pthread library we need to pass the option -pthread to gcc to ling the required libraries and compile it successfully.



The output should be:



We can see that the parent thread creates a thread and waits for it to complete before exiting. If we removed the pthread_join(and the print of return value) from our program the output would look as below.



As the parent thread did not wait for the child thread, the child thread never got a chance to exit as it got killed as soon as the parent exited.

Launching a GUI window as root (superuser)

To launch an GUI window as root, we can use the command



for e.g. if we want to open the nautilus file browser as root then we can use the command



This will launch the file browser as the super user or the root.
We can also launch the root terminal i.e. a terminal which always works as the root, and we need not use the sudo command in it.




Grabing or moving a window using keyboard

Some times the terminal window or other GUI windows move to uncomfortable positions, from where we are unable to grab the title bar using the mouse to pull it back to where we want.

In such situations we can use a keyboard option to grab the window, i.e Alt+F7.

This will grab the window and then you can use the mouse or the arrow keys to move the window to which ever position we want.

Compiling linux kernel on debian

Here are the steps to compile a kernel from source in debian based systems.

Note:These steps have worked successfully on debian 6.0 (linux 2.6.32)
You will need a package by the name kernel-package, which implements the commands required for compilation, hence run



1. Download the source of the kernel version to which you want to compile e.g. linux-3.1.5.tar.bz2 or linux-3.1.5.tar.gz for linux kernel version 3.1.5 2. Untar the source using



Now change directory to kernel source



The make-kpkg command which we will use to compile the kernel might some times fail generate the initrd, to make sure the initrd is generated at the end of compilation run the following command.



Create a config file using the command



This will create a default configuration file, to customize it we can either open the .config file using an editor and set the required configuration or use the menuconfig i.e



Note: ncurses-devel package would be required to launch the menuconfig, hence if menuconfig does not launch with the error that ncurses was not found install the package.


A graphics window should launch which will allow you to select the options you need and then create an updated .config file based on your choices.
Now to compile and generate the deb package for the new kernel run the command



If you want the kernel headers too then add the target kernel-headers also to the command. 10. If the compilation in the above step finishes with out any errors, you should have a .deb package, linux-image-3.1.5_3.1.5-10.00.Custom_i386.deb in the folder in which you have placed the source package.
Install the package using



Now if you restart the system, the grub should list out this kernel too in the boot options, on selecting which you will boot into the custom kernel with your system call in it.


We can confirm the kernel version using the command


Finding out the amount of RAM being used

To find out the amount of RAM and swap space being used by all the processes in the system we can use the command free
for e.g.



To make the output a little more easy to understand we can use the option
"-k" for output in kilobytes,
"-m" for output in megabytes,
"-g" for output in gigabytes,
We can also make free to run periodically by using the options "-s" . For e.g.



Will run the command every seconds.

ejectiing a cdrom from the command line

The cd/dvd drive, which is usually ejected by pressing the button on the drive can also be controlled from the command line. The command to eject the drive from the command line is

The command works only on a Desktop and is not useful in laptops
Here is small fun script to play a prank on some one,
The script keeps ejecting and closing the cdrom cover repeatedly ,untill the script is not killed or the terminal from which the script was launched is not closed.


ejectcd.sh:

Save the script and give it execute permissions



execute it



and see the fun with the cd drive popping out and in all by itself.
You can kill it by pressing cntrl+c or closing the terminal from where the script was launched.

bash: ifconfig: command not found



This is a very common error which lot of us might have encountered for commands like ifconfig,insmod,modprobe etc.
The error does not mean that the system does not have the command, it just means that these commands are placed in the folder /sbin and only superusers are supposed to execute the commands in the folder /sbin.

All the other commands that we are allowed to execute with as normal users are placed in the folder /bin.
Thus to get around this error add sudo before the command. i.e.



Note that adding sudo will only work if the user has the permission to execute sudo i.e. has the admin rights.

Displaying the commands being run by make.

Make files are used to compile multiple source files and to generate executable from the source code.
If we want to check what are the files being compiled or what commands are being executed by make, we can open the make file using an editor and look into it which in case of big makefiles can be a difficult task or use the option "--just-print" with make.



If your makefile is not named "makefile" or "Makefile" add the name of the file with "-f " option i.e.



The output Will display all the commands that the makefile will execute when make is actually executed.
Could be quite useful when you want to debug makefiles written by some one else.

Creating a triangle of characters in the terminal

Here is a script that crates a triangle of what ever character we choose.
The triangle gets created right at the center in the terminal.
The script uses tput along with various loops to create the triangle.

triangle.sh



Save the script and give it execute permission



Execute the script as follows



You should see a triangle of * as below on the terminal.



You can enter any number of rows and any character to create the triangle, the only limit being the number of rows should not exceed one screen of the terminal, it can not create a shape that goes beyond one screen.

pgrep: grep of processes

pgrep searches in the currently running processes for processes that match the search criterion passed as the argument.
For e.g. If we want to view all the processes that are being run by user1 we can use pgrep with the option -u i.e.



This will the pids of all the processes being run by user1. To list the pid as well as the process name add the option "-l". i.e.




Finding the process id from its name

Every process in linux has a unique process id, which can be used to control the process.
To find the process id from the process name we can use the command pidof
For e.g.


Launching gnome help from terminal

When using the gnome desktops, its common to use the function key F1 to launch the genome help window. But same can also the done from the command line .
The command launch gnome help from command line or the terminal is




Inbuilt vim tutorial in linux

One of the simplest ways to learn using the "vi" editor is using the inbuilt tutorial in Linux.
Open a terminal and type the command



And you should have a tutorial on your screen which will allow you to practice the lessons as you read them.

coldreboot

If we have kexec enabled in the system, on reboot it by default boots back into the same kernel with out showing the grub menu. (More details in the post "Disabling kexec)
But if we still want to do the traditional reboot i.e. boot all over from the BIOS then we can use the command coldreboot .



This command will restart the system in the traditinal way and also give us the grub prompt to choose the boot option which is not given we do the kexec reboot. Note:We need to have root privileges to be able to use the command.

Disabling kexec

In debian 6.0(Or any other distro that uses kexec) when we reboot(Either from GUI or from the command line) it does not display the grub menu and directly loads the kernel that we are running currently.
This is because of the use of a system call called kexec.
kexec makes reboot faster because it skips the hardware initializations that BIOS does and directly loads the kernel.
This behaviour can be modified by setting the flag LOAD_EXEC in the file /etc/default/kexec to false.



and set the flag as below



Note: After changing the flag, shutdown and boot the system for the change to take effect. Rebooting straight away might not work.

Making sudo remember the password

The sudo command by default remembers a password for 15 minutes i.e. once a user enters the correct password for sudo the user can use sudo with out being prompted for password for 15 minutes.

This behaviour can be modified using the flag "timestamp_timeout" in the /etc/sudoers file.
To make sudo remember the password for 30 minutes add the following line after the initial comments.



To make sudo prompt for password every time add the following line after the initial comments



And to make sudo remember the password as long as the terminal is open add the,following line


Finding the number of columns in a terminal

If we want find the number of columns in a terminal, we can use the command tput


Making sudo give a lecture every time it is used.

sudo command needs to be used with caution and sometimes we might need make this caution obvious with a message .
There is an option in sudo using which we can inform the user about using sudo with a message every time sudo is used.

Open the file /etc/sudoers



Add the following line after the intial comments to make sudo to throw the lecture every time sudo is used by a user.



If giving lecture every time seems like an overkill, it can be made to lecture only once when a user uses the sudo for the first time.

The message that is shown by default is



Instead of the above message, we can show our own customized message by putting the message into a file. for e.g. let us put the following message



In a file called lecture ,under the folder /home/user .

To make sudo use this file for the lecture message add the following line after enabling the lecture as shown above.



Save and quit the file. The next time we use the command sudo, we should see the above message being shown.

Making sudo prompt for root password

When we use the sudo command, it by default asks for the password of the user as whom we executed sudo.
If we want to change this behaviour and make sudo prompt for the password of root instead of user password, we can do it by adding the flag rootpw to the file etc/sudoers

Open the file /etc/sudoers



Add the following line after the inital comment lines



Note: Please do this only if you know the root password

Save and quit.
After this the next time sudo is used remember to enter the root password and not the user password.

No package 'mono-cairo' found

Workaround for the error in debian lenny :

Install the package mono-devel

No package 'glib-sharp-2.0' found

Workaround for the error in debian lenny :

Install the package libglib2.0-cil-dev

Making sudo display * while entering password

While using the sudo command by default there is no response on the screen what we type the password, it remains blank and only after we hit enter we see any response.
This can get a little confusing for the beginners who are used to seeing "*" or other characters when password is entered.
sudo can also be made to behave the same way by adding the flag "pwfeedback" to /etc/sudoers .

Open the file "/etc/sudoers" (You will need root privilege)



After the intial lines of comments add the following



Save the file and quit.

Note: This introduces a securtiy threat as an onlooker can see the number of characters present in the password.

The next time sudo command is used, we should see "*" instead of just blank space while entering the password.

Module to print the open files of a process

Linux maintains the information about the current process in a structure task_struct.
A macro named current returns a pointer to the task_struct of the current process.
A process can have one or more open files at any given time. A list of all the open files that any process has can be obtained from the structure task_struct.
The task_struct has a member files, which is of type files_struct.
The structure files_struct maintains the information regarding the files that are being used by the process.
files_struct which is defined in fdtable.h is as follows.



The member fdt, in files_struct, of type struct fdtable stores the file descriptors and other relevant pointers for the currently open files.
The struct fdtable which is also defined in fdtable.h is as follows



The member open_fds is bitmap of all the open files, and the member fd is a pointer to the array, which stores the pointers to struct file of each of the open file.

The index of the fd array is the file descriptor of the corresponding file.

The struct file has a member f_path which will enable us to get the complete path in the filesystem for the corresponding file.

Thus to get a list of all the open files we need to access the array fd in the structure fdtable.

The function files_fdtable defined in fdtable.h returns a pointer to the fdtable, taking as input the files_struct.

Once we have fdtable we can iterate over the fd array, printing the file path of each fd.

To retrieve the actual path from f_path we need to make use of the function d_path



defined in fs/dcache.c

Here is module that prints all the open files on being inserted into the kernel.

current_files.c



Makefile to compile the code



Note: Code tested on 2.6.32


Compile and insert.



After inserting into the kernel using insmod, to see the output run the command



By default all processes have 3 files open the standard input, standard output and the standard error with file descriptors 0,1,2 respectively.
Thus the three values /dev/pts/1 are pointing to the terminal on which we are ran the insmod.
To see how the file path changes if we change one of the three file descriptors, add a redirection to a file of output to a file.



Now run dmesg.



The path of file descriptor 2 has changed from the terminal to the new redirected file.

Making sudo throw insults instead of error

The sudo command by default prompts for the password of the user and on entering the wrong password it throws the error

To make this a little more fun, we can change the error to some thing else. The sudo command has an option using which sudo can be made to throw mildly rude comments as errors.
To this open the file /etc/sudoers (You will need root privileges).



Add the following line at the beginning of the file (after the intial set of comments).



and save the file.
Now try using the command sudo and enter a wrong password.
For e.g.


User is not in the sudoers file. This incident will be reported

On using the sudo command if we see the error



This means that the user as whom we have logged in and are trying to run the command "sudo" does not have the permission to do so.
Only the users listed in /etc/sudoers have the permission to use the command "sudo".
To give the sudo permission to a user we need to add the user to the file /etc/sudoers file.
Open the file /etc/sudoers as root.



Add the line



under the User privilege specification section.
Save the file and exit, now the sudo command should work for the user which was added in the file.

The working of macros MAJOR,MINOR and MKDEV

In linux, every device under /dev is associated with two numbers "major number" and the minor number.

Where the major number represents the driver that the device is being controlled by and the minor number is the number that the driver uses to recognize the device so that even if the same driver controls multiple devices it can defferentiate between them.

In the kernel versions before 2.6 these two numbers were 8 bit numbers thus allowing only 256 drivers with each controlling maximum of 256 devices.

But this was not enough for the modern systems like the big servers which have a large number of devices connected to them.

Thus from 2.6 these two numbers are combined and stored in one 32 bit number of the data type dev_t. Out of the 32 bits the MSB 12 bits represent the major number and the LSB 20 bits represent the minor number.

Thus when we allocate a major number dynamically in a driver the kernel fills up the variable dev_t with the combination of the major number and the first minor that we requested for.

Given a dev_t number we can extract the major number and minor number using the macros MAJOR and MINOR respectively.

And given two integer numbers we can combine them and convert them into one dev_t using the macro MKDEV.

These three macros are defined in the header file linux/kdev_t.h as shown below.



MAJOR

The macro MAJOR accepts a dev_t type number which is 32 bits, and right shits it by MINORBITS which is defined as 20 bits as shown above.

To see how this works let us take dev_t to be a 6 bit number, with MSB 2 bits being the major number and the LSB 4 bits being the minor.

let dev_t be 33 i.e. 100001 in binary . To extract the major number that is the first two bits we will have to right shift it 4 times.

Which gives the result 2, thus the major number is 2.

Similarly the macro MAJOR shifts dev_t by 20 bits to extract the major number.

MINOR The minor number is stored in the lower 20 bits, to extract that we will have to mask the first 12 bits i.e. make them as 0.

Taking the same example as above
Let dev_t = 33 i.e. 100001
We create a mask 001111, which when anded with 100001 should extract the LSB 4 bits as the MSB 2 bits when anded with 0 will always be 0.
This mask is created by taking the number 1 => 000001
Left shifting it by MINORBITS that is 4 in our example



Thus the mask becomes 010000.
Now subtract this with 000001



The mask 001111 is anded bitwise with 100001

Thus we are able to extract the lower 4 bits,0001, which is the minor number .
Macro MINOR retrives the minor number in the same way except that it shifts 1 by 20 bits.

MKDEV



Given two integers, MKDEV combines them into one 32 bit number.
This is done by left shifting the major number MINORBIT times i.e. 20 times and then oring the result with the minor number.
For e.g. if the major number is 2 => 000010 and the minor number is 1 => 000001
Then left shift 2, 4 times



Then or this with the minor number



The result,100001, is the dev_t after combining the major number 2 with minor number 1.
The macro MKDEV works in the same way except that it is a 32 bit number.

Changing the terminal prompt to date

The standard prompt in most of the terminals is "username@computername" or some thing similar to it.
But this can be changed easily, just by setting a variable "PS1".
To change it temporarily open a terminal and type



and you will see the prompt change to hello.
But how about making the prompt a little more sensible, like the date.

To change the prompt to the current date run the following command in a terminal



These changes are temporary and will be lost as soon as the terminal is closed.
To make them permanent add them into the ~/.bashrc file.
Either you can look for the line where PS1 gets set to the default value in the .bashrc file or just over ride the previous assignment by adding the new assignment at the end of the file.

Deleting a command from the history

The history command allows us to look at all the various commands that we have executed in the recent time.
The number of commands remembered at any given time is determined by the environment variable HISTSIZE.
We can use the echo command to see its value



If we want to get rid of some of the unnecessary commands that have been stored in the history (or keep some the commands we have executed a secret ;-) ) we can use the option "-d" with the command history and pass as an argument the command number that has to be deleted.

For eg.



The above is just a snapshot of some of the commands that got listed in the history in my terminal, now if the command "kill -9 -1" has to be removed from the list which has number 496 we can do it by running the command



Now if we run the history command again, the "kill -9 -1" will not be listed and the number 496 will have been assigned to the next command in the list.