Выбрать главу

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.

4.12.1.6. An example

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