Quiz Solutions
001 | 002 | 003 | 004 | 005 | 006 | 007 | 008
#001
(Provided by the ever-so-talented-and-looking-for-linux-work Josh)
user ~> foobar.sh 1>data.out 2>diag.out
So what is going on here? The bash shell allows redirecting standard output and standard error using 1 and 2 respectively.
For more on I/O redirection using the bash shell click here
#003
When you append panic=N to the kernel command line, the kernel will automatically reboot N seconds after a kernel panic. This can be very handy when troubleshooting. For more on kernel command line options please see Documentation/kernel-parameters.txt in your kernel source directory.
#!/bin/bash # Setup some variables for ease of maintenance # Not really necessary on a script this size, but good coding # practice LOGDIR="/usr/local/app/logs" GZIP="gzip -9" # If our given directory doesn't exist, then exit with an error # message and exit code 1. It is common practice for a # program to exit 0 if everything is OK, an exit code greater # than 0 signifies an error condition if [ ! -d ${LOGDIR} ] then echo "Directory not found: ${LOGDIR}" exit 1 fi# The real work is here. The find command returns a list of # all files in our log directory with an extension of ".log" that # have not been accessed in the last day. Each of these # files is then gzipped individually in the for loop. The -9 # parameter causes gzip to use it's best compression # algorithm at the expense of extra cpu cycles. for FILE in `find ${LOGDIR}/ -type f -name "*.log" -atime +1` do ${GZIP} ${FILE} done
#005
The syntax !275:^ translates to the first argument of item number 275 in the bash command history. If that happens to be a file on your machine then you would get an ls -l style listing of that file.
Note that the ^ could have been replaced with a 1. The ^ and $ characters correspond to first and last respectively, just like in regular expressions.
For more on the bash command history see this link.
#006
There are a lot of ways to solve this problem. I’ve created a couple of examples below.
This first script uses the builtin bash expr command.
#!/bin/bashfunction usage() { echo "Usage: mycalc OPERATOR FIRST SECONDWhere OPERATOR is one of add,subtract,multiply,divide and FIRST and SECOND are numeric" exit 1 } if [ $# -ne 3 ] then usage fi OPERATOR=$1 FIRST=$2 SECOND=$3 case "$OPERATOR" in "add") expr $FIRST + $SECOND ;; "subtract") expr $FIRST - $SECOND ;; "multiply") expr $FIRST * $SECOND ;; "divide") expr $FIRST / $SECOND ;; *) usage ;; esac
One problem with expr is the lack of floating point support.
The second script uses the bc program to perform calculations. bc can handle complex math with ease.
#!/bin/bashfunction usage() { echo "Usage: mycalc OPERATOR FIRST SECONDWhere OPERATOR is one of add,subtract,multiply,divide and FIRST and SECOND are numeric" exit 1 } if [ $# -ne 3 ] then usage fi CMDS="bc" for cmd in $CMDS do if ! type $cmd >/dev/null 2>&1; then echo "ERROR: command \"$cmd\" not found in your path." exit 2 fi done OPERATOR=$1 FIRST=$2 SECOND=$3 case "$OPERATOR" in "add") echo "$FIRST + $SECOND" | bc -l ;; "subtract") echo "$FIRST - $SECOND" | bc -l ;; "multiply") echo "$FIRST * $SECOND" | bc -l ;; "divide") echo "scale=4;$FIRST / $SECOND" | bc -l ;; *) usage ;; esac
Scroll down a bit on this page for more on using expr and see this page for the bc command.
#!/bin/bashif [ -z $1 ]; then echo "Usage: $0 [filename]" exit 1 fi echo `wc -w $1 | awk '{print $1}'`
Click here for a solution written in perl, below is a solution in bash.
#!/bin/bash SLEEP=2 RXLAST=0 TXLAST=0 CYCLE=1 INTERFACE="eth0" while (true); do RXCUR=`cat /proc/net/dev | grep eth0 | awk '{print $1}'|sed "s/^$INTERFACE://"` RX=$(((RXCUR - RXLAST) / SLEEP)) RXLAST=$RXCUR TXCUR=`cat /proc/net/dev | grep eth0 | awk '{print $9}'` TX=$(((TXCUR - TXLAST) / SLEEP)) TXLAST=$TXCUR if [ $CYCLE == 1 ]; then CYCLE=2 echo "Timestamp,Interface,RX Bytes/sec,TX Bytes/sec" else echo "`date +"%F %T"`,$INTERFACE,$RX,$TX" fi sleep $SLEEP done