Практические занятия 1-4.




 

#!/bin/bash

# am-i-root.sh: Am I root or not?

 

ROOT_UID=0 # Root has $UID 0.

 

if [ "$UID" -eq "$ROOT_UID" ] # Will the real "root" please stand up?

then

echo "You are root."

else

echo "You are just an ordinary user (but mom loves you just the same)."

fi

 

exit 0

 

 

# ============================================================= #

# Code below will not execute, because the script already exited.

 

# An alternate method of getting to the root of matters:

 

ROOTUSER_NAME=root

 

username=`id -nu` # Or... username=`whoami`

if [ "$username" = "$ROOTUSER_NAME" ]

then

echo "Rooty, toot, toot. You are root."

else

echo "You are just a regular fella."

Fi

#!/bin/bash

 

a=24

b=47

 

if [ "$a" -eq 24 ] && [ "$b" -eq 47 ]

then

echo "Test #1 succeeds."

else

echo "Test #1 fails."

fi

 

# ERROR: if [ "$a" -eq 24 && "$b" -eq 47 ]

#+ attempts to execute ' [ "$a" -eq 24 '

#+ and fails to finding matching ']'.

#

# Note: if [[ $a -eq 24 && $b -eq 24 ]] works.

# The double-bracket if-test is more flexible

#+ than the single-bracket version.

# (The "&&" has a different meaning in line 17 than in line 6.)

# Thanks, Stephane Chazelas, for pointing this out.

 

 

if [ "$a" -eq 98 ] || [ "$b" -eq 47 ]

then

echo "Test #2 succeeds."

else

echo "Test #2 fails."

fi

 

 

# The -a and -o options provide

#+ an alternative compound condition test.

# Thanks to Patrick Callahan for pointing this out.

 

 

if [ "$a" -eq 24 -a "$b" -eq 47 ]

then

echo "Test #3 succeeds."

else

echo "Test #3 fails."

fi

 

 

if [ "$a" -eq 98 -o "$b" -eq 47 ]

then

echo "Test #4 succeeds."

else

echo "Test #4 fails."

fi

 

 

a=rhino

b=crocodile

if [ "$a" = rhino ] && [ "$b" = crocodile ]

then

echo "Test #5 succeeds."

else

echo "Test #5 fails."

fi

 

exit 0

#!/bin/bash

 

echo

 

if test -z "$1"

then

echo "No command-line arguments."

else

echo "First command-line argument is $1."

fi

 

echo

 

if /usr/bin/test -z "$1" # Equivalent to "test" builtin.

# ^^^^^^^^^^^^^ # Specifying full pathname.

then

echo "No command-line arguments."

else

echo "First command-line argument is $1."

fi

 

echo

 

if [ -z "$1" ] # Functionally identical to above code blocks.

# if [ -z "$1" should work, but...

#+ Bash responds to a missing close-bracket with an error message.

then

echo "No command-line arguments."

else

echo "First command-line argument is $1."

fi

 

echo

 

 

if /usr/bin/[ -z "$1" ] # Again, functionally identical to above.

# if /usr/bin/[ -z "$1" # Works, but gives an error message.

# # Note:

# This has been fixed in Bash, version 3.x.

then

echo "No command-line arguments."

else

echo "First command-line argument is $1."

fi

 

echo

 

exit 0

#!/bin/bash

 

a=4

b=5

 

# Here "a" and "b" can be treated either as integers or strings.

# There is some blurring between the arithmetic and string comparisons,

#+ since Bash variables are not strongly typed.

 

# Bash permits integer operations and comparisons on variables

#+ whose value consists of all-integer characters.

# Caution advised, however.

 

echo

 

if [ "$a" -ne "$b" ]

then

echo "$a is not equal to $b"

echo "(arithmetic comparison)"

fi

 

echo

 

if [ "$a"!= "$b" ]

then

echo "$a is not equal to $b."

echo "(string comparison)"

# "4"!= "5"

# ASCII 52!= ASCII 53

fi

 

# In this particular instance, both "-ne" and "!=" work.

 

echo

 

exit 0

#!/bin/bash

# zmore

 

#View gzipped files with 'more'

 

NOARGS=65

NOTFOUND=66

NOTGZIP=67

 

if [ $# -eq 0 ] # same effect as: if [ -z "$1" ]

# $1 can exist, but be empty: zmore "" arg2 arg3

then

echo "Usage: `basename $0` filename" >&2

# Error message to stderr.

exit $NOARGS

# Returns 65 as exit status of script (error code).

fi

 

filename=$1

 

if [! -f "$filename" ] # Quoting $filename allows for possible spaces.

then

echo "File $filename not found!" >&2

# Error message to stderr.

exit $NOTFOUND

fi

 

if [ ${filename##*.}!= "gz" ]

# Using bracket in variable substitution.

then

echo "File $1 is not a gzipped file!"

exit $NOTGZIP

fi

 

zcat $1 | more

 

# Uses the filter 'more.'

# May substitute 'less', if desired.

 

 

exit $? # Script returns exit status of pipe.

# Actually "exit $?" is unnecessary, as the script will, in any case,

# return the exit status of the last command executed.

#!/bin/bash

# shft.sh: Using 'shift' to step through all the positional parameters

 

# Name this script something like shft.sh,

#+ and invoke it with some parameters.

#+ For example:

# sh shft.sh a b c def 23 skidoo

 

until [ -z "$1" ] # Until all parameters used up...

do

echo -n "$1 "

shift

done

 

echo # Extra line feed.

 

exit 0

 

# See also the echo-params.sh script for a "shiftless"

#+ alternative method of stepping through the positional params.

#!/bin/bash

# Listing the planets.

 

for planet in Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto

do

echo $planet # Each planet on a separate line.

done

 

echo

 

for planet in "Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto"

# All planets on same line.

# Entire 'list' enclosed in quotes creates a single variable.

# Why? Whitespace incorporated into the variable.

do

echo $planet

done

 

exit 0

#!/bin/bash

# Planets revisited.

 

# Associate the name of each planet with its distance from the sun.

 

for planet in "Mercury 36" "Venus 67" "Earth 93" "Mars 142" "Jupiter 483"

do

set -- $planet # Parses variable "planet"

#+ and sets positional parameters.

# The "--" prevents nasty surprises if $planet is null or

#+ begins with a dash.

 

# May need to save original positional parameters,

#+ since they get overwritten.

# One way of doing this is to use an array,

# original_params=("$@")

 

echo "$1 $2,000,000 miles from the sun"

#-------two tabs---concatenate zeroes onto parameter $2

done

 

# (Thanks, S.C., for additional clarification.)

 

exit 0

#!/bin/bash

 

# Invoke this script both with and without arguments,

#+ and see what happens.

 

for a

do

echo -n "$a "

done

 

# The 'in list' missing, therefore the loop operates on '$@'

#+ (command-line argument list, including whitespace).

 

echo

 

exit 0

#!/bin/bash

 

var0=0

LIMIT=10

 

while [ "$var0" -lt "$LIMIT" ]

# ^ ^

# Spaces, because these are "test-brackets"...

do

echo -n "$var0 " # -n suppresses newline.

# ^ Space, to separate printed out numbers.

 

var0=`expr $var0 + 1` # var0=$(($var0+1)) also works.

# var0=$((var0 + 1)) also works.

# let "var0 += 1" also works.

done # Various other methods also work.

 

echo

 

exit 0

#!/bin/bash

 

echo

# Equivalent to:

while [ "$var1"!= "end" ] # while test "$var1"!= "end"

do

echo "Input variable #1 (end to exit) "

read var1 # Not 'read $var1' (why?).

echo "variable #1 = $var1" # Need quotes because of "#"...

# If input is 'end', echoes it here.

# Does not test for termination condition until top of loop.

echo

done

 

exit 0

#!/bin/bash

# Using getopt

 

# Try the following when invoking this script:

# sh ex33a.sh -a

# sh ex33a.sh -abc

# sh ex33a.sh -a -b -c

# sh ex33a.sh -d

# sh ex33a.sh -dXYZ

# sh ex33a.sh -d XYZ

# sh ex33a.sh -abcd

# sh ex33a.sh -abcdZ

# sh ex33a.sh -z

# sh ex33a.sh a

# Explain the results of each of the above.

 

E_OPTERR=65

 

if [ "$#" -eq 0 ]

then # Script needs at least one command-line argument.

echo "Usage $0 -[options a,b,c]"

exit $E_OPTERR

fi

 

set -- `getopt "abcd:" "$@"`

# Sets positional parameters to command-line arguments.

# What happens if you use "$*" instead of "$@"?

 

while [! -z "$1" ]

do

case "$1" in

-a) echo "Option \"a\"";;

-b) echo "Option \"b\"";;

-c) echo "Option \"c\"";;

-d) echo "Option \"d\" $2";;

*) break;;

esac

 

shift

done

 

# It is usually better to use the 'getopts' builtin in a script.

# See "ex33.sh."

 

exit 0

#!/bin/bash

 

E_WRONG_DIRECTORY=73

 

clear # Clear screen.

 

TargetDirectory=/home/bozo/projects/GreatAmericanNovel

 

cd $TargetDirectory

echo "Deleting stale files in $TargetDirectory."

 

if [ "$PWD"!= "$TargetDirectory" ]

then # Keep from wiping out wrong directory by accident.

echo "Wrong directory!"

echo "In $PWD, rather than $TargetDirectory!"

echo "Bailing out!"

exit $E_WRONG_DIRECTORY

fi

 

rm -rf *

rm.[A-Za-z0-9]* # Delete dotfiles.

# rm -f.[^.]*..?* to remove filenames beginning with multiple dots.

# (shopt -s dotglob; rm -f *) will also work.

# Thanks, S.C. for pointing this out.

 

# Filenames may contain all characters in the 0 - 255 range, except "/".

# Deleting files beginning with weird characters is left as an exercise.

 

# Various other operations here, as necessary.

 

echo

echo "Done."

echo "Old files deleted in $TargetDirectory."

echo

 

 

exit 0

#!/bin/bash

# userlist.sh

 

PASSWORD_FILE=/etc/passwd

n=1 # User number

 

for name in $(awk 'BEGIN{FS=":"}{print $1}' < "$PASSWORD_FILE")

# Field separator =: ^^^^^^

# Print first field ^^^^^^^^

# Get input from password file ^^^^^^^^^^^^^^^^^

do

echo "USER #$n = $name"

let "n += 1"

done

 

 

# USER #1 = root

# USER #2 = bin

# USER #3 = daemon

#...

# USER #30 = bozo

 

exit 0

 

# Exercise:

# --------

# How is it that an ordinary user (or a script run by same)

#+ can read /etc/passwd?

# Isn't this a security hole? Why or why not?

#!/bin/bash

# kill-process.sh

 

NOPROCESS=2

 

process=xxxyyyzzz # Use nonexistent process.

# For demo purposes only...

#... don't want to actually kill any actual process with this script.

#

# If, for example, you wanted to use this script to logoff the Internet,

# process=pppd

 

t=`pidof $process` # Find pid (process id) of $process.

# The pid is needed by 'kill' (can't 'kill' by program name).

 

if [ -z "$t" ] # If process not present, 'pidof' returns null.

then

echo "Process $process was not running."

echo "Nothing killed."

exit $NOPROCESS

fi

 

kill $t # May need 'kill -9' for stubborn process.

 

# Need a check here to see if process allowed itself to be killed.

# Perhaps another " t=`pidof $process` " or...

 

 

# This entire script could be replaced by

# kill $(pidof -x process_name)

# or

# killall process_name

# but it would not be as instructive.

 

exit 0

#!/bin/bash

 

ARGS=2 # Two args to script expected.

E_BADARGS=65

E_UNREADABLE=66

 

if [ $# -ne "$ARGS" ]

then

echo "Usage: `basename $0` file1 file2"

exit $E_BADARGS

fi

 

if [[! -r "$1" ||! -r "$2" ]]

then

echo "Both files to be compared must exist and be readable."

exit $E_UNREADABLE

fi

 

cmp $1 $2 &> /dev/null # /dev/null buries the output of the "cmp" command.

# cmp -s $1 $2 has same result ("-s" silent flag to "cmp")

# Thank you Anders Gustavsson for pointing this out.

#

# Also works with 'diff', i.e., diff $1 $2 &> /dev/null

 

if [ $? -eq 0 ] # Test exit status of "cmp" command.

then

echo "File \"$1\" is identical to file \"$2\"."

else

echo "File \"$1\" differs from file \"$2\"."

fi

 

exit 0

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: