scripting:posparams

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
scripting:posparams [2012/02/01 13:42]
jaalto Fix topo in code comment
scripting:posparams [2015/08/06 02:29]
bill_thomson
Line 6: Line 6:
 ===== Intro ===== ===== Intro =====
  
-The day will come when you want to give arguments to your scripts. These arguments are reflected ​as the **positional parameters** ​inside your scriptMost relevant special parameters are described below:+The day will come when you want to give arguments to your scripts. These arguments are known as **positional parameters**. ​Some relevant special parameters are described below:
 ^Parameter(s)^Description^ ^Parameter(s)^Description^
 |''​$0''​|the first positional parameter, equivalent to ''​argv[0]''​ in C, see [[scripting:​posparams#​the_first_argument | the first argument]]| |''​$0''​|the first positional parameter, equivalent to ''​argv[0]''​ in C, see [[scripting:​posparams#​the_first_argument | the first argument]]|
Line 18: Line 18:
  
 These positional parameters reflect exactly what was given to the These positional parameters reflect exactly what was given to the
-script when it was called. ​There are no special things interpreted:​ +script when it was called. 
-Option-switch parsing (''​-h''​ for displaying help) is not done in this + 
-stage.+Option-switch parsing (e.g. ''​-h''​ for displaying help) is not performed at 
 +this point.
  
 See also [[dict:​terms:​parameter | the dictionary entry for "​parameter"​]]. See also [[dict:​terms:​parameter | the dictionary entry for "​parameter"​]].
Line 27: Line 28:
 ===== The first argument ===== ===== The first argument =====
  
-The very first argument you can access is referenced ​by ''​$0''​. It +The very first argument you can access is referenced ​as ''​$0''​. It 
-usually ​is set to the script'​s name exactly ​like it was called, and +is usually ​set to the script'​s name exactly ​as called, and it's 
-it's set on shell initialization:​+set on shell initialization:​
  
 __Testscript__ - it just echos ''​$0'':​ __Testscript__ - it just echos ''​$0'':​
Line 36: Line 37:
 echo "​$0"​ echo "​$0"​
 </​code>​ </​code>​
-You see, ''​$0''​ is always set to however you call that script (''​$''​ is the prompt...):+You see, ''​$0''​ is always set to the name the script ​is called with (''​$''​ is the prompt...):
 <​code>​ <​code>​
 > ./​testscript ​ > ./​testscript ​
Line 52: Line 53:
 </​code>​ </​code>​
  
-Alsoto be over-exact: ​''​$0''​ is not a positional parameter, it's a +In other terms, ''​$0''​ is not a positional parameter, it's a 
-special parameter independent from the real parameter list. Also it +special parameter independent from the positional ​parameter list. It 
-really ​can be set to anything. In the **ideal** case it's the pathname +can be set to anything. In the **ideal** case it's the pathname 
-of the script, but since this is set on invocation, the invoking+of the script, but since this gets set on invocation, the invoking
 program can easily influence it (the ''​login''​ program does that for program can easily influence it (the ''​login''​ program does that for
-login shells, by prepending ​a dash, for example).+login shells, by prefixing ​a dash, for example).
  
-Inside a function, ''​$0''​ still reflects what was described above. To+Inside a function, ''​$0''​ still behaves as described above. To
 get the function name, use ''​$FUNCNAME''​. get the function name, use ''​$FUNCNAME''​.
  
Line 71: Line 72:
   * in general: ''​$N''​ will become ''​$N-1''​   * in general: ''​$N''​ will become ''​$N-1''​
  
-The command can take a number as argument: ​How many positions to shift. +The command can take a number as argument: ​Number of positions to shift. 
- So, a ''​shift 4'' ​will shift ''​$5''​ to ''​$1''​.+ e.g. ''​shift 4'' ​shifts ​''​$5''​ to ''​$1''​.
  
 ===== Using them ===== ===== Using them =====
Line 91: Line 92:
 </​code>​ </​code>​
  
-Well, it might be useful in one or the other situation, ​but this way +While useful in another ​situation, this way is lacks flexibility. 
-is not very flexibleYou're fixed in your maximum number of arguments+The maximum number of arguments ​is a fixedvalue
 - which is a bad idea if you write a script that takes many filenames - which is a bad idea if you write a script that takes many filenames
 as arguments. as arguments.
Line 98: Line 99:
 => forget that one => forget that one
  
-==== Loopings ​====+==== Loops ====
  
 There are several ways to loop through the positional parameters. There are several ways to loop through the positional parameters.
Line 105: Line 106:
  
 You can code a [[syntax:​ccmd:​c_for | C-style for-loop]] using ''​$#''​ You can code a [[syntax:​ccmd:​c_for | C-style for-loop]] using ''​$#''​
-as end-value. On every iteration, the ''​shift''​-command is used to+as the end value. On every iteration, the ''​shift''​-command is used to
 shift the argument list: shift the argument list:
  
Line 117: Line 118:
 </​code>​ </​code>​
  
-Not very stylish, but okay, usable. The ''​numargs''​ variable is used +Not very stylish, but usable. The ''​numargs''​ variable is used 
-to store the initial value of ''​$#''​ because ​it will change ​due to the +to store the initial value of ''​$#''​ because ​the shift command 
-shifting.+will change ​it as the script runs.
  
 ---- ----
  
-Another way to iterate one-by-one ​is the ''​for''​-loop without given +Another way to iterate one argument at a time is the ''​for''​ loop 
-wordlist, it will use the positional parameters as wordlist ​then:+without ​given wordlist. The loop uses the positional parameters as wordlist:
  
 <​code>​ <​code>​
Line 132: Line 133:
 done done
 </​code>​ </​code>​
-__Advantage:​__ The positional parameters will be preserved ​and not shifted into nirvana!+__Advantage:​__ The positional parameters will be preserved
  
 ---- ----
  
-The next way is similar to the first example (the ''​for''​-loop), but+The next method ​is similar to the first example (the ''​for''​ loop), but
 it doesn'​t test for reaching ''​$#''​. It shifts and checks if ''​$1''​ it doesn'​t test for reaching ''​$#''​. It shifts and checks if ''​$1''​
 still expands to something, using the [[commands:​classictest | test command]]: still expands to something, using the [[commands:​classictest | test command]]:
Line 148: Line 149:
 </​code>​ </​code>​
  
-Looks nice, but it has the disadvantage ​to stop when ''​$1''​ is empty+Looks nice, but has the disadvantage ​of stopping ​when ''​$1''​ is empty
 (null-string). Let's modify it to run as long as ''​$1''​ is defined (null-string). Let's modify it to run as long as ''​$1''​ is defined
-(but may be empty), using [[syntax:​pe#​use_an_alternate_value | parameter expansion for an alternate value]]:+(but may be null), using [[syntax:​pe#​use_an_alternate_value | parameter expansion for an alternate value]]:
  
 <​code>​ <​code>​
Line 167: Line 168:
 ==== All Positional Parameters ==== ==== All Positional Parameters ====
  
-Sometimes it's necessary to just "​relay"​ or "hand through" given+Sometimes it's necessary to just "​relay"​ or "pass" given
 arguments to another program. It's very inefficient to do that in one arguments to another program. It's very inefficient to do that in one
-of these loops, ​also you will destroy integrity, most likely+of these loops, ​as you will destroy integrity, most likely
 (spaces!). (spaces!).
  
-The shell-developers ​invented ​''​$*''​ and ''​$@''​ for this purpose.+The shell developers ​created ​''​$*''​ and ''​$@''​ for this purpose.
  
-As overwiew:+As overview:
  
 ^Syntax ​     ^Effective result ​                ^ ^Syntax ​     ^Effective result ​                ^
Line 182: Line 183:
 |  ''"​$@"'' ​ |  ''"​$1"​ "​$2"​ "​$3"​ ... "​${N}"'' ​ | |  ''"​$@"'' ​ |  ''"​$1"​ "​$2"​ "​$3"​ ... "​${N}"'' ​ |
  
-You see that without ​being quoted (double-quoted), both have the same +Without ​being quoted (double ​quotes), both have the same 
-effect: All positional parameters from ''​$1''​ to the last used one are +effect: All positional parameters from ''​$1''​ to the last one used are 
-expanded without any specials. A subsequent wordsplitting will +expanded without any special handling.
-recognize as much words as expanded before (i.e. it "​doesn'​t preserve +
-words"​).+
  
-When the ''​$*''​ special parameter is doublequoted, it expands to the+When the ''​$*''​ special parameter is double quoted, it expands to the
 equivalent of: ''"​$1c$2c$3c$4c........$N"'',​ where '​c'​ is the first equivalent of: ''"​$1c$2c$3c$4c........$N"'',​ where '​c'​ is the first
 character of ''​IFS''​. character of ''​IFS''​.
  
-But when the ''​$@''​ special parameter is used inside ​doublequotes, it+But when the ''​$@''​ special parameter is used inside ​double quotes, it
 expands to the equivanent of... expands to the equivanent of...
  
 ''"​$1"​ "​$2"​ "​$3"​ "​$4"​ ..... "​$N"''​ ''"​$1"​ "​$2"​ "​$3"​ "​$4"​ ..... "​$N"''​
  
-...which **exactly ​reflects all positional parameters ​like they were +...which **reflects all positional parameters ​as they were 
-initially ​set** and given to the script or the function. If you want+set initially** and passed ​to the script or function. If you want
 to re-use your positional parameters to **call another program** (for to re-use your positional parameters to **call another program** (for
-example in a wrapper-script),​ then this is the choice for you, use the +example in a wrapper-script),​ then this is the choice for you, use 
-doublequoted ​''"​$@"''​.+double quoted ​''"​$@"''​.
  
 Well, let's just say: **You almost always want a quoted ''"​$@"''​!** Well, let's just say: **You almost always want a quoted ''"​$@"''​!**
Line 207: Line 206:
 ==== Range Of Positional Parameters ==== ==== Range Of Positional Parameters ====
  
-Another way to mass-expand the positional parameters is similar to +Another way to mass expand the positional parameters is similar to 
-what is possible for a range of characters using the+what is possible for a range of characters using
 [[syntax:​pe#​substring_expansion | substring expansion]] on normal [[syntax:​pe#​substring_expansion | substring expansion]] on normal
-parameters and the range mass expansion of [[syntax:​arrays | arrays]].+parameters and the mass expansion ​range of [[syntax:​arrays | arrays]].
  
 ''​${@:​START:​COUNT}''​ ''​${@:​START:​COUNT}''​
Line 220: Line 219:
 ''"​${*:​START:​COUNT}"''​ ''"​${*:​START:​COUNT}"''​
  
-The rules for using ''​@''​ or ''​*''​ and the quoting are the same as+The rules for using ''​@''​ or ''​*''​ and quoting are the same as
 above. This will expand ''​COUNT''​ number of positional parameters above. This will expand ''​COUNT''​ number of positional parameters
-starting ​at ''​START''​. ''​COUNT''​ can be omitted (''​${@:​START}''​),​ in +beginning ​at ''​START''​. ''​COUNT''​ can be omitted (''​${@:​START}''​),​ in 
-this case all positional parameters beginning at ''​START''​ are+which caseall positional parameters beginning at ''​START''​ are
 expanded. expanded.
  
-If ''​START''​ is negative, the positional parameters are numbered ​from +If ''​START''​ is negative, the positional parameters are numbered ​in reverse 
-the last one backwards.+starting with the last one.
  
-''​COUNT''​ may not be negative, ​so elements are always counted in the +''​COUNT''​ may not be negative, ​i.e. the element count may not be decremented.
-forward direction.+
  
 __**Example:​**__ __**Example:​**__
Line 238: Line 236:
 </​code>​ </​code>​
  
-:V4: __**Attention**__: ​Since Bash 4, a ''​START''​ of ''​0''​ includes the special parameter ''​$0'',​ i.e. the shell name or whatever ​it'​s ​set to, when the positional parameters are in use. A ''​START''​ of ''​1''​ begins at ''​$1''​. In Bash 3 and older, both ''​0''​ and ''​1''​ began at ''​$1''​.+__**Attention**__: ​As of Bash 4, a ''​START''​ of ''​0''​ includes the special parameter ''​$0'',​ i.e. the shell name or whatever ​$0 is set to, when the positional parameters are in use. A ''​START''​ of ''​1''​ begins at ''​$1''​. In Bash 3 and older, both ''​0''​ and ''​1''​ began at ''​$1''​.
  
 ===== Setting Positional Parameters ===== ===== Setting Positional Parameters =====
  
-Letting the caller set the positional parameters, ​by giving parameters +Setting ​positional parameters ​with command line arguments
-on commandline, ​is not the only way to set them. +is not the only way to set them. 
-The [[ commands:​builtin:​set | set builtin command ]] +The [[ commands:​builtin:​set | builtin command, set ]] 
-can be used to "​artificially"​ change the positional parameters from+may be used to "​artificially"​ change the positional parameters from
 inside the script or function: inside the script or function:
  
Line 261: Line 259:
  
 It's wise to signal "end of options"​ when setting positional It's wise to signal "end of options"​ when setting positional
-parameters this way. If not, dashes might be interpreted as option ​tag+parameters this way. If not, the dashes might be interpreted as an option ​swich
 by ''​set''​ itself: by ''​set''​ itself:
  
Line 276: Line 274:
 ==== Using a while loop ==== ==== Using a while loop ====
  
-To make your program accept options ​like standard command ​with syntax:+To make your program accept options ​as standard command syntax:
  
 ''​COMMAND [options] <​params>'' ​ # Like 'cat -A file.txt'​ ''​COMMAND [options] <​params>'' ​ # Like 'cat -A file.txt'​
Line 286: Line 284:
 <​code>​ <​code>​
 #!/bin/sh #!/bin/sh
-By keeping ​options in alphabetical orderit'​s ​easy to add more.+Keeping ​options in alphabetical order makes it easy to add more.
  
 while : while :
Line 306: Line 304:
       -v | --verbose)       -v | --verbose)
           #  It's better to assign a string, than a number like "​verbose=1"​           #  It's better to assign a string, than a number like "​verbose=1"​
-   #  because if you're debugging script with "bash -x" code like this:+   #  because if you're debugging ​the script with "bash -x" code like this:
    #    #
    #    if [ "​$verbose"​ ] ...    #    if [ "​$verbose"​ ] ...
Line 339: Line 337:
 ==== Filter unwanted options with a wrapper script ==== ==== Filter unwanted options with a wrapper script ====
  
-This simple wrapper ​allows to filter ​unwanted options (here: ''​-a''​ +This simple wrapper ​enables filtering ​unwanted options (here: ''​-a''​ 
-and ''​--all''​ for ''​ls''​) out of the commandline. It reads the +and ''​--all''​ for ''​ls''​) out of the command line. It reads the 
-positional parameters and builds a (filteredarray out of them, then +positional parameters and builds a filtered array consisting ​of them, then 
-it calls ''​ls''​ with the new option set. It also respects the ''​--''​+calls ''​ls''​ with the new option set. It also respects the ''​--''​
 as "end of options"​ for ''​ls''​ and doesn'​t change anything after it: as "end of options"​ for ''​ls''​ and doesn'​t change anything after it:
  
  • scripting/posparams.txt
  • Last modified: 2018/05/12 18:04
  • by wayeoyuz