BL-Linux Chapter 12 - Shell Scripting
How do you comment out a line? What is the symbol?
#
What is shebang?
#!/bin/bash This tells the kernel that the script should be interpreted by /bin/bash instead of run as a binary.
What are two ways to run a script? What does the first way imply? What is a major difference between the two ways?
$ ./script.sh ^^This way requires the #!/bin/bash especially if the user is running a different shell. It also requires that the script be executable. $ bash script.sh This way automatically uses a bash shell and does not require it to be executable.
What does the special bash variable $# contain?
$# contains the number of arguments passed to the scripot.
What is another option to place your scripts in that also servers as a variable?
$HOME/bin
Where is a good place to put your scripts and why?
/usr/local or /usr/local/bin - This is because it can be shared across multiple users/computers making it widely available.
What does this command do? $ seq -w 8 10
08 09 10 The -w flag will cause seq to pad the output with leading zeroes if the number of digits changes.
$ case $1 in start) echo "starting the process" ;; stop) echo "stopping the process" ;; *) echo "I need to hear start or stop" esac
1.) First comes the string to be matched, which is terminated in a closing parenthesis. The * matches anything, which makes it a default. 2.) Then comes zero or more statements that are run if this case is matched. 3.) The list of statements is terminated by two semicolons (;;). 4.) Finally the whole statement is closed with esac. * Processing stops after the first match, so if multiple conditions are possible on the first one is run.
What do these test commands do? $ if [[ `hostname` = 'bob.ertw.com' ]] ; then $ if [[ `hostname` != 'bob.ertw.com' ]] ; then
= This will test if the commands are equal. != This will test if they are not equal.
What does a case statement start with?
A "case" statement will start with a description of what the value to be tested is in the form: case $variable in
You have written a Perl script to send emails to users who leave processes that abuse the CPU. Rather than perl cpu_report.pl, you want to run it as ./cpu_report.pl. Which two steps are needed? a. Put #!/usr/bin/perl on the first line of the script. b. chmod +x cpu_report.pl c. chown root cpu_report.pl; chmod +s cpu_report.pl d. Put #!perl on the first line of the script e. Put the script in /usr/bin along with perl
A, B A is correct because the shebang line indicates how the script is to be run; in this case it is with the /usr/bin/perl. B is correct because the script needs to be executable.
On a Linux system installed with the default shell, you need to execute a shell script that contains variables, aliases, and functions by simply entering its name on the command line. What should be the first line of the script? (Choose all that apply) a. Nothing b. #/bin/csh c.#!/bin/bash d. exec=/bin/bash
A, C. Answers A, and C are correct because the features mentioned as being in the script are all related to the bash shell. Either you use answer C to specifically set it or you allow the default of bash to be used by not specifying a shell.
During a script's execution, what is stored in $1? a. The first argument to the script b. The shell that called the script c. The name of the script d. The process ID of the script
A. A is correct because the $1 and $2, and so forth variables contain the arguments passed to the script.
Your script automates the creation of a virtual machine and you have read the desired size of memory, in gigabytes, into a variable called MEM. The tool you are using inside your script to create the virtual machine expects this value in megabytes. How can you convert MEM to megabytes? a. MEM=$((MEM * 1024)) b. MEM=$MEM*1024 c. MEM=`$MEM * 1024` d MEM=eval($MEM*1024)
A. A is correct because it uses the $(()) syntax to evaluate an arithmetic expression.
What does the bc tool allow? What does this command do? $ RADIUS=3 $ echo "3.14 * $RADIUS ^ 2" | bc What does the * mean? Why do you need the quotes?
Allows bash to work with decimals. bc accepts an arithmetic expression on the input and returns the calculation on the output. Therefore you must echo a string into the tool. The quotes are necessary to prevent the shell form interpreting elements as a file glob, as the asterisk was intended for bc and not to match a file.
You are using the scripting statement case in a script and keep getting a message such as the following: script1: line 10: syntax error: unexpected end of file What is the likely cause of the error? a. You didn't have a default condition set. b. You forgot to close the case with esac. c. You were using the old [ ] bash style instead of [[ ]]. d. You were comparing an integer when you should have been comparing a string.
B B is correct because the shell expects an esac to close out the case and will get to the end of file and throw an error if it's missing.
When writing a bash script, you find yourself needing to exit early because of an error condition. Which of the following commands should be used? a. die b. exit 1 c. raise d. exit
B B is correct because it uses the exit keyword with a value of 1, which indicates an error.
You are writing a shell script that calls another program called /bin/foo. If the program does not return successfully, you should print an error to the screen. How can you test for an error condition? a. if [ -e /bin/foo] b. if [$? -gt 0 ] c. if [$? -eq 0] d. until [ /bin/foo ]
B. B is correct because it checks the value of $?, which stores the exit code of the last program ran, for the value of 1 or greater, which means an error.
Consider the following program, which is run as ./script a b c d. shift echo $0 $1 What will it print? a. b c b. a b c. /script b d. /script a
C C is correct because after the shift, $1 becomes "b" and $0 contains the name of the script.
You are looking at an old script you wrote and see this line: if [ -x /bin/ps - a -f /etc/app.conf ] In plain English, what does it say? a. if /bin/ps is excluded from /etc/app.conf b. if the output of /bin/ps contains all the strings from file /etc/app.conf c. if /bin/ps is executable and /etc/app.conf exists d. if either /bin/ps or /etc/app.conf exists
C C is correct because the -x and -f mean "is executable" and "exists," respectively, and the -a requires both with a logical AND.
If you had an operation you wanted to perform on every process currently running, the most appropriate loop construct would be a. seq b. while c. for d. until
C C is correct because the collection is known and a for loop can easily iterate over every process.
If ps -ef | grep nginx | awk '{print $2}' returns a list of process ids for nginx, how would you kill them all in one line? a. kill "ps -ef | grep nginx | awk '{print $2}'" b. PIDS="ps -ef | grep nginx | awk '{print $2}'";kill PIDS c. kill $(ps -ef | grep nginx | awk '{print $2}') d. kill $((ps -ef | grep nginx | awk '{print$2}'))-
C c is correct because it properly substitutes the command for the arguments to the kill command.
A Bash comment starts with which character? a. " b. ! c. # d. --
C. C is correct because comments start with the hash symbol. The other answers are incorrect.
Reviewing a shell script you found, you see this: if [[ -x /etc/zoid ]]; then . /etc/zoid elif [[ -x $HOME/ .zoid ]]; then . $HOME/ .zoid fi Which of the following is true? a. /usr/bin elif needs to be present for this to work b. The script will run /etc/zoid and $HOME/.zoid if they exist c. If /etc/zoid is marked as executable, it will be executed d. $HOME/.zoid takes priority over /etc/zoid
C. C is correct because the script will source /etc/zoid if it has the executable bit set.
Consider the following transcript: $./report.pl $echo $? 1 What can be said about what just happened? a. The command completed successfully? b. One argument was passed to report.pl through the environment. c. The script ran for 1 second d. An error happened during the script
D D is correct because a result code ($?) of a nonzero number indicates an error condition.
Given a directory full of files, how could you rename everything to have a .back extension? a. mv * *. bak b. for i in ls; do mv $i $i.bak; done c. for i in ls; do mv i i.bak; done d. for i in *; do mv $i $i.bak; done
D D is correct because it correctly uses a file glob in the for clause and moves the file to the same name plus a .bak.
You are writing a shell script that accepts parameters on the command line. How can you check to make sure you've received exactly three parameters? a. if [[ $# -ge 3 ]] b. if [[ $ARGV = 3]] c. if [[ $? = 3]] d. if [[ 3 -eq $# ]]
D D is correct because it uses the -eq integer equality operator to compare 3 to $#, which holds the number of arguments.
Looking inside a script, you see this line: if [[ `hostname` = 'bob' ]]; What is it doing? a. Nothing. It is trying to perform an integer comparison on a string. b. Checking to see whether the hostname command was successful. c. Changing the hostname to bob and checking to see whether that was successful. d. Checking to see whether the hostname is bob.
D D is correct because the script is performing a string quality check on the output of the hostname command against the string bob.
Your script: ./deploy foo.war production
Each of the arguments in the script is stored in $1, $2, $3 and so forth. $0 is the name of the script itself.
What does this script do? if [[ $# -lt 2 ]] ; then echo Usage: $0 deployable environment exit 1 # return an error
Each of the arguments is stored in $1, $2, $3, and so forth. $0 is the name of the script itself. The special bash variable $# contains the number of arguments passed to the script. The script provides some basic error check of the input.
What do these commands do? $ PID= (`ps -ef | grep "[n]ginx: master process" | awk '{print $2}'`) $echo nginx is running at $PID
Enclosing the last command in backticks within the script gives the output in a variable which is known as "command substitution."
What does this test command do? -e FILE
FILE exists
What does this test command do? -s FILE
FILE exists and has a single a size greater than zero
What does this test command do? -d FILE
FILE exists and is a directory
What does this test command do? -f FILE
FILE exists and is a regular file
What does this test command do? -h FILE
FILE exists and is a symbolic link
What does this test command do? -r FILE
FILE exists and the user can read it
What does this test command do? -x FILE
FILE exists and the user has the execute bit set
What does this test command do? FILE1 -ef FILE 2
FILE1 and FILE2 have the same device and inode numbers
What does this test command do? FILE1 -nt FILE2
FILE1 is newer (modification date) than FILE2
What does this test command do? FILE1 -ot FILE2
FILE1 is older than FILE2
True or false for bash: 1 is true and 0 is false for return codes
False Bash is opposite of most computer systems. For bash, 0 is true.
What does this test command do? -w FILE
File exists and the user can write to it
What does this command do? $ ps -ef | grep nginx
Finds the process IDs of your web server
What will this script do? for i in $(seq -w 1 10); do curl -O http://example.com/downloads.html done
Here the loop counter is more than just to count the number of iterations. The counter, i, forms part of a URL on a remote web server. Also note that the seq command included -w so that the numbers were all two digits, which is common in remote web files. Ultimately this script downloads 10 files with a predictable name from a remote website using curl.
What can you do with the "exit command in your script/program? What does it return if successful?
If successful, it will return a 0. If you write exit 42 it will return 42 if the caller/user uses the $? command. Please note you can choose to have the value outputted to any number, but be careful as most users are not expecting anything except for a 0 or a 1 exit code.
What does this script do? $ for name in Ross Sean Mary-Beth; do > echo $name > done
In this instance, the command will just print the items in the for loop. So your output would just be: Ross Sean Mary-Beth
What does $? hold in the command? $ ps -ef | grep -q [n]agios $ echo $?
It holds the return code of the LAST command executed, which is the grep command in this instance. It is important to note it only holds the LAST command.
What is the order of logic from high precedence to lower?
Like the order of operations in math, boolean logic assigns precedence in the following order: 1.) Brackets 2.) AND 3.) OR
Does the kernel honor the setuid bit on script files?
No! if you need to give elevated privileges within a script you must use something like sudo.
What will this command do? $ seq 1 5
Output: 1 2 3 4 5 The seq command just iterates over the range
What will this command do? $ seq 1 2 5
Output: 1 3 5 In this instance, it will count by 2
What do these commands do? $ PID= $(ps -ef | grep "[n]ginx: master process" | awk '{print $2}') $echo nginx is running at $PID
Same as the prior card - - note the $() style - both methods do the same thing. Parentheses are easier to match up when debugging problems, which makes the 2nd method easier to use.
What does this command do? $ ps -ef | grep "[n]ginx: master process" | awk '{print $2}'
Searches for process IDs of web server, then greps for master process, then uses RegEx that matches the nginx process, but not the grep command line, then extracts column 2 which is the process ID......
What does the following do? $ if test -f /etc/passwd; then $ echo "password file exists" $ fi
The -f test checks for the existence of a file; in the previous case it is /etc/passwd. If the file exists, the echo will be run.
What does this script do? while [[ -f /var/lock/script1 ]] ; do echo waiting sleep 10 done
The command on the while line looks for the presence of a lock file and pauses for 10 seconds if it's found. The file is checked each time through the loop and the loop ends only when the file is removed.
What does the ! do in this command? $ if ! ps -ef | grep -q [n]agios; then $ echo Natios is NOT running $ fi
The if ! will test for the absence of a condition. This allows the programmer to negate the test statement.
What does this test command do? $if [[ -n $STRING ]] ; then
The opposite of -z is -n, which tests for a nonzero length string.
While and until are different. How?
The opposite of while is until, which behaves as if the loop condition were written with an exclamation point in front of it. In other words the loop continues while the expression is false and ends the loop once the condition is true.
What does the test command do?
The test command reads a series of options up until the semicolon or end of line and returns a value depending on the results of the test.
What does this test command do? $ if [[ -z $STRING ]] ; then
The test uses -z to check for a zero length string.
What does this test command do? $ if [ -x /usr/bin/nginx ] ; then $ echo nginx is executable $ fi
The test will see if /usr/bin/nginx is executable
What does this test command do? $ if [[ -x /usr/bin/nginz ]] ; then $ echo nginx is executable $ fi
The test will see if /usr/bin/nginx is executablel. It is important to note that newer versions of Bash can also use 2 square brackets. So either [ ] or [[ ]] works. The purpose of the new style is to be more forgiving of errors, such as if you're using a variable that's unset. *** Note the space before and after the conditions.... You must have a space BEFORE AND AFTER!!! The shell can't differentiate between the square brackets and the test itself if the spaces are missing.
What will this allow $(())
This allows a person to do math.
What do these test commands do? $ if [ -f /etc/passwd -a -x /usr/sbin/adduser ] $if [[ -f /etc/passwd && -x /usr/sbin/adduser ]] $ if [ -f /etc/passwd -o -x /usr/sbin/adduser ] $ if [ -f /etc/passwd || -x /usr/sbin/adduser ]
This command will see if the /etc/passwd file exists and is a regular file (-f), the -a represents the && which is to say AND, finally the -x will see if the file exists and the user has the execute bit set. In the last 2 examples, the -o is the equivalent of || which is to say OR.
What does this script do? value=0 last=33 while [ $value -lt $last ] do echo $value value=$(($value +1)) done
This counts from 0 to 32. It is 32 instead of 33 because the condition is -lt (less than) isntead of -le (which is less than or equal to).
What does this command do? until [ -f /var/tmp/report.done ] ; do # Waiting until the report is done sleep 10 done rm /var/tmp/report.done
This program waits until a file is present, such as from a report job that is run. It then cleans up the state file and continues on.
What does this script do? echo -n "What is your name?" read NAME echo Hello, $Name
This read the input from the user and output the following: Hello, [name inputted by the user]
What does this script do? for file in $.txt; do newname=`echo $file | sed 's/txt$/doc/'`; mv $file $newname; done
This renames every file ending in .txt to .doc. It does this by iterating over the *.txt wildcard and each time setting the variable file to the current file. It assigns a temporary variable, newname, to the output of a sed command that replaces the extension with the new one. Finally, it moves the old name to the new name before moving on to the next file.
What does this script do? while read LINE; do echo $LINE done
This script behaves the same as the cat command. It echoes anything passed to it as a filter to the output.
What do these commands do? $ PROCS=$(($(ps -ef | wc -l) -1)) $ PROCS=$((`ps -ef | wc -l` -1 ))
This will give the process list, return the number of lines, and then subtract 1 essentially eliminating the line for the header that is returned from ps -ef Both commands do the same thing.
What does this command do? grep -r foo /etc/ > /dev/null 2>&1
This will redirect the output to /dev/null and also redirect the standard error stream to the to the regular output stream.
What do these test commands do? [[ A || B && C ]] is evaluated how?
[[ A || (B && C) ]]
What is else if in bash?
elif
What is the "for" loop basic syntax?
for variable in collection; do #do something on $variable done
What does this command do? $ ps -ef | wc -l
ps -ef gives you the process list wc -l returns the number of lines
How do you denote a test in Bash?
square brackets $ if [ conditions ] ; then Anything between the brackets is considered a test.