Pages

Affichage des articles dont le libellé est csh. Afficher tous les articles
Affichage des articles dont le libellé est csh. Afficher tous les articles

vendredi 9 août 2013

Exit from child script to parent script with error message


In csh, use

exit [n]

Suppose you want to write a script named readable that returns a 0 if a file is readable and a 1 if the file is not readable.
     if [ -r "$1" ] then
          exit 0
     else 
          exit 1
     endif
You pass readable a single argument, which is a filename. If the file is a readable file, the return code is a 0; otherwise, a 1 is returned. Now in your parent shell you can use the $? ($status-csh) variable to test whether the file is readable are not. For example, your parent shell might look like this:
     readable somefile
     if [ $? ] then
          echo "Processing the file"
          ...
     else 
          echo "Cannot read the file"
     endif
This provides you with the capability to tell whether a child shell script completed with or without errors.


Note: this useful text is from http://alasir.com/

jeudi 1 août 2013

@: Badly formed number, octal problem in shell

In a csh script, I have :

set a = "08"
printf "%03i" $a
printf: 008: value not completely converted


set c = "08"
@ c ++
@: Badly formed number.

This happens when the variable a is equal to 018,..., 098, as well as 09, 019 .... 099.
This is because: 1) while shell treats numbers starting with 0 ("08") as octal, but not as integer number; 2) 8 and 9 do not exist in octal; 3) my tcsh version: tcsh --version is tcsh 6.17.00 (Astron) . (In fact in an older version tcsh 6.13.00 (Astron), the same error does not happen !)

The solution is to remove the leading 0s from the variable before we apply the commands such as printf or @. for example:

set a = "008"
set a  =  `echo $a   |   sed   's/^0*//g`
@ a ++







vendredi 25 mai 2012

paste: concatenate columns to form a new file

If file1:
0.0066
0.0357
0.0475
0.0609
0.0370
0.0443

file2:
0.0181
0.0176
0.0155
0.0152
0.0131
0.0137

Then use the linux command "paste file1 file2 ", we can concatenate two columns as follows :

0.0066 0.0181
0.0357 0.0176
0.0475 0.0155
0.0609 0.0152
0.0370 0.0131
0.0443 0.0137

by default the delimiter is Tab. If we want to define our own delimiter, we can :

paste -d " " file1 file2 

This will use one-space as the delimiter between the two.


If the two files have multiple lines, it seems to me that paste has difficulty to merge them correctly. In a case I have two files and each have 3 columns. Finally what it works well is:

pr  -t  -m   file1  file2

mardi 22 mai 2012

deal with array in csh/tcsh

In the shell enviroment of tcsh, I have a variable $zz which is an array:

---echo $zz
la1_22066 la1_22073 la1_22080 la1_22087 la1_22094 la1_22101 la1_22108 la1_22115 la1_22122 la1_22129 la1_22136 la1_22143 la1_22150 la1_22157

--- to get the first element in the array: echo $zz[1]
--- to get the last element in the array:  echo $zz[$#zz]  (in csh perhaps it works also with echo $zz[$])
--- to get all the elements in the array:  echo $zz[*]

sed: remove text between two keywords

If the inputfile contains:

la1_22000
la1_22066
la1_22124
la1_22236
la1_22341
la1_22431
la1_22572

In order to remove the text between two lines which contains the keywords la1_22066 and la1_22431 respectively,

set keyword1 = la1_22066
set keyword2 = la1_22431
sed "s/$keyword1/,/$keyword2/d"    inputfile


Attention: in order to use variables in SED, it is better to use double quote than single quote.


If we have special characters in the keyword, for example, /, what we can do is to add \ before it, such that the system can identify this special character.

Example: to repalce /aaa with /bbb
set 's/\/aaa/\/bbb/g' inputfile

mercredi 28 mars 2012

concatenate strings in csh

set a = "/home/user"
set b = "ss"
set c = 2.2

The following works:
echo  input$a"/"$b"_tt"$c".txt"
echo  input$a/$b"_tt"$c".txt"
echo  "input$a"/"$b"_tt"$c".txt""
echo  "input"$a"/"$b"_tt"$c".txt"
echo  ""input"$a"/"$b"_tt"$c".txt""


The following does not work:
echo  input$a"/"$b_tt$c".txt"


 Note: to concatenate a variable with a string, the following works:
$variable"string"   or   "$variable"string""
$variable"_string"
$variable"*string"
$variable"/string"   or $variable/string
$variable".string"   or $variable.string


if string is before the variable, then we can omit the double quote often:
string$variable    or "string"$variable
string_$variable  "string_"$variable
string/$variable   "string/"$variable

stderr in csh: how to catch the errors in running csh script

the c-shell is limited to redirect the standard error to a null file. Here is a workaround:


set command =  ls dyd_*
set errors = `sh -c   'ls dyd_*   2> /dev/null'  `
set if_errorexits = `echo $errors | awk '{print length($0)}' `


if ( $if_errorexits == 0) then
     echo "the command does not work"
     exit 1
endif


jeudi 15 mars 2012

test if a string contains a substring

1)
set exist_substring = `echo $string | grep -c $substring`
if ( $exist_substring == 1 ) then
      echo "$substring exists in the $string"
endif



2) ---to test if str exists in $mystring:
echo $mystring | awk '{print index($0, "str")}'" searches the $mystring variable for an occurrence of "str" in the string's value.

if exists, return 1, otherwise 0

mardi 13 mars 2012

add in the end of line, sed

1) in sed, "^" represents the begining of a line, and "$" the end of line, "^$" a blank line

2) if we want to add a string in the end of each line of a text file and save it to a new file:


#!/bin/csh
# find each file starting with "input" and apply the changes
foreach i ( `ls input*` )
    # get the last string in the filename separated by _
    set append = `echo $i | awk '{split($0,a, "_");print a[6]}' `     


    # add _elim_1fois at the end of each line and save it to a new file
    sed    's/$/_elim_1fois/'   $i  >> $i"_elim_1fois_"$append 
   
    sed   's/$/_elim_2fois/'    $i  >> $i"_elim_2fois_"$append


end

mercredi 7 mars 2012

install or update a software in a server

I work in a server and uses the gnuplot for making figures. I found the gnuplot does not work well with some new functions.

First I tried to find out the version of gnuplot in the server.
1) which gnuplot
/usr/bin/gnuplot
2) /usr/bin/gnuplot --version
4.0
 this is an old version and I want to install the new version. Therefore I go to sourceforge http://sourceforge.net/projects/gnuplot/files/gnuplot/4.4.0/ to download the version 4.4,
and put the downloaded file in a temporary directory in my home in the server. Then I tried to install it in the server !

3) To build it:
     ./configure --PREFIX=$HOME/software
Because I do not have permission to install software in/usr/local, I use --PREFIX=$HOME/software  to install it in this path.
     make
6) test it
     make check
7) install it
     make install

8) finally I add an alias in the .bashrc and .tcshrc (and the .tcshrc_profile)
alias gnuplot4="/home/username/software/bin/gnuplot"
add in the .tcshrc (and the .tcshrc_profile)
alias   gnuplot4    home/username/software/bin/gnuplot
I also add the GNUPLOT_PS_DIR in the tcshrc and bashrc.
set GNUPLOT_PS_DIR = /home/username/software/


9) when I try to call a gnuplot program,
gnuplot4    histogram.plt




mardi 6 mars 2012

define the path and name of a file by a double-quote ?

1) In csh, it does not work if we try to save the tt from current directory into a new directory ~/dire1/dire2/ with a new filename  "~/dire1/dire2/aa_temp" as below:

set appendix_name = temp
cat tt  > "~/dire1/dire2/aa_"$appendix_name  (Not work)

The csh can not find the file ~/dire1/dire2/aa_temp !! (No such file or directory)
The same thing happens if we:

ls "~/dir1/dir2"           (Not work)

2) It works if we remove the double quote:
cat tt   >  ~/dire1/dire2/aa_temp   (work !)
ls ~/dir1/dir1

3) it also works if we give the complete path with a double quote:
cat tt >   "/home/user/dire1/dire2/aa_temp"        (work !)
ls   "/home/user/dir1/dir2"  




The double quote defines the string. but this string is not recognized by csh as a proper path/file, if it does not has the complete path.  

vendredi 2 mars 2012

numeric calculation with shell or awk

1) For processing two variables with one number given to each variable

Shell language is usually not used for complex scientific calculation. But sometimes we may will use it to do some simple calculations with text files. What can we do ?

set  a = 1.25E-02
set b = 3.289E-02

There are two ways to calculate numerically with these two variables in the shell language: either use the echo + bc, or the awk.
For example, when we do the addition:
1) echo "$a+$b" | /usr/bin/bc 
2) echo "$a $b" | awk '{print $1+$2}'

For comparisons:
1) echo "$a > 0 &  $b > 0" | /usr/bin/bc
2) echo "$a  $b" | awk '{if ($1 > 0 & $2 > 0) print 1; else print 0}'
3) echo "$a" | awk '{if ($1 > 1 || $1 < -1) print 1; else print 0}'

If we have to do some complicated computation with shell,  the AWK is more accurate than the echo + bc, esp when the data is the the scientific format (eg., 1.236778E-02).


2) For processing the data from different files
---- if want to substract two columns of data which are from two files file1 and file2 respectively:
cat file1   | awk '{column1=$which_column_in_file1; getline <"file2"; print column1 - $which_column_in_file2}'   

exit in shell script

exit 0: finish a task, could logout ! attention.
exit 1: have an error and exit the current code

jeudi 23 février 2012

mardi 21 février 2012

argv and csh

How can we check the number of arguments?

#!/bin/csh
echo There are $#argv arguments
echo First argument is $argv[1], second argument is $argv[2]
echo All of the arguments are $argv[*]

vendredi 17 février 2012

continuation symbol in shell \

starting position index in shell and emacs

Attention: when open a file in emacs, the starting position for a line is 0 , but in shell, the starting position of a string is 1  !!!

jeudi 16 février 2012

flow control in csh


1) 
-----if (expression) simple command
or :
if (expression) then
  ...
else
  ...
endif

2) The switch statement can replace several if ... then statements. For the string given in the switch statement's argument, commands following the casestatement with the matching pattern are executed until the endsw statement. These patterns may contain ? and * to match groups of characters or specific characters.
switch (string)
  case pattern1:
    commands...
    breaksw
  case pattern2:
    commands...
    breaksw
  default:
    commands...
    breaksw
endsw
3) The while statement will enter the loop only if the expression evaluates to true (or non-zero). Once within the loop, the commands within it will continue to execute until the expression evaluates to false (zero).
while (expression)
commands...
end
4) 
The foreach statement takes an array variable and places the contents of each array element into the loop variable for each iteration.
foreach variable (array variable or list)
...
end
The break statement breaks out of the current loop.
break
The continue command returns to the top of the current loop after testing the condition for the loop.
continue
The shift command without arguments will shift the variable, argv down by one element. In other words, argv[2] becomes argv[1] and so forth, withargv[1] being discarded. With an array variable argument, the shift command performs the same operation on the variable specified.
shift

shift variable

Conditional expressions

The expressions used in the while and if commands are similar to C language expressions, with these exceptions:
=~
If the right hand side matches a pattern, (i.e., similar to filename matching, with asterisks and question marks.) the condition is true.
!~
If the right hand side doesn't match a pattern, the condition is true.
-d $var
True if the file is a directory.
-e $var
True if the file exists.
-f $var
True if the file is a file. (I.e., not a directory)
-o $var
True if the file is owned by the user.
-r $var
True if the user has read access.
-w $var
True if the user has write access.
-x $var
True if the user has execute access.
-z $var
True if the file is zero-length.

reading and processing lines in a text file

For a text file with arrays is called toto:


76039011873490122462 2592.624526   6407821.687553863   3 0.2461  0.0002892 9667 74    1  10 5320
76039011873490122462 2708.024084   6277975.529578525   3 0.2461  0.0002892 9667 74    2  10 5320
76039011873490122462 2835.623772   6179282.694306660   3 0.2461  0.0002892 9667 74    3  10 5320
76039011873490122462 2916.223642   6142426.064870278   3 0.2461  0.0002892 9667 74    4  10 5320
76039011873490122462 3055.424598   6126591.671642607   3 0.2461  0.0002892 9667 74    5  10 5320
76039011873490122462 3186.624722   6167350.779549360   3 0.2461  0.0002892 9667 74    6  10 5320

1) if we want to read the file:
set file = ` awk '{print $0}'  toto `

2) if we want to make some actions to each row, then

set num_lines =  `cat toto | wc -l`
@ j  = 1
while ( $j  <= $num_lines)
     set eachline =  `awk -v ln=$j   '{if (NR==ln) print $0}'  toto`
     more actions to eachline
     @ j += 1
end


Attention: with foreach, we can find each element in each row, but not to get a complete line !
foreach tt ( `cat toto `)
     set eachelement = $tt
end


3) to get a column of data, ie., column 4,

cat toto   |   awk  '{print $4}'

mercredi 15 février 2012

csh common errors

1) Missing -  :
check if a variable misses the symbol $ when we use it

2) Unmatched ` .  :
we have forgot to complete the symbol `  with another `

3) VaraibleName: Undefined variable  :
The variable is not defined yet