do the assignment first. reading the answer is not the same as doing it, and u will feel like u learned it when u didn’t.
1 and 2 and 3 — hello.sh
#!/bin/bash
# hello.sh -- say hello to someone
if [ -z "$1" ]; then # -z means "is it empty?", so: was no name given?
echo "usage: ./hello.sh <name>" # tell them how to use it
exit 1 # stop here. 1 means it did not work
fi # closes the if
echo "hello $1" # only gets here if a name was givenchmod u+x hello.sh
./hello.sh atihello ati
./hello.sh
echo $?usage: ./hello.sh <name>
1
- check that exit code. that
1is what lets someone else write./hello.sh ati && echo "it worked".
4 — count.sh
#!/bin/bash
count=1 # a counter to keep track of where we are
while [ $count -le 5 ]; do # -le is "less than or equal". keep going while it is 1..5
echo $count # print whatever the counter holds right now
count=$((count + 1)) # add 1. $(( )) is how u do maths in bash.
# forget this line and the loop never ends
done # closes the whileor the shorter way with a
for, both are correct:
#!/bin/bash
for count in 1 2 3 4 5; do # go through the list, one number at a time
echo $count # `count` holds a different one each time round
done1
2
3
4
5
5 — check.sh
#!/bin/bash
# check.sh -- is this a file, a directory, or nothing
if [ -f "$1" ]; then # -f asks: does it exist AND is it a normal file?
echo "$1 is a file"
elif [ -d "$1" ]; then # elif is "else if". -d asks: is it a directory?
echo "$1 is a directory"
else # neither, so it is not there at all
echo "$1 does not exist"
fi./check.sh notes.txt
./check.sh backup
./check.sh nothingnotes.txt is a file
backup is a directory
nothing does not exist
elifiselse ifwritten short. u can have as many as u want between theifand theelse.- the order matters.
-fhas to be checked before-d, otherwise nothing breaks here, but in general the first branch that matches is the one that runs and the rest are never looked at.
6 — backup.sh
#!/bin/bash
# backup.sh -- copy every txt file into backup/
mkdir -p backup # -p means: do not complain if it is already there
count=0 # count how many we actually copied
for file in *.txt; do # the shell turns *.txt into the real names first
if [ -f "$file" ]; then # is this a real file? see the note below
cp "$file" backup/ # copy it in
count=$((count + 1)) # and add one to the tally
fi
done
echo "copied $count files into backup/"./backup.shcopied 3 files into backup/
mkdir -pdoes not complain if the folder is already there, which is exactly what u want in a script u run more than once.- the
if [ -f "$file" ]inside the loop looks pointless but it is not. if there is no.txtfile at all, bash hands the loop the text*.txtitself, and without that check u would try to copy a file with that name and get an error.
7 — ask.sh
#!/bin/bash
read -p "what is ur name? " name # -p prints the question, then waits.
read -p "what city do u live in? " city # whatever they type lands in the variable
echo "$name lives in $city"what is ur name? ati
what city do u live in? Istanbul
ati lives in Istanbul
8 — watching it run
bash -x hello.sh ati+ '[' -z ati ']'
+ echo 'hello ati'
hello ati
every line starting with
+is a command about to run, with the variables already replaced. so u are not guessing what the script saw, u are looking at it.
try it on the one that fails too:
bash -x hello.sh+ '[' -z '' ']'
+ echo 'usage: ./hello.sh <name>'
usage: ./hello.sh <name>
+ exit 1
- there it is:
-z ''was true because there was no argument, so it went into theifand exited. this is how u debug a script, and it beats puttingechoeverywhere.