Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 70 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
70
Dung lượng
417,18 KB
Nội dung
# Put anything you want to process in this function. I # recommend that you specify an external program of shell # script to execute. echo “HELLO WORLD - $DATE_ST” > $UNIQUE_FN & # : # No-Op - Does nothing but has a return code of zero } #################################################### ################ BEGINNING OF MAIN ################# #################################################### SCRIPT_NAME=$(basename $0) # Query the system for this script name # Check for the correct number of arguments - exactly 1 if (( $# != 1 )) then echo “\nERROR: Usage error EXITING ” usage fi # What filename do we need to make unique? BASE_FN=$1 # Get the BASE filename to make unique RANDOM=$$ # Initialize the RANDOM environment variable # with the current process ID (PID) UPPER_LIMIT=32767 # Set the UPPER_LIMIT CURRENT_SECOND=99 # Initialize to a nonsecond LAST_SECOND=98 # Initialize to a nonsecond USED_NUMBERS= # Initialize to null PROCESSING=”TRUE” # Initialize to run mode while [[ $PROCESSING = “TRUE” ]] do DATE_ST=$(get_date_time_stamp) # Get the current date/time CURRENT_SECOND=$(get_second) # Get the current second RN=$(in_range_fixed_length_random_number_typeset) # Get a new number # Check to see if we have already used this number this second if (( CURRENT_SECOND == LAST_SECOND )) Listing 21.10 mk_unique_filename.ksh shell script listing. (continued) 538 Chapter 21 then UNIQUE=FALSE # Initialize to FALSE while [[ “$UNIQUE” != “TRUE” ]] && [[ ! -z “$UNIQUE” ]] do # Has this number already been used this second? echo $USED_NUMBERS | grep $RN >/dev/null 2>&1 if (( $? == 0 )) then # Has been used Get another number RN=$(in_range_fixed_length_random_number) else # Number is unique this second UNIQUE=TRUE # Add this number to the used number list USED_NUMBERS=”$USED_NUMBERS $RN” fi done else USED_NUMBERS= # New second Reinitialize to null fi # Assign the unique filename to the UNIQUE_FN variable UNIQUE_FN=${BASE_FN}.${DATE_ST}.$RN # echo $UNIQUE_FN # Comment out this line!! LAST_SECOND=$CURRENT_SECOND # Save the last second value # We have a unique filename # # PROCESS SOMETHING HERE AND REDIRECT OUTPUT TO $UNIQUE_FN # my_program # # IF PROCESSING IS FINISHED ASSIGN “FALSE” to the # PROCESSING VARIABLE # # if [[ $MY_PROCESS = “done” ]] # then # PROCESSING=”FALSE” # fi done Listing 21.10 mk_unique_filename.ksh shell script listing. (continued) We need five functions in this shell script. As usual, we need a function for correct usage. We are expecting exactly one argument to this shell script, the base filename to make into a unique filename. The second function is used to get a date/time stamp. Pseudo-Random Number Generation 539 The date command has a lot of command switches that allow for flexible date/time stamps. We are using two digits for month, day, year, hour, minute, and second with a period (.) between the date and time portions of the output. This structure is the first part that is appended to the base filename. The date command has the following syntax: date +/%m%d%y.%H%M%S'. We also need the current second of the current minute. The current second is used to ensure that the pseudo-random number that is created is unique to each second, thus a unique filename. The date command is used again using the following syntax: date +%S. The in_range_fixed_length_random_number_typeset function is used to create our pseudo-random numbers in this shell script. This function keeps the num- ber of digits consistent for each number that is created. With the base filename, date/ time stamp, and the unique number put together, we are assured that every filename has the same number of characters. One more function is added to this shell script. The my_program function is used to point to the program or shell script that needs all of these unique filenames. It is better to point to an external program or shell script than trying to put everything in the inter- nal my_program function and debugging the internal function on an already working shell script. Of course, I am making an assumption that you will execute the external program once during each loop iteration, which may not be the case. At any rate, this script will show the concept of creating unique filenames while remaining in a tight loop. At the BEGINNING OF MAIN in the main body of the shell script we first query the system for name of the shell script. The script name is needed for the usage function. Next we check for exactly one command-line argument. This single command-line argument is the base filename that we use to create further unique filenames. The next step is to assign our base filename to the variable BASE_FN for later use. The RANDOM environment variable is initialized with an initial seed, which we decided to be the current process ID (PID). This technique helps to ensure that the ini- tial seed changes each time the shell script is executed. For this shell script we want to use the maximum value as the UPPER_LIMIT, which is 32767. If you need a longer or shorter pseudo-random number, you can change this value to anything you want. If you make this number longer than five digits the extra preceding digits will be zeros. There are four more variables that need to be initialized. We initialize both CURRENT_SECOND and LAST_SECOND to nonsecond values 99 and 98, respectively. The USED_NUMBERS list is initialized to null, and the PROCESSING variable is initial- ized to TRUE. The PROCESSING variable allows the loop to continue creating unique filenames and to keep calling the my_process function. Any non-TRUE value stops the loop and thus ends execution of the shell script. A while loop is next in our shell script, and this loop is where all of the work is done. We start out by getting a new date/time stamp and the current second on each loop iteration. Next a new pseudo-random number is created and is assigned to the RN vari- able. If the current second is the same as the last second, then we start another loop to ensure that the number that we created has not been previously used during the cur- rent second. It is highly unlikely that a duplicate number would be produced in such a short amount of time, but to be safe we need to do a sanity check for any duplicate numbers. 540 Chapter 21 When we get a unique number we are ready to put the new filename together. We have three variables that together make up the filename: $BASE_FN, $DATE_ST, and $RN. The next command puts the pieces together and assigns the filename to the vari- able to the UNIQUE_FN variable. UNIQUE_FN=${BASE_FN}.${DATE_ST}.$RN Notice the use of the curly braces ({}) around the first two variables, BASE_FN and DATE_ST. The curly braces are needed because there is a character that is not part of the variable name without a space. The curly braces separate the variable from the character to ensure that we do not get unpredictable output. Because the last variable, $RN, does not have any character next to its name, the curly braces are not needed, but it is not a mistake to add them. The only thing left is to assign the $CURRENT_SECOND value to the LAST_SECOND value and to execute the my_program function, which actually uses the newly created filename. I have commented out the code that would stop the script’s execution. You will need to edit this script and make it suitable for your particular purpose. The mk_unique_filename.ksh shell script is in action in Listing 21.11. yogi@/scripts# ./mk_unique_filename.ksh /tmp/myfilename /tmp/myfilename.120601.131507.03038 /tmp/myfilename.120601.131507.15593 /tmp/myfilename.120601.131507.11760 /tmp/myfilename.120601.131508.08374 /tmp/myfilename.120601.131508.01926 /tmp/myfilename.120601.131508.07238 /tmp/myfilename.120601.131509.07554 /tmp/myfilename.120601.131509.12343 /tmp/myfilename.120601.131510.08496 /tmp/myfilename.120601.131510.18285 /tmp/myfilename.120601.131510.18895 /tmp/myfilename.120601.131511.16618 /tmp/myfilename.120601.131511.30612 /tmp/myfilename.120601.131511.16865 /tmp/myfilename.120601.131512.01134 /tmp/myfilename.120601.131512.19362 /tmp/myfilename.120601.131512.04287 /tmp/myfilename.120601.131513.10616 /tmp/myfilename.120601.131513.08707 /tmp/myfilename.120601.131513.27006 /tmp/myfilename.120601.131514.15899 /tmp/myfilename.120601.131514.18913 /tmp/myfilename.120601.131515.27120 /tmp/myfilename.120601.131515.23639 /tmp/myfilename.120601.131515.13096 /tmp/myfilename.120601.131516.19111 /tmp/myfilename.120601.131516.05964 Listing 21.11 mk_unique_filename.ksh shell script in action. (continues) Pseudo-Random Number Generation 541 /tmp/myfilename.120601.131516.07809 /tmp/myfilename.120601.131524.03831 /tmp/myfilename.120601.131524.21628 /tmp/myfilename.120601.131524.19801 /tmp/myfilename.120601.131518.13556 /tmp/myfilename.120601.131518.24618 /tmp/myfilename.120601.131518.12763 # Listing of newly created files yogi@/tmp# ls -ltr /tmp/myfilename.* -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131507.15593 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131507.03038 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131508.08374 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131508.01926 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131507.11760 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131509.12343 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131509.07554 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131508.07238 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131510.18285 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131510.08496 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131511.30612 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131511.16618 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131510.18895 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131512.19362 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131512.01134 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131511.16865 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131513.10616 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131513.08707 Listing 21.11 mk_unique_filename.ksh shell script in action. (continued) 542 Chapter 21 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131512.04287 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131514.18913 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131514.15899 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131513.27006 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131515.27120 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131515.23639 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131515.13096 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131516.19111 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131516.05964 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131524.21628 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131524.03831 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131516.07809 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131518.24618 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131518.13556 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131524.19801 -rw-r r root system Dec 06 13:15 /tmp/myfilename.120601.131518.12763 Listing 21.11 mk_unique_filename.ksh shell script in action. (continued) Summary In this chapter we stepped through some different techniques of creating pseudo- random numbers and then used this knowledge to create unique filenames. Of course these numbers are not suitable for any security-related projects because of the predictability and cyclical nature of computer generated numbers using the RANDOM variable. Play around with these shell scripts and functions and modify them for your Pseudo-Random Number Generation 543 needs. In Chapter 10 we used pseudo-random numbers to create pseudo-random pass- words. If you have not already studied Chapter 10, I suggest that you break out of sequence and study this chapter next. In the next chapter we move into a little floating point mathematics and introduce you to the bc utility. Floating point math is not difficult if you use some rather simple techniques. Of course you can make mathematics as difficult as you wish. I hope you gained a lot of knowledge in this chapter and I will see you in the next chapter! 544 Chapter 21 545 Have you ever had a need to do some floating-point math in a shell script? If the answer is yes, then you’re in luck. On Unix machines there is a utility called bc that is an interpreter for arbitrary-precision arithmetic language. The bc command is an inter- active program that provides arbitrary-precision arithmetic. You can start an interac- tive bc session by typing bc on the command line. Once in the session you can enter most complex arithmetic expressions as you would in a calculator. The bc utility can handle more than I can cover in this chapter, so we are going to keep the scope limited to simple floating-point math in shell scripts. In this chapter we are going to create shell scripts that add, subtract, multiply, divide, and average a list of numbers. With each of these shell scripts the user has the option of specifying a scale, which is the number of significant digits to the right of the decimal point. If no scale is specified, then an integer value is given in the result. Because the bc utility is an interactive program, we are going to use a here document to supply input to the interactive bc program. We will cover using a here document in detail throughout this chapter. Syntax By now you know the routine: We need to know the syntax before we can create a shell script. Depending on what we are doing we need to create a mathematical statement to Floating-Point Math and the bc Utility CHAPTER 22 present to bc for a here document to work. A here document works kind of like a label in other programming languages. The syntax that we are going to use in this chapter will have the following form: VARIABLE=$(bc <<LABEL scale=$SCALE ($MATH_STATEMENT) LABEL) The way a here document works is some label name, in this case LABEL, is added just after the bc command. This LABEL has double redirection for input into the interactive program, bc <<LABEL. From this starting label until the same label is encountered again everything in between is used as input to the bc program. By doing this we are automating an interactive program. We can also do this automation using another technique. We can use echo, print, and printf to print all of the data for the math statement and pipe the output to bc. It works like the following commands. VARIABLE=$(print ‘scale = 10; 104348/33215’ | bc) or VARIABLE=$(print ‘scale=$SCALE; ($MATH_STATEMENT)’ | bc) In either case we are automating an interactive program. This is the purpose of a here document. It is called a here document because the required input is here, as opposed to somewhere else, such as user input from the keyboard. When all of the required input is supplied here, it is a here document. Creating Some Shell Scripts Using bc We have the basic syntax, so let’s start with a simple shell script to add numbers together. The script is expecting a list of numbers as command-line arguments. Addi- tionally, the user may specify a scale if the user wants the result calculated as a floating- point number to a set precision. If a floating point number is not specified, then the result is presented as an integer value. Creating the float_add.ksh Shell Script The first shell script that we are going to create is float_add.ksh. The idea of this shell script is to add a list of numbers together that the user provides as command-line arguments. The user also has the option of setting a scale for the precision of floating- point numbers. Let’s take a look at the float_add.ksh shell script in Listing 22.1, and we will go through the details at the end. 546 Chapter 22 #!/usr/bin/ksh # # SCRIPT: float_add.ksh # AUTHOR: Randy Michael # DATE: 03/01/2001 # REV: 1.1.A # # PURPOSE: This shell script is used to add a list of numbers # together. The numbers can be either integers or floating- # point numbers. For floating-point numbers the user has # the option of specifying a scale of the number of digits to # the right of the decimal point. The scale is set by adding # a -s or -S followed by an integer number. # # EXIT CODES: # 0 ==> This script completed without error # 1 ==> Usage error # 2 ==> This script exited on a trapped signal # # REV. LIST: # # # set -x # Uncomment to debug this script # set -n # Uncomment to debug without any command execution # ######################################################## ############## DEFINE VARIABLE HERE #################### ######################################################## SCRIPT_NAME=$(basename $0) # The name of this shell script SCALE=”0” # Initialize the scale value to zero NUM_LIST= # Initialize the NUM_LIST variable to NULL COUNT=0 # Initialize the counter to zero MAX_COUNT=$# # Set MAX_COUNT to the total number of # command-line arguments. ######################################################## ################ FUNCTIONS ############################# ######################################################## function usage { echo “\nPURPOSE: Adds a list of numbers together\n” echo “USAGE: $SCRIPT_NAME [-s scale_value] N1 N2 Nn” Listing 22.1 float_add.ksh shell script listing. (continues) Floating-Point Math and the bc Utility 547 [...]... not meet the criteria that we defined, the * is matched and we execute the usage function before exiting the shell script The regular expressions for testing for integers and floating point numbers include +([0 -9] ), +(-[0 -9] ), +([0 -9] |.[0 -9] , +(+[0 -9] .[0 -9] , +(-[0 -9] .[0 -9] , +([-.0 -9] ), +([+.0 -9] ) The first two tests are for integers and negative whole numbers The last five tests are for positive and... +([0 -9] )) # Check for an integer : # No-op, do nothing ;; +(-[0 -9] )) # Check for a negative whole number : # No-op, do nothing ;; +([0 -9] |[.][0 -9] )) # Check for a positive floating point : # No-op, do nothing ;; +(+[0 -9] |[.][0 -9] )) # Check for a positive floating point # with a + prefix : # No-op, do nothing ;; +(-[0 -9] [.][0 -9] )) # Check for a negative floating point : # No-op, do nothing ;; +([-.0 -9] ))... +([0 -9] )) # Check for an integer : # No-op, do nothing ;; +([-0 -9] )) # Check for a negative whole number : # No-op, do nothing ;; +([0 -9] |[.][0 -9] )) # Check for a positive floating point : # No-op, do nothing ;; +(+[0 -9] [.][0 -9] )) # Check for a positive floating point # with a + prefix : # No-op, do nothing ;; +(-[0 -9] [.][0 -9] )) # Check for a negative floating point : # No-op, do nothing ;; +([-.0 -9] ))... case $NUM in +([0 -9] )) # Check for an integer : # No-op, do nothing ;; +([-0 -9] )) # Check for a negative whole number : # No-op, do nothing ;; +([0 -9] |[.][0 -9] )) # Check for a positive floating point number : # No-op, do nothing ;; +(+[0 -9] |[.][0 -9] )) # Check for a positive floating point number # with a + prefix : # No-op, do nothing ;; +([-0 -9] |.[0 -9] )) Listing 22.4 float_subtract.ksh shell script listing... testing, or using, a shell script with a here document To be safe, just leave out any beginning spaces The final step is to display the result to the user Listing 22.3 shows the float_add.ksh shell script in action [root:yogi]@/scripts# /float_add.ksh -s 8 2 223.545 332.0 099 76553 The sum of: 2 + 223.545 + 332.0 099 76553 to a scale of 8 is 557.55 497 6553 Listing 22.3 float_add.ksh shell script in action... Listing 22.6 float_multiply.ksh shell script listing (continued) Floating-Point Math and the bc Utility ;; +([-0 -9] )) # Check for a negative whole number : # No-op, do nothing ;; +([0 -9] |[.][0 -9] )) # Check for a positive floating point : # No-op, do nothing ;; +(+[0 -9] |[.][0 -9] )) # Check for a positive floating point # with a + prefix : # No-op, do nothing ;; +([-0 -9] |.[0 -9] )) # Check for a negative floating... Creating the float_subtract.ksh Shell Script As the float_add.ksh shell script performed addition on a series of numbers, this section studies the technique of subtraction Because this shell script is very similar to the shell script in Listing 22.1 we are going to show the shell script and study the details at the end The float_subtract.ksh shell script is shown in Listing 22.4 #!/usr/bin/ksh # # SCRIPT:... for TST_ARG in $* do if [[ $(echo $TST_ARG | cut -c1) = ‘-’ ]] \ Listing 22.1 float_add.ksh shell script listing (continued) Floating-Point Math and the bc Utility && [ $TST_ARG != ‘-s’ -a $TST_ARG != ‘-S’ ] then case $TST_ARG in +([-0 -9] )) : # No-op, do nothing ;; +([-0 -9] .[0 -9] )) : # No-op, do nothing ;; +([-.0 -9] )) : # No-op, do nothing ;; *) echo “\nERROR: Invalid argument on the command line” usage... != ‘-S’ ] 561 562 Chapter 22 then case $TST_ARG in +([-0 -9] )) : # No-op, do nothing ;; +([-0 -9] .[0 -9] )) : # No-op, do nothing ;; +([-.0 -9] )) : # No-op, do nothing ;; *) echo “\nERROR: $TST_ARG is an invalid argument\n” usage exit 1 ;; esac fi done esac done A getopts statement starts with a while loop To define valid command-line switches for a shell script you add the list of characters that you want... or using, a shell script with a here document Floating-Point Math and the bc Utility The final step is to display the result to the user Listing 22.5 shows the float _subtract.ksh shell script in action [root:yogi]@/scripts# float_subtract.ksh -s 4 8. 098 38 2048 65536 42.632 The difference of: 8. 098 38 - 2048 - 65536 - 42.632 to a scale of 4 is -67618.53362 Listing 22.5 float_subtract.ksh shell script . the shell script. The regular expressions for testing for integers and floating point numbers include +([0 -9] ), +(-[0 -9] ), +([0 -9] |.[0 -9] , +(+[0 -9] .[0 -9] , +(-[0 -9] .[0 -9] , +([ 0 -9] ), +([+.0 -9] ) /tmp/myfilename /tmp/myfilename.120601.131507.03038 /tmp/myfilename.120601.131507.15 593 /tmp/myfilename.120601.131507.11760 /tmp/myfilename.120601.131508.08374 /tmp/myfilename.120601.131508.0 192 6 /tmp/myfilename.120601.131508.07238 /tmp/myfilename.120601.1315 09. 07554 /tmp/myfilename.120601.1315 09. 12343 /tmp/myfilename.120601.131510.08 496 /tmp/myfilename.120601.131510.18285 /tmp/myfilename.120601.131510.18 895 /tmp/myfilename.120601.131511.16618 /tmp/myfilename.120601.131511.30612 /tmp/myfilename.120601.131511.16865 /tmp/myfilename.120601.131512.01134 /tmp/myfilename.120601.131512. 193 62 /tmp/myfilename.120601.131512.04287 /tmp/myfilename.120601.131513.10616 /tmp/myfilename.120601.131513.08707 /tmp/myfilename.120601.131513.27006 /tmp/myfilename.120601.131514.15 899 /tmp/myfilename.120601.131514.1 891 3 /tmp/myfilename.120601.131515.27120 /tmp/myfilename.120601.131515.236 39 /tmp/myfilename.120601.131515.13 096 /tmp/myfilename.120601.131516. 191 11 /tmp/myfilename.120601.131516.0 596 4 Listing. [root:yogi]@/scripts# ./float_add.ksh -s 8 2 223.545 332.0 099 76553 The sum of: 2 + 223.545 + 332.0 099 76553 to a scale of 8 is 557.55 497 6553 Listing 22.3 float_add.ksh shell script in action. Floating-Point Math