Tuesday, December 16, 2014

Shell Scripting : How to truncate a file to zero length, without changing permissions?

To truncate a file to zero length without changing permissions, here are the options

1) cp /dev/null file.xxx
2) : > file.xxx

In the second option involving colon(:), the : being a shell built-in command, no new process is forked.

Monday, December 15, 2014

Shell Scripting: What if shebang(#!) is followed by path of the command /bin/rm i.e #! /bin/rm

What will happen if the following script, test.sh, is executed?

#!/bin/rm

echo "Hi"

./test.sh when executed, will remove the file test.sh

Shell scripting : What if there are two shebang(#!) lines in the shell script?

Suppose if there are two she-bang (#!) lines in a shell script

#!/bin/bash

echo "First line"

#!/bin/csh

echo "Second line"

When we run the above script, will /bin/bash be the interpreter for executing the command echo "First Line"  and later  /bin/csh be the interpreter for executing the command echo "Second line"?

No. Only the first line is #!/bin/bash is the interpreter for the whole script. The second interpreter beginning with # is considered as a comment. Any line beginning with # following the first shebang line is considered as a comment.


Shell Scripting : Which gets executed - shell specified in shebang(#!) or shell specified in command line

Suppose I have an executable script, test.sh as follows

#!/bin/bash

readlink /proc/$$/exe

When I run the above script as ./test.sh, then I know that bash shell executes the script. Then the output of above script is

$ ./test.sh
/bin/bash

If I run the above script as follows

$ /bin/csh test.sh

Which shell will execute the script - csh(specified in the command line) or bash(specified in the shebang)?

The output of the the above command is /bin/csh.

So why does /bin/csh execute the script instead of /bin/bash specified in the script?

Here is the answer,

Whenever a shell script is executed, a new shell(process) is spawned(forked) and the commands in the scripts are executed. The child shell becomes the parent process of commands in the script.
The shebang, #!, is used by the exec() family of functions to determine whether the file to be executed is a binary or script. If the shebang(#!) is present, then exec() will run the executable specified after the shebang - in the above case it is /bin/bash. she-bang is actually a two byte magic number that designates a file type. Immediately following the she-bang(#!) is the path name - this is the path to the program that interprets the commands in the script whether it be a shell, programming language or a utility. This command interpreter then executes the commands in the script starting at the top(following the shebang #! line), ignoring commands.

Now if you run the script by specifying the shell in the command line, like /bin/csh test.sh, the exec() will execute the shell interpreter, /bin/csh specified in the command line instead of looking into the script for shell interpreter specified in shebang line.


Thursday, December 11, 2014

SIGNALS: Use Signal Names or Signal Numbers with KILL command?

While passing signals to kill command, it is always better to use signal names rather than their numbers because the same signal is sometimes represented by different names on SVR4 and BSD systems.

Wednesday, December 10, 2014

How to copy a specific file type keeping the folder structure intact in the destination directory

By using cpio command in pass through mode, files can be copied to the destination directory with the same path structure as in the source directory

find /source_path/of/files -name "<regex_of_filetype>" | cpio -pdm /destination_directory_path

Eg: To copy all files of type "*.sh" in /home/bob to /tmp/jim, keeping the source directory path of files in destination intact


find /home/bob -type f -name "*.sh" | cpio -pdm /tmp/jim

How to find the version of cloudera Hadoop

Read the following file

# cat /usr/lib/hadoop/cloudera/cdh_version.properties

# Autogenerated build properties
version=2.0.0-cdh4.1.2
git.hash=f0b53c81cbf56f5955e403b49fcd27afd5f082de
cloudera.hash=f0b53c81cbf56f5955e403b49fcd27afd5f082de
cloudera.base-branch=cdh4-base-2.0.0
cloudera.build-branch=cdh4-2.0.0_4.1.2
cloudera.pkg.version=2.0.0+552
cloudera.pkg.release=1.cdh4.1.2.p0.27
cloudera.cdh.release=cdh4.1.2
cloudera.build.time=2012.11.02-00:01:31GMT

cloudera.pkg.name=hadoop

The Hadoop version installed is 2.0.0-cdh4.1.2, which means that Cloudera version installed is based on Apache Hadoop 2.0.0 release.