Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
|
soc:2009:lynusvaz:notes:scripting_doc:features_added [2009/08/05 09:30] lynusvaz created |
soc:2009:lynusvaz:notes:scripting_doc:features_added [2009/08/16 00:19] (current) lynusvaz |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | The features mentioned here are NOT YET part of mainline gPXE, and are still under development. The modified code can be found in my git repository, in the [[http://git.etherboot.org/?p=people/lynusvaz/gpxe.git;a=shortlog;h=refs/heads/offset|offset]] branch. | + | =====Scripting Features===== |
| + | The features mentioned here are NOT YET part of mainline gPXE, and are still under development. The modified code can be found in my git repository, in the [[http://git.etherboot.org/?p=people/lynusvaz/gpxe.git;a=shortlog;h=refs/heads/expt|expt]] branch. | ||
| - | Scripting features: | + | - Identifiers |
| + | - Arithmetic evaluator | ||
| + | - Quoting | ||
| + | - Branches | ||
| + | - Return code | ||
| + | - Loops | ||
| - | 1. Identifiers | + | ====Identifiers==== |
| - | 2. Arithmetic evaluator | + | See the Identifiers section at: [[http://etherboot.org/wiki/commandline]], for the basic syntax of an identifier. The new code allows identifiers to be 'nested', like: |
| - | 3. Quoting | + | set i 0 |
| - | 4. Return code of commands | + | echo ${net${i}/ip} |
| - | 5. Branches | + | will print the IP address of the net0 interface. Arithmetic operations (see 2) can also be performed within the ${}: |
| - | 6. Loops | + | E.g.: |
| - | + | set i 0 | |
| - | 1. See the Identifiers section at: [[http://etherboot.org/wiki/commandline]], for the basic syntax of an identifier. The new code allows identifiers to be 'nested', like: | + | echo ${net$(${i}+1)/ip} |
| - | set i 0 | + | will print the IP address of the net1 interface (if it exists). |
| - | echo ${net${i}/ip} | + | |
| - | will print the IP address of the net0 interface. | + | |
| - | 2. Arithmetic expressions can be evaluated by placing them within $(). | + | ====Arithmetic Evaluation==== |
| - | The usual C operators (except assignment) are supported with their usual precendence. Also, string comparison is permitted. | + | Arithmetic expressions can be evaluated by placing them within $(). |
| - | Identifiers are expanded by placing them within ${}. | + | The following operators are supported (in order of decreasing precedence): |
| + | - !, ~ (logical NOT and bitwise negation) | ||
| + | - *, /, % (multiplication, division, and modulo) | ||
| + | - +, - (addition, subtraction) | ||
| + | - <<, >> (left- and right-shift) | ||
| + | - <, <=, >, >= (inequality) | ||
| + | - !=, == (equal, not equal) | ||
| + | - & (bitwise AND) | ||
| + | - | (bitwise OR) | ||
| + | - ^ (bitwise EX-OR) | ||
| + | - && (logical AND) | ||
| + | - || (logical OR) | ||
| + | The == and != operators also act on strings. Identifiers are expanded by placing them within ${}. | ||
| E.g.: | E.g.: | ||
| - | echo $(1 + 2) | + | echo $(1 + 2) |
| - | set a 15 | + | set a 15 |
| - | echo $(${a} * 3 + 5) | + | echo $(${a} * 3 + 5) |
| - | echo $( ${net0/ip} != "" ) | + | echo $( ${net0/ip} != "" ) |
| + | Output: | ||
| + | 3 | ||
| + | 50 | ||
| + | 1 | ||
| - | 3. Quoting: | + | ====Quoting==== |
| The \ is used as an escape character. The following sequences are recognised: | The \ is used as an escape character. The following sequences are recognised: | ||
| - | \<space> Treats the space as part of the command-line argument | + | * \<space> Treats the space as part of the command-line argument |
| - | \<tab> Ditto | + | * \<tab> Ditto |
| - | \<newline> Concatenates the next line to the current line. Both the \ and the newline character are removed | + | * \<newline> Concatenates the next line to the current line. Both the \ and the newline character are removed |
| - | \\ A literal \ | + | * \<any other character> Removes the special meaning of the character (if any) |
| - | \<any other character> Removes the special meaning of the character (if any) | + | Within single-quotes, all characters lose their special meaning. Within double-quotes, the \ and $ retain their special meaning. Single- and double-quotes allow you to use a newline character in a command-line argument. |
| - | + | ||
| - | Within single-quotes, all characters lose their special meaning. Within double-quotes, the \ and $ retain their special meaning. | + | |
| E.g.: | E.g.: | ||
| - | set message 'Hello World' | + | set message "Hello World" |
| - | echo '${message} = '${message} | + | echo '${message} = '${message} |
| - | set message Hello\ \ World | + | set message Hello\ \ World |
| - | set message Hello\ World\ \#1 #'Hello World #1' is treated as a single argument | + | echo ${message} |
| - | echo 'Hello | + | set message Hello\ World\ \#1 #'Hello World #1' is treated as a single argument |
| - | World' | + | echo ${message} |
| - | echo Hello \ | + | echo 'Hello |
| - | World | + | World' # Will introduce a newline between Hello and World |
| - | echo It\'s good to see you! | + | echo Hello \ |
| + | World | ||
| + | echo It\'s good to see you! | ||
| + | Output: | ||
| + | ${message} = Hello World | ||
| + | Hello World | ||
| + | Hello World #1 | ||
| + | Hello | ||
| + | World | ||
| + | Hello World | ||
| + | It's good to see you! | ||
| - | 4. The return code of the previous statement can be checked using the ${rc} variable. | + | ====Branches==== |
| - | A value of 0 means that the command completed successfully, while any other value means the command was not successful. | + | |
| - | + | ||
| - | 5. Branches: | + | |
| The keywords if, else and fi are used to branch command execution: | The keywords if, else and fi are used to branch command execution: | ||
| - | if <condition> | + | if <condition> |
| - | <statements> | + | <statements> |
| - | fi | + | fi |
| - | if <condition> | + | if <condition> |
| - | <statements> | + | <statements> |
| - | else #optional | + | else #optional |
| - | <statements> | + | <statements> |
| - | fi | + | fi |
| A try-catch block is a special kind of branch. | A try-catch block is a special kind of branch. | ||
| - | try | + | try |
| - | <crucial statements> #Call this statment sequence A | + | <crucial statements> #Call this statment sequence A |
| - | catch | + | catch |
| - | <backup statements> #Call this statement sequence B | + | <backup statements> #Call this statement sequence B |
| - | done | + | done |
| - | The statements in sequence A are executed one by one. If any of them fails, execution branches immediately to sequence B. | + | The statements in sequence A are executed one by one. If any of them fails, execution branches immediately to sequence B. If all the statements in sequence A are executed successfully, execution skips sequence B, and continue after the done statement. |
| E.g.: | E.g.: | ||
| - | if $( ${filename} == "") | + | if $( ${filename} != "" && ${server} != "") |
| - | echo "No filename" | + | chain tftp://${server}//${filename} |
| - | else | + | else |
| - | chain tftp://${server}//${filename} | + | echo "No filename" |
| - | fi | + | fi |
| + | will first check that neither filename and server are not empty, before attempting to boot. If either is empty, display an error message. | ||
| - | try | + | try |
| - | kernel tftp://${server}//${kernel} | + | kernel tftp://${server}//${kernel} |
| - | initrd tftp://${server}//${initrd} | + | initrd tftp://${server}//${initrd} |
| - | boot | + | boot |
| - | catch | + | catch |
| - | echo "Oops: ${rc}" | + | echo "Oops: ${rc}" |
| - | done | + | done |
| + | will attempt to boot using the given kernel and initrd. If any of the three commands fail, it displays a message. | ||
| - | 6. While and for loops have been added: | + | ====Return Code==== |
| - | while <condition> | + | The return code of the previous statement can be checked using the ${rc} variable. |
| - | do | + | A value of 0 means that the command completed successfully, while any other value means the command was not successful. |
| - | <statements> | + | |
| - | done | + | E.g.: |
| + | dhcp net0 | ||
| + | if $( ${rc} != 0 ) | ||
| + | echo "DHCP failed" | ||
| + | else | ||
| + | chain http://etherboot.org/gtest/gtest.gpxe # (Tom's Root Boot disk) | ||
| + | fi | ||
| + | |||
| + | ====Loops==== | ||
| + | You can use while and for loops as: | ||
| + | while <condition> | ||
| + | do | ||
| + | <statements> | ||
| + | done | ||
| The while loop executes the statement block while the condition is true. | The while loop executes the statement block while the condition is true. | ||
| - | for <variable> in <value list> | + | for <variable> in <value list> |
| - | do | + | do |
| - | <statements> | + | <statements> |
| - | done | + | done |
| The variable takes on each value in the value list one by one. | The variable takes on each value in the value list one by one. | ||
| E.g.: | E.g.: | ||
| - | set i 0 | + | set i 0 |
| - | while $( ${net${i}/mac} != "" ) | + | while $( ${net${i}/mac} != "" ) |
| - | do | + | do |
| - | dhcp net${i} | + | dhcp net${i} |
| - | if $(${rc} == 0) | + | if $(${rc} == 0) |
| - | chain tftp://${server}//${filename} | + | chain tftp://${server}//${filename} |
| - | fi | + | fi |
| - | set i $( ${i} + 1 ) | + | set i $( ${i} + 1 ) |
| - | done | + | done |
| - | + | will attempt to get a dhcp connection on each valid interface, and if it is successful, boot using a given file. | |
| - | for i in 0 1 2 3 $(3 + 1) 5 | + | |
| - | do | + | |
| - | dhcp net${i} | + | |
| - | if $(${rc} == 0) | + | |
| - | chain tftp://${server}//${filename} | + | |
| - | fi | + | |
| - | done | + | |
| + | for i in 0 1 2 3 5 $(6*3) | ||
| + | do | ||
| + | echo 'i =' ${i} | ||
| + | done | ||
| + | displays: | ||
| + | i = 0 | ||
| + | i = 1 | ||
| + | i = 2 | ||
| + | i = 3 | ||
| + | i = 5 | ||
| + | i = 18 | ||
| + | A break statement will exit a loop, and a continue statement will start the next iteration of the loop. | ||
| + | for i in 1 2 3 4 5 6 | ||
| + | do | ||
| + | if $(${i} == 3) | ||
| + | continue | ||
| + | fi | ||
| + | echo 'i =' ${i} | ||
| + | if $(${i} == 4) | ||
| + | break #This will exit the for loop, not just the if branch | ||
| + | fi | ||
| + | done | ||
| + | displays: | ||
| + | i = 1 | ||
| + | i = 2 | ||
| + | i = 4 | ||