echo $SHELL echo $shell
echo Multiply is signified by the * symbol will be Multiply is signified by the file_list symbolwhere file_list will be all the filenames in the current directory.
string=hello there how are you echo $string will be helloThe shell variable is assigned only the first word. The shell interprets the space after hello as separating out a command and ignores the rest of the arguments. Using quote characters as follows would have solved the problem
string="hello there how are you"
#!/bin/sh echo The current directory is `pwd` and it contains `ls`
#!/bin/sh echo $0 accepted $# command line arguments echo they were $*$0 should be used here as it allows the shell procedure to be renamed and it will still work as specified.
#!/bin/sh if [ $# -eq 0 ] then echo No parameters were passed. exit 1 fi echo $0 accepted $# command line arguments echo they were $*
#!/bin/sh if [ $# -eq 0 ] then echo usage: $0 filename echo $0 will test to see if filename exists exit 1 fi if [ -f $1 ] then echo The file $1 exists. else echo The file $1 does not exist. fi
#!/bin/sh if [ $# -eq 0 ] then echo usage: $0 filename echo $0 will test to see if filename exists exit 1 fi for filename in $* do if [ -f $filename ] then echo The file $filename exists. else echo The file $filename does not exist. fi done
#!/bin/sh if [ $# -eq 0 ] then echo USAGE: $0 list_of_filenames echo $0 will return what type of files they are exit 1 fi file_type() { if [ -d $1 ] then type=directory elif [ -h $1 ] then type="symbolic link" elif [ -c $1 ] then type="character device file" elif [ -b $1 ] then type="block device file" elif [ -p $1 ] then type="named pipe" elif [ -f $1 ] then type="normal file" else type="something very unusual" fi } for filename in $* do file_type $filename echo $filename is a $type done
#!/bin/bash ok() { echo -n '(y,n) ==> ' read response # put the response into uppercase # it makes the comparison easier response=`echo $response | tr [a-Z] [A-Z]` case $response in N | NO) ;; Y | YES) ;; *) response=ERROR;; esac } ok echo $response
#!/usr/local/bin/bash while read num1 num2 do echo $num1 + $num2 = `expr $num1 + $num2` >> totals done < amounts
#!/usr/local/bin/bash trap "echo $0 received signal 15" 15 while [ 0 -eq 0 ] do # do nothing useful echo > /dev/null done
awk 'BEGIN { FS=":" } { total=$3+$4 printf "%s, %s %3d/n", $1, $2, total }' results.dat
#!/usr/local/bin/bash if [ $# -eq 0 ] then echo Usage: $0 group_id echo $0 will return a list of users belonging to the group id exit 1 fi for group in $* do awk 'BEGIN { FS=":" count=0 } /.*:.*:.*:'$group':/{ print $1 count++ } END { if ( count !=0 ) printf "Group '$group' has %d users\n", count else printf "Group '$group' has no users\n" }' /etc/passwd done
This defines an alias temp. All mail sent to temp will actually be forwarded to the account with the username david.
Add the following to your .profile (if you are using a Bourne shell derivative) or to your .login (if you using a C shell derivative).
echo Logged in `date` > $HOME/account.usageAdd the following to your .logout
echo Logged out `date` > $HOME/account.usage
#!/usr/local/bin/bash # # FILE: create_mail # PURPOSE: Create a new mail file for a user with # correct permissions. Login name is first # parameter # AUTHOR: David Jones # HISTORY: 18/9/94 Created # MAIL_DIR=/usr/spool/mail # check to see parameter passed in if [ "$1" = "" ] then echo 'ERROR: expecting login name as first parameter' exit 1 fi # check to see if file already exists if [ -r $MAIL_DIR/$1 ] then echo 'ERROR: mail file already exists' exit 2 fi # create the file touch $MAIL_DIR/$1 chown $1 $MAIL_DIR/$1 chgrp mail $MAIL_DIR/$1 chmod 660 $MAIL_DIR/$1
#!/usr/local/bin/bash # # FILE: get_uid.sh # PURPOSE: Using commands other than awk obtain # the next free UID number from the # /etc/passwd file # AUTHOR: David Jones # HISTORY: 18/9/94 Created # getuid() { NEXT_UID=`sort -t: -n +2 -3 /etc/passwd | cut -d: -f3 | tail -1` NEXT_UID=`expr $NEXT_UID + 1` } getuid echo $NEXT_UIDThere is a problem with the above solution in how it picks the UID. The question asked for the next free UID but in most cases what you really want here is the next free UID between a certain upper and lower value. For example, on my machine aldur there is a predefined user nobody with a UID of 60000 so the above solution will return a number greater than that leaving about 59000 free UIDs below it. Also as mentioned in the section it is often a good idea to leave UIDs less than 100 to the system users. However on a number of systems there are not 100 system users to start with.
The following solution using awk includes a specification of a lower and upper bound for the UID.
#!/usr/local/bin/bash # # FILE: get_uid.awk # PURPOSE: Using awk obtain the next free UID # number from the /etc/passwd file # AUTHOR: David Jones # HISTORY: 18/9/94 Created # # next uid must be > LOWER and < GREATER LOWER_UID=100 UPPER_UID=60000 getuid() { awk 'BEGIN { FS=":" UID=0 } { if (($3>UID) && ($3>'$LOWER_UID') && ($3<'$UPPER_UID')) UID=$3 } END { printf "%d\n", UID }' < /etc/passwd > /tmp/get_uid.$$ NEXT_UID=`cat /tmp/get_uid.$$` NEXT_UID=`expr $NEXT_UID + 1` rm /tmp/get_uid.$$ } getuid echo this is it $NEXT_UID
#!/usr/local/bin/bash # # FILE: make_username # PURPOSE: Accept a firstname and a lastname as # parameters # Convert them into a username # consisting of the # first seven letters of the surname # and the first initial # AUTHOR: David Jones # HISTORY: 18/9/94 Created # # check that we got everything if [ $# -ne 2 ] then echo -n 'ERROR: expecting both firstname and ' echo 'lastname as parameters' exit 1 fi INITIAL=`echo $1 | cut -c1` REST=`echo $2 | cut -c1-7` username=$REST$INITIAL
Terminals not being used will have different permissions. The user becomes owner of the terminal during the login process
Don't forget to use mknod to recreate the device file.
man 2 kill
Tells the system to display the manual page for kill that appears in section two of the manual.
Some systems display the user with a choice of all matching man pages. For example:
bash$ man kill 1 kill(1) kill - terminate a process by default 2 kill(2) kill - send a signal to a process or a group of processes View which man page? (q to quit) [1]
direct blocks = 10 * 512
single indirect = 256 * 512
double indirect = 256 * 256 * 512
triple indirect = 256 * 256 * 256 * 512
The actual total works out to be something in excess of 8 Gigabytes. This is a very large figure, larger than normal. Mainly because on a real system a 512 byte block is not going to be able to contain 256 block pointers. (Under System V a 1K block contains 256 block addresses).
If System V uses 1K blocks that can contain 256 block addresses and the i-node uses the above structure (10 direct blocks and a single, double, triple indirect block) what is the biggest size file System V can handle?
bash$ cd / bash$ ls -i 5422 Mail 159 home 163 proc 8795 UNIX 33 bin 3 lost+found 164 sbin 168 usr 34 dev 161 mnt 166 stand 287 var 48 etc 162 opt 11928 tmp bash$ ls -id / 2 /
The command sync forces the buffers to be flushed straight away. One of the first things that happens when you use umount is that it flushes the buffers.
bash$ cat > $HOME/tmp/temp.dat this is temp.dat8-2.bash$ tar cvf backup.tar $HOME tar is one command where the switches don't need the -.
The above may or may not work depending on whether or not the version of tar you are using automatically makes absolute path names into relative paths (by removing the first /). If it does it will not find any file in the archive starting with a / in the tape archive (which is what the extract command has told it to do). In that case you will have to repeat the command but put in the full relative path for the file you wish to extract.
You should be careful where the file you are attempting to extract will be placed. If you are extracting a using relative path the file will be placed relative to your current directory. If not it will be placed at the absolute location specified by the path.
dd if=temp.tar.old | gzip - > temp.tar.gz
One of the columns displayed by ps will be the controlling terminal. For a process without a controlling terminal some systems will display ?. Working on this premise the following command may workps -ae | grep \?
$ stty -a line = NTTYDISC; speed 9600 baud erase = DEL; kill = ^u; min = 6; time = 1; intr = ^c; quit = ^|; eof = ^d; eol = ^`; start = ^q; stop = ^s; parenb -parodd cs7 -cstopb -hupcl cread -clocal -loblk -ignbrk brkint ignpar -parmrk inpck istrip -inlcr -igncr icrnl -iuclc ixon -ixany -ixoff isig icanon -xcase echo echoe echok -echonl -noflsh opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel $ stty erase \^i change the erase character to control-i $ stty -a line = NTTYDISC; speed 9600 baud erase = ^i; kill = ^u; min = 6; time = 1; intr = ^c; quit = ^|; eof = ^d; eol = ^`; start = ^q; stop = ^s; parenb -parodd cs7 -cstopb -hupcl cread -clocal -loblk -ignbrk brkint ignpar -parmrk inpck istrip -inlcr -igncr icrnl -iuclc ixon -ixany -ixoff isig icanon -xcase echo echoe echok -echonl -noflsh opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel $ d^?^?^? try to use the backspace key three times d: not found $ stty erase ^? change erase back to the backspace key
10-4. Something for you to complete.
10-5. Much the same result can be achieved by changing your current terminal to something completely wrong. If your terminal is currently set up as a vt100 change it to a tvi912b and see how this affects the output of various commands.
10-6. The following is what happens on my system. The reason being is that vi has looked up the system's terminal configuration database looking for myterm. It hasn't found an entry so it doesn't know about any extended capabilities (like how to clear the screen, position a character at a specific location on the screen etc). It then defaults back to what it calls open mode which means no extended features (one line at a time much like ed).
bash$ TERM=myterm bash$ vi /etc/passwd myterm: Unknown terminal type I don't know what kind of terminal you are on - all I have is 'myterm'. [Using open mode]10-7. The following solution is for a system using terminfo. The solution for a system using termcap is to bring the /etc/termcap file into vi and then search for your terminal name (e.g. /vt100).
bash$ echo $TERM vt100 bash$ ls /usr/lib/terminfo/v/vt100 /usr/lib/terminfo/v/vt100 bash$ infocmp -C vt100 # Reconstructed via infocmp from file: /usr/share/lib/terminfo/v/vt100 vt100|vt100-am|dec vt100 (w/advanced video):\ :am:mi:ms:xn:xo:bs:pt:\ :co#80:li#24:\ :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:ae=^O:as=^N:\ :cd=50\E[J:ce=3\E[K:cl=50\E[H\E[J:cm=5\E[%i%d;%dH:\ :cs=\E[%i%d;%dr:ct=\E[3g:ho=\E[H:k0=\EOy:k1=\EOP:\ :k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOt:k6=\EOu:k7=\EOv:\ :k8=\EOl:k9=\EOw:kb=\b:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:nd=2\E[C:\ :r2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:sc=\E7:\ :se=2\E[m:so=2\E[1;7m:sr=5\EM:st=\EH:ue=2\E[m:\ :up=2\E[A:us=2\E[4m:
bash$ arp -a pol.cqu.EDU.AU (138.77.37.28) at aa:0:4:0:b:1c jasper.cqu.EDU.AU (138.77.1.1) at aa:0:4:0:b:1c bash$ ping bertha bertha.ucq.edu.au is alive bash$ arp -a pol.cqu.EDU.AU (138.77.37.28) at aa:0:4:0:b:1c bertha.cqu.EDU.AU (138.77.37.37) at aa:0:4:0:b:1c jasper.cqu.EDU.AU (138.77.1.1) at aa:0:4:0:b:1c12-5. The standard daemons for smtp are usually smtpd or maybe smail (amongst others). They are typically started up in the systems startup files.
telnet jasper 21 Trying 138.77.1.1... Connected to jasper.cqu.edu.au. Escape character is '^]'. 220 jasper.cqu.edu.au FTP server....ready. help ....list of valid commands user anonymous log on as an anonymous user 331 Guest login ok, send your complete e-mail ... pass david@pol send my e-mail address as a password12-7. Any number of uses of the netstat command will answer this. Try -s or refer to your systems manual pages.
12-8. Another for you to discover, try looking at the manual pages.
13-2. The order of hostname and -l username can differ from system to system. On the machine aldur running SysV -l username comes first.
13-5. Most of these daemons will be started by the systems startup files.
13-6. Simplest method is to examine the output of an appropriate ps command and see if any of the daemons mentioned in the section are running. You can also look in the /etc/fstab, /etc/vfstab and /etc/exports files.
13-7. Follow the steps outlined in the section.
13-8. Performing a traceroute that passes through a large number of gateways increases the possibility of two different runs being different. The Internet has the ability to use different routes to get to the same destination.
a) bash$ nslookup Default Server: jasper.cqu.edu.au Address: 138.77.1.1 > ls -a cqu.edu.au [jasper.cqu.edu.au] Host or domain name Alias mailroom janus.cqu.edu.au library onyx.cqu.edu.au civax topaz.cqu.edu.au info janus.cqu.edu.au cq-pan bertha.cqu.edu.au www janus.cqu.edu.au newsroom janus.cqu.edu.au bindmaster jasper.cqu.edu.au b) > ls -h cqu.edu.au > hosts [jasper.ucq.edu.au] ########## Received 545 records. looking at the file hosts revealed 136 hosts c) > server cc.uq.oz.au Default Server: cc.uq.oz.au Address: 130.102.128.5 > www.cc.uq.oz.au Server: cc.uq.oz.au Address: 130.102.128.5 Name: dingo.cc.uq.oz.au Address: 130.102.2.14 Aliases: www.cc.uq.oz.au
#!/usr/local/bin/bash # # FILE: passwdck # PURPOSE: Perform the following checks on the /etc/passwd file # * that all accounts have passwords # * that all accounts have usernames # * only the account root has uid of 0 # * only the proper accounts have gid of 0 # * only additions performed by Sys Admin have been # made. Keeps a copy of /etc/passwd in a protected # file $ROOTDIR/.old.passwd # * file permissions on /etc/passwd haven't been # altered # AUTHOR: David Jones # HISTORY: 2/9/94 Created # PASSWORD_FILE='/etc/passwd' # file containing encrypted passwords PERMISSIONS="-r--r--r--" # permissions for /etc/passwd file ROOTDIR=/root # directory in which .old.password is stored # Check that all accounts have passwords awk -F- '{ FS=":" } { if ( $2=="" ) printf "passwdck: ERROR user %s has no password\n", $1 }' < $PASSWORD_FILE # display user ids for accounts without usernames # display usernames of accounts other than system accounts with uids of 0 awk '{ FS=":" } { if ( $1=="" ) printf "passwdck: ERROR userid %s has no username\n", $3 if ( $3=="0" && $1!="root" && $1!="setup" && $1!="powerdown" && $1!="sysadm" && $1!="checkfsys" && $1!="makefsys" && $1!="mountfsys" && $1!="umountfsys" ) printf "passwdck: ERROR user %s has uid of 0\n", $1 }'< /etc/passwd # check for changes in the password file diff /etc/passwd $ROOTDIR/.old.password > /dev/null if [ $? -ne 0 ] then echo passwdck: ERROR $PASSWORD_FILE has been illegally changed. RETURN=1 fi # check on the permissions for the passwd file if [ ! "`ls -l /etc/passwd | cut -d' ' -f1`" = $PERMISSIONS ] then echo passwdck: ERROR illegal permissions on /etc/passwd fi14-2. The following is a very coarse grained answer to the question.
#!/usr/local/bin/bash # # FILE: fs_check # PURPOSE: Perform the following checks on the security of the # filesystem # AUTHOR: David Jones # HISTORY: 2/9/94 Created # ROOTDIR=/root # directory in which summary files are kept # directories or files to be checked could be placed into a specific file DIRECTORIES='/dev/hda* /etc/passwd' # create filename for new summary file # FORMAT is $ROOTDIR/summary."todays_date" SUMMARY_FILE="$ROOTDIR/summary.`date | cut -d: -f1 | tr ' ' _`" # move previous summary file mv $ROOTDIR/summary* $ROOTDIR/old.summary for directory_name in $DIRECTORIES do ls -lR $directory_name >> $SUMMARY_FILE done diff $ROOTDIR/old.summary $SUMMARY_FILE14-3. The main difference is the addition of the s in the executable fields for the owner and the group. This means that the passwd program is both setuid and setgid.
# which passwd /usr/bin/passwd # ls -l /usr/bin/passwd -r-sr-sr-x 1 root sys 20240 Nov 23 1991 /usr/bin/passwd14-4. Methods exist using symbolic and numeric permissions
chmod 4??? filename set uid chmod 2??? filename set gid Where ??? is replaced with the normal numeric permissions and filename is the name of the file chmod u+s filename set uid chmod g+s filename set gid14-5.
bash$ i_am The real uid is 201 The effective uid is 201 The real gid is 1 The effective gid is 1 # chown root i_am # chmod u+s i_am # ls -l i_am total 80 -rwsr-xr-x 1 root other 5600 Oct 2 19:47 i_am bash$ i_am The real uid is 201 The effective uid is 0 The real gid is 1 The effective gid is 114-6.
# chgrp root i_am # ls -l i_am # chmod g+s i_am total 80 -rwsr-sr-x 1 root root 5600 Oct 2 19:47 i_am bash$ i_am The real uid is 201 The effective uid is 0 The real gid is 1 The effective gid is 014-7. The find command has a switch that can very easily find all the setuid and setgid programs. Add the following to the fs_check program just before the diff command.
find / -perm -4000 -print >> $SUMMARY_FILE find / -perm -2000 -print >> $SUMMARY_FILE
Many systems will divide the different sections into separate directories.
15-2. The following command will give a good indication though it is probably going to pick up a number of object files in addition.
pol:/usr/src/linux# find . -name \* -print | wc -w 1108 pol:/usr/src/linux#15-3. On this particular system the MANPATH variable wasn't set but examining the manual page for the man command revealed that the manual pages (in one format) were stored in the directory /var/share/catman. Under this directory there were a number of directories corresponding to the various different sections of the manual.
Taking a listing of the contents of the correct directory gives a list of the system calls that are documented in the manual pages.
bash$ ls /var/share/catman/2 access.Z getgroups.Z msgop.Z setpgid.Z sys3b.Z acct.Z getmsg.Z munmap.Z setpgrp.Z sysfs.Z adjtime.Z getpid.Z nice.Z setsid.Z sysinfo.Z alarm.Z getrlimit.Z open.Z setuid.Z termios.Z brk.Z getsid.Z pause.Z shmctl.Z time.Z chdir.Z getuid.Z pipe.Z shmget.Z times.Z chmod.Z intro.Z plock.Z shmop.Z uadmin.Z chown.Z ioctl.Z poll.Z sigaction.Z ulimit.Z chroot.Z kill.Z priocntl.Z sigaltstack.Z umask.Z close.Z link.Z priocntlset.Z signal.Z umount.Z creat.Z lseek.Z profil.Z sigpending.Z uname.Z dup.Z memcntl.Z ptrace.Z sigprocmask.Z unlink.Z exec.Z mincore.Z putmsg.Z sigsend.Z ustat.Z exit.Z mkdir.Z read.Z sigsuspend.Z utime.Z fcntl.Z mknod.Z readlink.Z stat.Z vfork.Z fork.Z mmap.Z rename.Z statvfs.Z wait.Z fpathconf.Z mount.Z rmdir.Z stime.Z waitid.Z fsync.Z mprotect.Z semctl.Z swapctl.Z waitpid.Z getcontext.Z msgctl.Z semget.Z symlink.Z write.Z getdents.Z msgget.Z semop.Z sync.Z15-4. to 15-6. Both are system specific tasks read your manual pages.
diff abc.doc def.doc > patch.file patch abc.doc < patch.file > newabc.doc15-8. & 15-9. The process here will depend on your system.
0 7 2,4,6,8,10,12,14,16,18,20,22,24,26,28,30 * * /root/passwdck | mail root On some systems the redirection to the mail command is not necessary as the system automatically sends output of commands run by cron as mail.16-5. & 16-6. Again questions for you to answer on your system but you should be able to follow the steps in the section and the documentation for you system.
16-7. Simply cat /etc/syslog.conf
16-8. *.emerg /dev/console
David Jones (author)