echo $(( ++A ))
done
The expression $(( ++A )) returns the value of A after it is incremented. You could also use $(( A++ )) , which returns the value of A before it is incremented:
A=1
while [ "$A" -le 20 ]
do
echo $(( A++ ))
done
Since loops that count through a range of numbers are often needed, bash also supports the C-style for loop. Inside double parentheses, specify an initial expression, a conditional expression, and a per-loop expression, separated by semicolons:
# Initial value of A is 1
# Keep looping as long as A<=20
# Each time you loop, increment A by 1
for ((A=1; A<=20; A++))
do
echo $A
done
Note that the conditional expression uses normal comparison symbols ( <= ) instead of the alphabetic options ( -le ) used by test .
Don't confuse the C-style for loop with the for...in loop!
4.12.1.5. Making your scripts available to users of other shells
So far we have been assuming that the user is using the bash shell; if the user of another shell (such as tcsh ) tries to execute one of your scripts, it will be interpreted according to the language rules of that shell and will probably fail.
To make your scripts more robust, add a shebang line at the beginning a pound-sign character followed by an exclamation mark, followed by the full path of the shell to be used to interpret the script ( /bin/bash ):
#!/bin/bash
# script to count from 1 to 20
for ((A=1; A<=20; A++))
do
echo $A
done
I also added a comment line (starting with # ) after the shebang line to describe the function of the script.
The shebang line gets its name from sharp and bang , common nicknames for the #! characters.
Here is an example of a longer script, taking advantage of some of the scripting features in bash :
#!/bin/bash
#
# number-guessing game
#
# If the user entered an argument on the command
# line, use it as the upper limit of the number
# range.
if [ "$#" -eq 1 ]
then
MAX=$1
else
MAX=100
fi
# Set up other variables
SECRET=$(( (RANDOM % MAX) + 1 )) # Random number 1-100
TRIES=0
GUESS=-1
# Display initial messages
clear
echo "Number-guessing Game"
echo "--------------------"
echo
echo "I have a secret number between 1 and $MAX."
# Loop until the user guesses the right number
while [ "$GUESS" -ne "$SECRET" ]
do
# Prompt the user and get her input
((TRIES++))
echo -n "Enter guess #$TRIES: "
read GUESS
# Display low/high messages
if [ "$GUESS" -lt "$SECRET" ]
then
echo "Too low!"
fi
if [ "$GUESS" -gt "$SECRET" ]
then
echo "Too high!"
fi
done
# Display final messages
echo
echo "You guessed it!"
echo "It took you $TRIES tries."
echo
This script could be saved as /usr/local/bin/guess-it and then made executable:
# chmod a+rx /usr/local/bin/guess-it
Here's a test run of the script:
$ guess-it
Number-guessing Game
--------------------
I have a secret number between 1 and 100.
Enter guess #1:
50
Too low!
Enter guess #2:
75
Too low!
Enter guess #3:
83
Too low!
Enter guess #4:
92
Too high!
Enter guess #5:
87
Too high!
Enter guess #6:
85
Too low!
Enter guess #7:
86
You guessed it!
It took you 7 tries.
Another test, using an alternate upper limit:
$ guess-it 50
Number-guessing Game
--------------------
I have a secret number between 1 and 50.
Enter guess #1:
25
Too low!
Enter guess #2:
37
Too low!
Enter guess #3:
44
Too high!
Enter guess #4:
40
You guessed it!
It took you 4 tries.
4.12.1.7. Login and initialization scripts
When a user logs in, the system-wide script /etc/profile and the per-user script ~/.bash_profile are both executed. This is the default /etc/profile :
# /etc/profile
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
pathmunge ( ) {
if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
fi
}
# ksh workaround
if [ -z "$EUID" -a -x /usr/bin/id ]; then
EUID=\Qid -u\Q
UID=\Qid -ru\Q
fi
# Path manipulation
if [ "$EUID" = "0" ]; then
pathmunge /sbin
pathmunge /usr/sbin
pathmunge /usr/local/sbin
fi
# No core files by default
ulimit -S -c 0 > /dev/null 2>&1
if [ -x /usr/bin/id ]; then
USER="\Qid -un\Q"
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
fi
HOSTNAME=\Q/bin/hostname\Q
HISTSIZE=1000
if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then
INPUTRC=/etc/inputrc
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC
for i in /etc/profile.d/*.sh ; do
if [ -r "$i" ]; then
. $i
fi
done
unset i
unset pathmunge
This script adds /sbin , /usr/sbin , and /usr/local/sbin to the PATH if the user is the root user. It then creates and exports the USER , LOGNAME , MAIL , HOSTNAME , and HISTSIZE variables, and executes any files in /etc/profile.d that end in .sh .
Читать дальше