Wednesday, February 25, 2004

Emacs & XEmacs Guide

GNU Emacs is a free, portable, self-documenting, customizable, extensible and real-time text editor, Emacs was originally written by Richard Stallman, the founder of the GNU Project, and James Gosling, the creator of the Java language. XEmacs has evolved from the original Emacs, with more GUI and content-based formatting support. For the user-friendly interface reason, I stick to Xemacs all the time.

I found Xemacs was not convenient to use at the beginning, since I was used to the vi and it's shortcuts. However, when I became more experienced I found Xemacs much powerful than vi in most aspects. (X)Emacs is the monster of all editors! It is more than just a text editor. It is a huge and complete system for development, communications, file management, and things you wouldn't even imagine. I only know a very limit features of Xemacs.

Vi (vim) and Emacs (Xemacs) have a very different look and feel, but that's not a real reason for choosing one over the other. Vi is much smaller and loads much faster, while Xemacs is a powerful tool for complex files and software development. They were designed for different jobs, they are better at different things, and I use both of them depending on the job.

Xemacs automatically saves the files you are editing by default. The name of the autosave file is the same as the name of the file you are editing, with a sharp (#) added to the beginning and to the end. When you do a file save, Xemacs creates a backup file of name with a tilde (~) added to the end. When Xemacs starts up, it reads the file ~/.emacs or ~/.xemacs/init.el to customize the Xemacs. You could modify this file by your favorite with Lisp format, e.g. if you like your Xemacs working as a pure txt editor, add the following in the .emacs file:

(setq default-major-mode 'text-mode)
(add-hook 'text-mode-hook 'turn-on-auto-fill)
(setq-default transient-mark-mode t)

There are several basic concepts (environment) of Xemacs: file, buffer, window, frame, echo area (mini-buffer) and mode line. When you are editing a file on disk, Xemacs read a copy of it to initialize a buffer and write a copy of a buffer out to a file to save it; a buffer is the basic editing unit hoding the text you actually edit. You can have multiple buffers but can only edit one buffer at a time; A window is the view of a buffer while frame is the whole screen of Xemacs with all buttons at the top. You could loosely call frames as windows; the echo area is the area at the very bottom of the XEmacs screen and is used to interact with you; the mode line is above the echo area on the XEmacs screen, showing the status and what is happening in the current window.

Some tips about Xemacs:

  • without X server, "Xemacs -nw" (no window mode) will open in the terminal, "Ctrl-z" switch back to the shell and type "fg" to go back Xemacs
  • command-handling "M-x" or "Alt-x" is not available in some cases, use "Esc x" instead
  • using tab or hitting space half will try to complete the command automatically
  • "M-x indent-buffer (indent-region)" will indent the buffer (region) contents
  • "M-x set-variable RET c-basic-offset RET " can set the indent value
  • a simple .emacs file with c/c++ style setting and my simpler .emacs file
  • remote access by Ange-ftp & EFS (Emacs File System):
    Ctrl-x d RET /huang@gate.csd.ca:source/mpi.cc RET
    Ctrl-x d RET /gaul.csd.uwo.ca: RET
  • remote access by Tramp (Transparent Remote Access, Multiprotocols):
    C-x d RET /[huang@gate.csd.ca]/csd/grad/huang RET
    C-x d RET /[ssh/greatwhite.sharcnet.ca]/ RET

You can do most jobs from the menus of Xemacs. But the more efficient way for editing is using shortcuts. Below are some most commonly used commands or keystrokes:



























































































































































































































Mode




Keystroke & command




Description




basic




Ctrl-x Ctrl-f




open a file




Ctrl-x d




DirEditting mode, identical to Alt-x dired




Ctrl-x Ctrl-c




quit a file and the Xemacs




Ctrl-x Ctrl-s




save a file




Ctrl-x Ctrl-w




write to a new file




Ctrl-x Ctrl-h




get help




Ctrl-h f (i, t, k, v)




get help for functions (info, tutorial, key variables, etc..)




Alt-x speedbar




pop up a speedbar




Alt-x shell (term)




switch to a shell (terminal)




buffer & window




Ctrl-x Ctrl-b




list buffers




Ctrl-x o




switch to a buffer




Ctrl-x k




kill a buffer




Ctrl-x 3




split the window vertically




Ctrl-x 2




split the window horizontally




Ctrl-x 1




make into one window




motion




Ctrl-v




Page down




Alt-v




Page up




Ctrl-p (n)




move to Previous (Next) line




Ctrl-a (e)




move to the start (end) of the line




Ctrl-f (b)




move Forward (Backward) one character




Alt-<(>)




move to the beginning (end) of the frame




Alt-x goto-line




go to certain line




editing




Ctrl-g




abort (quit) current command




Ctrl-x u




undo




Ctrl-_




more convenient undo




Ctrl-Space (Ctrl-@)




set a mark




Ctrl-x h




select the whole frame




Ctrl-w




cut the selected area




Esc w




copy to where the mark ends




Ctrl-y




yank (paste) back whatever you copied




Ctrl-d




kill one character




Ctrl-k




kill to the end of the line




Ctrl-a Ctrl-k Ctrl-k




kill an entire line




Ctrl-u 3 Ctrl-k (d)




kill the next three lines (characters)




search & replace




Ctrl-s




search




Ctrl-r




search backwards




Esc %




begin a search and replace




!




replace all occurrences at once




Space




replace




n




skip the replace




Esc




stop the search and replace




Esc Ctrl-c




continue with the search and replace




mode




Alt-x text-mode




text-mode




Alt-x c-mode


(c++, java, tex...)




programming mode




Alt-x makefile-mode Enter




makefile mode




Alt-x overwrite-mode Enter




overwrite mode




Alt-x font-lock-mode




activate color highlighting




Alt-x auto-fill-mode




auto wrapping




Alt-x auto-save-mode




auto save




Alt-x blink-cursor-mode




blinking cursor



Saturday, February 21, 2004

Vi & Vim Guide

Vi is a small, fast and efficient text editor that is installed by default in almost any Unix or Linux system, and Vim (Vi IMproved) is an enhanced version of vi. Most people find vi somewhat hard to learn at first, but it enables fast, simple and effective editing once you get used to it. I got hooked to vi when I first worked with Sun Sparc10 workstation in 1995. Vi is extremely powerful in moving around files without touching any arrow keys. Vi operates in three modes: command mode (colon prompt), insert mode and default mode. For insert mode, press ESC and type colon to switch to command mode. Vi works in default mode after ESC is pressed in all modes (without input colon). In default mode, we are able to move around in the file, switch to insert mode or command mode.

Follow is the vi/vim commands I most use:

























































































































































































Command


Mode


Description







vi filename
default


start editing a file
:wq command


write to disk and quit ( equal to :x)
:q! command


quit without saving any changes
:e! command recover to the original without any changes
:!command command execute a command; :!sh fork a shell, Ctrl-d
to exit






h; l; k; j
default one space to the left, right; one line up,
down respectively
^; $ default the beginning or end of current line
w; e default the beginning or end of next word
Ctrl-b; Ctrl-f default one page up (backward) or down
(forward)
:number command move line with the number
Ctrl-L command clear and redraw the screen
G default move to the end of file
/string; n default search string and repeat search (next)
a; A default append from next letter or the end of current
line
i; I default insert from current position or the beginning
of current line
o; O default open new line down or up of current line
x default delete single character; 5x deletes 5
characters
dw; dd default delete word or linde; 5dw deletes 5 words and
5dd deletes 5 lines
yy default yank (copy) into buffer; 5yy copies 5 lines
into buffer
p; P default paste buffer to next or previous line
u; U default undo last change or restore the current line
:set num; :set nonum command turn on or off line numbering
:set ic; set noic command ignore (or not ignore) case when searching
ma; :'a; y'a; d'a default

command
set marker 'a' (could be 'a' to 'z') to the
current position, go to marker 'a', copy text from current position to
marker 'a' into buffer, delete text from current position to marker 'a'
:%g/^#/d;


:%s/^#//g
command delete all comment lines or uncomment all the
comment lines
:[10-20]g/hello/d;


:[10-20]v/hello/d
command delete all lines containing (or not
containing) text "hello" from line 10 to 20
:i,jd;


:'a,'bd
command delete text from line i to j or from marker
'a' to marker 'b' inclusively
:i,js/old text/new text/g command substitute "new text" for "old text" from
line i to j






:'a,'bs/old text/new text/g





command substitute texts from marker 'a' to marker
'b'
:25,30m50;



'a,'bm50;


25,30co50
command move lines 25-30 to a new position after line
50; move the text between markers to line after 50; copy lines 25-30 to
line after 50

Thursday, February 19, 2004

Commonly Used Unix/Linux Tools and Commands

















































Browserlynx, mozilla, konqueror,
nautilus
Emailpine, mutt, kmail, gnus, balsa
Download(s)ftp, wget, kget, downloader for
X
Editorpico, vi, (x)emacs, ginf(html),
kite(latex), kate
Zipzip, unzip, gzip, zcat, bzip2,
tar
PS/PDFenscript, dvips, ps2pdf, pdf2ps,
a2ps, ps2epsi, xpdf, gs, gv, ggv
Image/Graphicxv, xfig, dia, gimp, gnuplot
Instant messengerlicq, amsn, gaim
Mutimediampg123, xmms, mplayer, toaster
Office suiteabiword, kword, koffice,
openoffice
IDEglade, motor, eclipse

















































































































































































































































































Command Command line
with arguments

Description

a2ps
% a2ps input -R -B
--right-footer='%s./%s#' -o output.ps

% a2ps -r --columns=1 -B -f10 --border=no -MLetter
--pretty-print=plain -o output.ps input
arguments: -r landscape (-R
for portrait), one column per page (default is 2), -B no
header , -f10 font size, --border=no no border, -MLetter
paper size to Letter, --pretty-print=plain print mode
turning off the highlights of keywords.
% a2ps input -2 -B
--right-footer='%s./%s#' ---footer='cenfooter'
-header='test' --cen='report' -o output.ps
more arguments: $Q = Page
$p./$p# (page number for this file), %Q = Page %p./%p#
(current page number), %s. (current sheet number), %s#
(total number of sheets), $s# (number of sheets of the
current file)
% a2ps $1 --columns=2
--pretty-print=$2 --font-size=8 --header='ID: 12345' -o
$3

% a2ps typescript -2 -B --right-footer='%s./%s#'
--footer='ID: 12345' --header='Asn 1' --cen='Captured
result' -o output.ps

% a2ps main.cpp -B -R --columns=1
--right-footer='%s./%s#' --left-footer='ID: 12345'
--header='Asn 1' --cen='main.cpp' -o main.ps
different output
format

ar
% ar rs liblprint.a
lprint1.o lprint2.o lprint3.o
creat a static library
with several object files
% ar -t
/usr/lib/libm.a
show the library object
dependency of libm.a
% ar -d liblprint.a
lprint3.o

% ar -s = ranlib
delete the module
awk % ls -aRl | awk '{sum =
sum + $5} END {print sum}'
sum up and print out
the file sizes

bzcat
% bzcat
prog-2.0.patch.bz2 | patch -p0
Unzip the bzip2 file
and do the patching
cat % cat file | tr -cd b |
wc -m
count the number of "b"
in the file
% cat id.pub | ssh
huang@csd.uwo.ca "(mkdir .ssh; cd .ssh; cat>>
auth)"

% cat file | ssh host "cat >> file"
ssh could be "rsh" or
"rlogin"
cb % cb -s test.cc >
test1.cc
indent code
according to K&R style (same as indent)
% cb -j test.cc put split lines back
together

chmod
% chmod -R 755
{zhu,wu,liang}/Asn1/docs/*

% chmod -R 755 [a-k]*/Asn2/*
change the
dir/subdir's permission

col
% man find | col -b
> find.txt
output a man page
into a plain text file

crypt
% crypt key <
plaintext > encrypted

% crypt key < encrypted > plaintext
Unix command,
Linux's crypt(encrypt) is a function call

diff
% diff -Nur
prog-1.0 prog-2.0 > prog-2.0.patch

% patch -p0 < prog-2.0.patch
Make a patch

dig
% dig
@ns1.uwo.ca genome1.beowulf.uwo.ca

%
dig -x
129.100.171.47

nslookup
find % find / -name
abc -print > result 2> errout

% find / -name abc -print 2>&1
1> logfile
B shell
% (find /
-name abc -print > result) >&
errout

% find / -name abc -print >&
logfile
C
shell
% find /
-type f \( -perm -2 -o -perm -20 \)
-exec ls -lg {} \; > files-results

% find / -type d \( -perm
u=rwx,g=rx,o=rx \) -exec ls -ldg {}
\; >dir-results
find the
files or directories with specific
permission
% find
[v-z]*/A*3/ -user wang -exec rm -f
{} \;
delete
all files created by user "wang" in
the directory between "v*" to "z*",
subdir of Asn3
% find
$HOME \( -name a.out -o -name '*.o'
\) -atime +7 -ok rm {} \;
remove
all files named a.out or *.o that
have not been accessed for a week,
need to confirm for each
execution
% find .
\( -type f -a -size -10k \)
-ok exec cp {} ~/tmp/ \;
copy
small size regular files to a
directory

% for i
in `find / -name *.[ch]`; do grep
-H jiffy $i; done


find
all files with defined string. -H
prints the filename for each
match

finger % finger
@hostname
show
users' info ( some versions need a
"*" before "@")
% finger
-f | awk '{print $1}

% finger -q -f | awk '{print
"User", $1, "is logged in on TTY:",
$2}'
print
out the login users with desired
format


gcc

% gcc
-o math math.c -lm

link
the shared libary
(libm.so)


% gcc
-o math math.c -lm
--static



static link. all code of libm.a
is merged into your distributed
executable

% gcc
-E test.c > test.i
turn
off compilation phase and display
the preprocess info
% gcc
-DBUFFERSIZE=1024
-D"max(A,B)=((A)>(B)?(A):(B))"
test.c

define the constant and
macro
grep %
grep -r string rc.d/
find
string in all files in rc.d
dir/subdir recursively, the same
as "-d"
% grep
-i '^\(.\).*\1$' file
all
lines whose first letter is the
same as the last one regardless
of the case (-i =-y)
gunzip %
gunzip [-q] < file.tar.gz |
tar xvf -
the
same as Linux's "tar zxvf
file.tar.gz"
indent %
indent -bad/-st/-kr/ test.c >
newformat.c

beautify the code with different
format as cb does
kill % kill
-9 -1
Kill
all processes in the login
machine
ls % ls
-aul

access tme
lsof % lsof
| nl

% lsof -u huang
list
all open files (by specified
user)
%
lsof -i -nP | grep ssh

% lsof -i :5000

% lsof -i :smtp

% lsof -i @hotmail.com

List all open files associated
with Internet connections
%
lsof /dev/cdrom

% lsof +D /tmp

% lsof `which sendmail`

% lsof -t `which
sendmail`

Who are using these
files?


netstat


% netstat -rn
routing
table

% netstat -alp
connection
statistics

nl

% nl -ba message.log | tail
-30 | grep error
print the
message having error in the
last 30 lines of the log
file
nm
% nm -a prog

% nm -s prog
list all the
symbols of the object
file
% nm -o
/lib/* /usr/lib/*
/usr/lib/*/*
/usr/local/lib/*
2>/dev/null | grep
'atoll'
search the
libraries for the
function
% nm -ng
prog
show
external symbols and
sorted by addresses

nohup
% nohup find
/ -name abc -print >
result 2>/dev/null
&
continue
finding after logout

ps
% ps
-efww
full format
(Linux)
% /usr/bin/ps
-axf
pstree plus
ps (Linux)

rcp
% rcp
brown:hb/\* .
the same as
"scp brown:hb/* .". rcp
needs .rhosts in remote
hosts:

snm.szptt.net.cn
huang

java huang

rusers


% rusers -l
hostname
show all
users in the host
% rusers
-a
show all
host names in the
network

sed
% cat file
| sed 's/^#/;/g' >
newfile
change
comments format (shell
to lisp)
% ls *htm |
sed 's/\(.*\)htm/mv
& \1html/' |
sh
change the
extension
% sed -e
's/\(\<[A-Za-z]*[aeiou][A-Za-z]*[aeiou][A-Za-z]*\>\)/(\1)/g'
file
surround
all words containing 2+
or vowels with (),
"tea"-->"(tea)"
(<> match
words)

sh
% sh -xv
shell_script
debug the
bsh script program
(csh: % csh -xv)

tar
% tar tvf
file.tar
show all
the files in a tar
file
% tar rvf
my.tar newdir
append
files in newdir to
my.tar
% tar uvf
my.tar mydir
update
my.tar with newly
updated files in
mydir
% tar cvf -
file | gzip >
file.tar.gz
the same
as linux's "tar cvfz
file.tar.gz file"
% (cd
~huang/target; tar -xvf
- .) | (cd
~huang/backup; tar -xvf
-)

% (cd ~/target; tar
cf - .) | rsh casky "cd
~/backup; tar xf -"
backup the
files in remote
machine
tr % tr -d
"\015" < input
> ouput
remove
the ugly ending char
in text files ftped
from windows to Unix,
the same as
"dos2unix"
% cat
a.txt | cat abc
| tr '[a-zA-Z]'
'[n-za-mN-ZA-M]' >
encrypted.txt

% cat
a-encrypted.txt | tr
'[a-zA-Z]'
'[n-za-mN-ZA-M]' >
decrypted.txt
the
easiest way of
encryption

uuencode
%
uuencode a.out key
> secret.out

% uudecode
secret.out
"key"
is a decode
label

wget
%
wget -r -l 4 -np
-N
http://www.abc.com

% wget -c -L
-nH
http://www.abc.com/big.zip

% wget
--passive-ftp
ftp://abc.com/d*/*.doc

download the
contents of the
website,
recursively (-r)
with depth 4 (-l
4), page
requisite mode
(-p), not ascend
the parent
directory (-np),
enable timestamp
(-N), continue
download the
interrupted file
(-c), only get
files from
relative links
(-L), disable
long header
(-nH).
%
wget -E -k -K
-p
http://www.abc.com

% wget -r
-H -l inf
--ignore-length
-p -e
robots=off
http://www.abc.com

% wget
--http-user=huang
--http-passwd=abc
--cache=off
--cookies=off
http://www/secret

html-extension
mode (-E) is
useful for asp
and cgi pages,
link-convert
(-k) and backup
the original
version (-K,
affects -N),
enable
span-host (-H),
ignore the
bogus
"Content-Length"
headers by CGIs
(--ignore-length),
turn off the
robots
mechanism(-e
)
%
wget
--save-cookies
cookies.txt
--post-data
'user=foo&password=*'
http://www.abc.com/auth.php

% wget
--load-cookies
cookies.txt
-p
http://www.abc.com/doc/article.php

llogin to the
server and
save the
cookie file (
done only
once), then
grab the
desired
pages

who

%who -u |
sort +0 -1
-u

display the
login users
without
repeat
names

%who -u |
cut -c1-10
| sort |
uniq -c |
grep -v " 1
"

display the
users
having more
than on
terminals

xterm

% xterm +ls
-sb
-rightbar
-sl 1000 -j
-title
"dreamer"
-fn
"*-courier-bold-r-*-140-*"
-b 5
-display
0:0 -bg
black -fg
green
-geometry
80x50+10+5
&



open an
xterm with
pure
subshell
(+ls) mode,
scrollbar
(-sb) with
1000 lines
(-sl) in
the right
side
(-rightbar),
jump
scrolling
(-j), font
defined
(-fn),
black
background
(-bg) and
green
foreground
(-fg), 80
characters
per line,
50 lines,
ordinate
(10, 5)
from
upper-left
corner.
( -10-5
means x
ordinate of
10 from the
right,
y ordinate
of 5 from
the
bottom)


Monday, February 09, 2004

A Java Utility for IBM Crosspad Devices

I've been doing some research on digital inks. IBM's CrossPad was one of the devices we used to collect people's writing. But there's no out of box tool to view and manipulate the collected writing.

So I wrote a Java GUI application for such purpose. It would be handy if you are also working on the same area. The source code can be downloaded here.
Screen-shot:

Friday, February 06, 2004

Unix/Linux Shell Scripts

Shell scripts are very powerful to solve some problems in Unix systems. Among bsh, csh and ksh, Bourne shell is the most commonly used one in the system job handling.

A brief summary of test operators in shell programming:
[ -d name ] true if name is a directory and exists
[ -f name ] true if name is a file and exists
[ -s name ] true if name is an existing, not empty file
[ -r name ] true if name is a readable file (read access)
[ -w name ] true if name is a writeable file (write access)
[ -x name ] true if name is an executable file (execute access)
[ -z name ] true if name has zero length
[ -n name ] true if name has non zero length
[ string ] true if string is not empty
[ name1 = name2 ] true if string name1 and name2 are equal
[ name1 != name2 ] opposite of =
[-d dir1 -a -f prog] -a: "and" (logical "and") -o: " or " (logical "or")
[ ! -f name ] true, if file name does not exist
[ num1 -eq num2 ] true if number num1 and num2 are equal
[ num1 -neq num2 ] true if number num1 and num2 are not equal
[ num1 -lt num2 ] true if number num1 is less than number num2
[ num1 -gt num2 ] true if number num1 is greater than number num2
[ num1 -ge num2 ] true if number num1 is greater than or equal to num2
[ num1 -le num2 ] true if number num1 is less than or equal to num2

Following are some examples:

1. Check your system's info and print the shells available in your system:
#!/bin/sh
# check your system's info and which shells are available
echo "The machine information: `uname -s` version `uname -r`"
for x in sh bsh bash csh tcsh ksh zsh; do
test -x /bin/$x && shells="$shells $x"
done
echo "The following shells are available in the system: $shells"
2. Check whether the input names are executable files from your searching path:
#!/bin/sh
# check whether the input names are executable files from your searching path
# if so, print the whole path of them
mypath=`echo $PATH | tr ':' ' ' `

for filename in $*; do
for apath in $mypath ;do
if [ -x $apath/$filename ]; then
echo $apath/$filename
fi
done
done | while read finded; do
ls -l $finded
done
3. Print shell command arguments in reverse order:
#!/bin/sh
# Print all the arguments reversely

inputString=""
for i in $*
do
inputString="$i $inputString"
done
echo "The reverse arguements you typed are:"
echo $inputString
exit
4. Menu switch:
#!/bin/sh
# interpret the input

echo "Enter a command (list/user/disk/quit/Quit):"
while read cmd
do
case "$cmd" in
list) ls -al ;;
user) who -l ;;
disk) df . ;;
quit|Quit) break ;;
*) echo "$cmd: No such command" ;;
esac
done
echo "All done"
5. Calculate the factorial of a number n!=n*(n-1)!
#!/bin/sh
#calculate the factorial of a number n!=n*(n-1)!

if [ $# -eq 0 ]; then
echo " Usage: factor.sh number"
exit 1
elif [ $# -gt 1 ]; then
echo " Too many arguments"
exit 1
fi

COUNT=0
VALUE=1
while [ $COUNT -lt $1 ]; do
COUNT=`expr $COUNT + 1`
VALUE=`expr $VALUE \* $COUNT`
done

#display the results
echo "The factorial of $1 is $VALUE"
6. Check whether the input words are existing in a given file:
#!/bin/sh
#check if the input are valid words in a specified dictionary
if [ $# -lt 2 ]; then
echo " Usage: check-word.sh dictionary-file word1 word2 ..."
exit 1
fi

COUNT=1
TARGET=$1
shift
for WORD in $*; do
echo -n "$COUNT : "
COUNT=`expr $COUNT + 1`
echo -n "Word $WORD "
CHECK=`eval "grep -w $WORD $TARGET | wc -l"`
if [ $CHECK -eq 0 ]; then
echo "is not found in $TARGET !"
else
echo "is found in $TARGET !"
fi
done
7. Check whether the input names are executable files from your searching path:
#!/bin/sh
# check whether the input names are executable files from your searching path
# if so, print the whole path of them

mypath=`echo $PATH | tr ':' ' ' `

for filename in $*; do
for apath in $mypath ;do
if [ -x $apath/$filename ]; then
echo $apath/$filename
fi
done
done | while read finded; do
ls -l $finded
done
8. Check mail status and display mail headers for new and unread mails:
#!/bin/csh
# check mail status and display mail headers for new and unread mail

set maildir="/var/mail"

if (-e $maildir/$USER.lock == 0) then
if ((-e $maildir/$USER != 0) && (-z $maildir/$USER == 0)) then
mailx -H | awk 'BEGIN { c = 0 } { if (($1 ~ /N/) || ($1 ~ /U/)) {print $0; c = 1} } \
END { if (c == 0) print "no new mail" }'
else
echo ' No mail for '$USER
endif
else
echo ' Your mailbox is locked'
endif
9. Change files' permission in directories and their subdirectories:
#!/bin/sh
# Change the permissions of all files in directories including subtree.
# Use command "find" to print all files(directories) in a path or paths.
# Pipe each file(directory) name to input function "read".
# Then use the script of question1 to change the permission.
# Select one or more directories to change.
# Function current path if without argument.

if [ $1 = ? ] || [ ! -d $1 ]
then echo " Usage: ch-perm.sh [path1] [path2] ... "
exit
fi

# If no argument then set path to current directork
path=${*:-.}

find $path -depth -print | while read file
do
if [ -d $file ]; then
chmod 711 $file
elif [ -x $file ]; then
chmod 755 $file
else chmod 644 $file
fi
done

echo " Job was done successfully!"
exit
10. A recursive version to do the above task:
#!/bin/sh
# set the permissions: directories 711, excutable files 755, else 644.
# [ -n "not_empty_string"]; [ -e "exist_file" ];
# [ -f "regular_file" ]; [ -L "symbol_link" ]

dir=`pwd`
command=$0
echo "Directory: $dir Command: $command"

for file in *
do
if [ -d $file ]
then
echo "directory: $file "
chmod 711 $file
cd $file
$dir/$command
echo "now directory is : `pwd` "
cd ..
elif [ -x $file ]
then
echo "excutable file: $file "
chmod 755 $file
else
echo "regular file: $file "
chmod 644 $file
fi
done

echo " Job was done successfully!"
exit