I am very much new in shell scripting and just got the below mentioned export of variable in shell :
export VAR_FILE=${*: -1}
Can anyone help me to understand this ,as I am not able to understand this
Ok, let's grab bash manual and go:
export variable[=value] - "Mark each name to be passed to child processes in the environment.". That means that if you run another process from this shell (ie. a subshell with a command: sh -c 'echo $variable') it will share the variable value.
$* - "($*) Expands to the positional parameters, starting from one.". For example: sh -c 'echo $1' -- 1, $1 will expand to the "first position argument". So $* expands to all positional parameters.
${parameter:offset:length} - This is named "substring expansion". It expands to characters starting at offset. If the paramter is * or @ it exapnds to positional parameter, ie: ${*:2:1} is equal to $2. You can also give negative offset, it then counts from the back. If you omit :length part, it assumes that length is infinite (to the end of string, to the last positional parameter).
${*:-1} - this will not work as you expect, cause ${parameter:-word} expands to 1 if $* is null or unset. That means that we need a space between :- so bash does not confuse substring expansion with :-.
${*: -1} - this will give you the last positional parameter. ie. sh -c 'echo ${*: -1}' -- 1 2 3 will output 3.
export VAR_FILE=${*: -1} - get's the last positional parameter, assigns it to VAR_FILE variable and set's that VAR_FILE variable will be exported to subprocesses.
$* is a special variable which expands to the list of positional parameters (arguments to your script), separated by a space character.
${list: -1} expands to the last element of a list.
So this sets the environment variable VAR_FILE to the last argument passed to the script.
Note that for an array that you define yourself, the syntax would be different:
list=( a b 'c d' )
export foo=${list[*]: -1} # list[*] instead of just *
* version works as well as @ -- they're in contexts where word splitting and glob expansion don't occur, and there's only one argument (/element) being extracted means that *'s usual problem of mushing multiple arguments together doesn't apply.
${!#}.