1754807 Members
3959 Online
108825 Solutions
New Discussion юеВ

Re: symbolic links

 
SOLVED
Go to solution
Sajjad Sahir
Honored Contributor

symbolic links

dear All
I need a shell script to create symbolic link
ln -s.
i am giving out put of the shell script running on anohter server same shell script i need to execute in my server.so I need to write a script to get the same output like my attachment

thanks and regards
sajjad
13 REPLIES 13
Dennis Handly
Acclaimed Contributor
Solution

Re: symbolic links

If you want to create every symlink that's in your previous output you can do:
awk '
$10 == "->" {
print "ln -s", $11, $9
} file-list > create_links

Then take a look at the output. If you like it, then:

cd directory
sh $OLDPWD/create_links
James R. Ferguson
Acclaimed Contributor

Re: symbolic links

Hi Sajjad:

If you would like a pure shell script (no 'awk' nor Perl) then :

# cat ./makelinks
#!/usr/bin/sh
INPUTFILE=$1
while read MODE X X X X X X X SRC X DST
do
if [ "$(echo ${MODE}|cut -c1)" = "l" ];then
echo ln -s ${DST} ${SRC}
fi
done < ${INPUTFILE}

...run as:

# ./makelinks file

...where the "file" argument is the name of the file to process --- exactly like your attachment in this post.

Change the line:

echo ln -s ${DST} ${SRC}

to:

ln -s ${DST} ${SRC}

...when you are satisfied with the proposed actions.

Regards!

...JRF...
Sajjad Sahir
Honored Contributor

Re: symbolic links

cat ./makelinks
#!/usr/bin/sh
INPUTFILE=$1
while read MODE X X X X X X X SRC X DST
do
if [ "$(echo ${MODE}|cut -c1)" = "l" ];then
echo ln -s ${DST} ${SRC}
fi
done < ${INPUTFILE}

...run as:

# ./makelinks file

...where the "file" argument is the name of the file to process --- exactly like your attachment in this post.

Change the line:

echo ln -s ${DST} ${SRC}

to:

ln -s ${DST} ${SRC}

dear torsten I don't shell script much more if u don't mind please can u explain what are the parameters mentioned in u steps

thanks in advance for u and my dear dennis
I need normal script


James R. Ferguson
Acclaimed Contributor

Re: symbolic links

Hi (again) Sajjad:

I wrote [ and I am JRF, not Torsten :-)) ]:

cat ./makelinks
#!/usr/bin/sh
INPUTFILE=$1
while read MODE X X X X X X X SRC X DST
do
if [ "$(echo ${MODE}|cut -c1)" = "l" ];then
echo ln -s ${DST} ${SRC}
fi
done < ${INPUTFILE}

...By line:

#!/usr/bin/sh

should always be set to specify the name of the interpreter to run --- here the HP-UX Posix shell.

INPUTFILE=$1

assign to the variable named INPUTFILE the first argument passed to the script. Arguments are denoted as $1, $2, etc. with $0 being the name of the process.

while read MODE X X X X X X X SRC X DST
do

This begins a while loop which runs the block bounded by the 'done'. The built-in shell 'read' collects the whitespace-delimited fields on each line read. The contents of the line so read are split into fields and assigned to variables of our choice. Since I only care about the first field (called "MODE") and the 9th and 11th which represent the "source" (SRC) element of the command I want to run; and the "destination" (DST) argument of the command that I want to run; I let the 'read' assign the fields I *don't* want to the bit-bucket in a variable I called "X".

if [ "$(echo ${MODE}|cut -c1)" = "l" ];then

This takes the MODE field we extracted and snips ('cut's) the first character from it. We then compare that character to the string "l" to match symbolic links from your original 'ls' listing. For matches (which represent lines from the 'ls' that show links) we do the next statement:

echo ln -s ${DST} ${SRC}

To end the scope of our condition (the 'if' we say:

fi

which is "if" spelled backwards.

The statement:

done < ${INPUTFILE}

...terminates the 'while do' we have and says to read as input ('<') the file (represented by the variable we assigned from the *first* script argument ($1) at the beginning of the script. This is an efficient mechanism. To often folks will write:

cat ${INPUTFILE} | while read...

...which is a *waste* of a process. You don't need 'cat' to open and read a file only to take the output of 'cat' and *read* it all over again!!!

Regards!

...JRF...


James R. Ferguson
Acclaimed Contributor

Re: symbolic links

Hi (again) Sajjad:

I should add a few shell facts about variables, too:

Variables spring into being when you assign to them:

VAR=sajjad

or (a more advanced way):

typeset VAR=sajjad

Now, to dereference (get the value of) a variable you must add the "$" sigil:

# echo $VAR
sajjad

But, a much safer thing to do is to enclose the variable name in curly braces, like:

# echo ${VAR}

This keeps the shell from confusing something like:

# VAR=_sajjad
# echo $VAR
_sajjad
# echo $VAR_here
sh: VAR_here: Parameter not set.
# echo ${VAR}_here
_sajjad_here

Now, it is just as legal for me to have done:

# INPUTFILE=${1}

...instead of :

# INPUTFILE=$1

...although this is pretty unambiguous in the context I used it.

*However*, if you needed to reference a positional parameter that is more than one-digit in length (g.g. ${10)) then you *must* enclose it in curly braces, so it is a good habit anyway!

As for the shell's 'read' statement. The auto-splitting of the record read ( --- a line ending with an ASCII newline character ) into its whitespace delimited fields, is controlled by the shell's 'IFS' [Inter Field Seperator] parameter. By default the IFS is a space, a tab and/or a newline character. This doesn't mean that the shell's 'read' is limited to spliting into only whitespace-delimited files, though.

OLDIFS=${IFS}
IFS=":"
while read NAME X
do
echo ${NAME}
done < /etc/passwd
IFS=${OLDIFS}

...the above alters the 'IFS' to a colon in order to read and auto-split into fields, the '/etc/passwd' file. In order to insure that you reset the IFS to what you originally had, we store it off in OLDIFS and restore it at the end of the loop where we used the modified variable.

The Posix shell is found as '/usr/bin/sh' and as '/sbin/sh' for the *root* account. Never alter root's default shell as defined in the '/etc/passwd' shell field of the root account! The '/sbin'sh' uses statically linked libraries that allow its use in single-user mode without '/usr/ mounted. The '/usr/bin/sh' version uses dynamic libraries and therefore has a smaller memory footprint given that the libraries it uses can be shared by multiple processes.

The HP-UX Posix shell is based on the Korn shell ('ksh'). Have a look at the manpages to learn more:

http://www.docs.hp.com/en/B3921-60631/sh-posix.1.html

...and at a very good, quick-start of the shell here:

http://www.docs.hp.com/en/B2355-90046/index.html

Regards!

...JRF...
Dennis Handly
Acclaimed Contributor

Re: symbolic links

>if you don't mind please can you explain

The awk script is even simpler to explain.
For every line in your input file "file-list", it does the following:
The pattern "$10 == "->"" checks when field 10 is "->", a symlink.
The action prints the "ln -s" with field 11 and field 9.
Sajjad Sahir
Honored Contributor

Re: symbolic links

dear
I am not asking variable assingning
I didn't get u peoples script properly
ok
any how i will study thoroughly then i will ask again

thanks alot

sajjad
Sajjad Sahir
Honored Contributor

Re: symbolic links

see dears

tdap1.dbf and rtdap1
tdap2.dbf and rtdap2
means i would like to symbolically link

these files with logival raw devices lie rtdap1 etc..
i have a lot fo dbf .log file extension i have to symbolically link these files with rtdap1 rtdap2 in this order
ln -s tdap1.dbf rtab1
ln -s tdap2.dbf rtab2
ln -s ttab3.log rttab3
etc...
how to do this one this is my question

sajjad
James R. Ferguson
Acclaimed Contributor

Re: symbolic links

Hi (again) Sajjad:

As you have seen, reading an input file to extract two fields representing the two files to symbolically link is trivial.

I do not understand what hasn't been provided. Please give an example of the *exact* input you want to use to create your links.

Based on your last post it almost looks like you want to create a name like "rtdap" from a name like "tdap.dbf" so that:

rtdap1 -> tdap1.dbf
rtdap2 -> tdap2.dbf

If this is the case, a small Perl script could do everything from finding files that match the pattern "tdap.dbf" to creating the symbolic links to them in the form "rtdap":

# cat .makelinks
#!/usr/bin/perl
use strict;
use warnings;
my ( $srcfile, $dstfile );
@ARGV = glob("tdap*");
for $srcfile (@ARGV) {
( $dstfile = $srcfile ) =~ s/tdap(\d+).dbf/rtdap$1/;
symlink( $srcfile, $dstfile );
}

# cd /path
# ls -l
-rw-r--r-- 1 root sys 0 Jun 16 16:45 tdap1.dbf
-rw-r--r-- 1 root sys 0 Jun 16 16:45 tdap2.dbf
-rw-r--r-- 1 root sys 0 Jun 16 16:45 tdap3.dbf
# ./makelinks
# ls -l
lrwxr-xr-x 1 root sys 9 Jun 16 16:45 rtdap1 -> tdap1.dbf
lrwxr-xr-x 1 root sys 9 Jun 16 16:45 rtdap2 -> tdap2.dbf
lrwxr-xr-x 1 root sys 9 Jun 16 16:45 rtdap3 -> tdap3.dbf
drwxr-xr-x 2 root sys 96 Jun 5 13:46 subdir
-rw-r--r-- 1 root sys 0 Jun 16 16:45 tdap1.dbf
-rw-r--r-- 1 root sys 0 Jun 16 16:45 tdap2.dbf
-rw-r--r-- 1 root sys 0 Jun 16 16:45 tdap3.dbf

Regards!

...JRF...