You are not logged in.
I've seen a few install files with the following lines at the end.
op=$1
shift
$op $*
This is not in any of the defined functions, such as `post_install(){…}`, but just added at the end of the file. What is the purpose of these lines?
FWIW I've seen it in some vimdoc.install files, but it's missing in others. The lack of these lines doesn't seem to affect the install; both work fine.
Last edited by Salkay (2016-07-11 00:45:14)
Offline
It's bash. From man shift
NAME
shift — shift positional parameters
SYNOPSIS
shift [n]
DESCRIPTION
The positional parameters shall be shifted. Positional parameter 1 shall be assigned the value of parameter (1+n),
parameter 2 shall be assigned the value of parameter (2+n), and so on. The parameters represented by the numbers
"$#" down to "$#−n+1" shall be unset, and the parameter '#' is updated to reflect the new number of positional
parameters.
The value n shall be an unsigned decimal integer less than or equal to the value of the special parameter '#'. If n
is not given, it shall be assumed to be 1. If n is 0, the positional and special parameters are not changed.
op=$1 is a variable assignment. The name is op and the content is whatever content $1 has. $something calls a variable assigned by something="value", so $something contains "value".
$1 is a positional parameter. Assimilate this information: http://wiki.bash-hackers.org/scripting/posparams
$* (as you can find out by asking google for "$* in shell script"), is, according to man bash 1:
* Expands to the positional parameters, starting from one. When the expansion is not within double quotes,
each positional parameter expands to a separate word. In contexts where it is performed, those words are
subject to further word splitting and pathname expansion. When the expansion occurs within double quotes, it
expands to a single word with the value of each parameter separated by the first character of the IFS special
variable. That is, "$*" is equivalent to "$1c$2c...", where c is the first character of the value of the IFS
variable. If IFS is unset, the parameters are separated by spaces. If IFS is null, the parameters are
joined without intervening separators.
@ Expands to the positional parameters, starting from one. When the expansion occurs within double quotes,
each parameter expands to a separate word. That is, "$@" is equivalent to "$1" "$2" ... If the double-
quoted expansion occurs within a word, the expansion of the first parameter is joined with the beginning part
of the original word, and the expansion of the last parameter is joined with the last part of the original
word. When there are no positional parameters, "$@" and $@ expand to nothing (i.e., they are removed).
So, it's a special variable for shell scripts (and functions in bash) for all parameters (a string of parameters. Unless you know what you're doing, you might want to use $@ instead. Example:
myscript --option1 -o2 -o3 -o4 some_file_name some_more_file_names
Then $@ (and respectively $*) contain a string "--option1 -o2 -o3 -o4 some_file_name some_more_file_names". The difference between $@ and $* is the way they are being handled during any form of expansion.
In shorter terms, shift is what you use while looping over parameters of a script or a function to get rid of the ones you've already processed.
In your case (op=$1 and $op $*), I assume, that the parameters are commands understood by the shell. You can, for example (type it in bash to try it): myfancyvar=ls and then call $myfancyvar to get ls. So, if you give a list of parameters to a script and that script takes the first (op=$1) and turns it into a command (by calling plain $op) with the rest of the arguments ($*). Example:
myscript command_as_parameter -o1 -o2 -o3 -o4 some_file_name some_more_file_names more_stuff_because_we_love_stuff
Then calling myscript would, with op=$1;shift;$1 $* at some point run this:
command_as_parameter -o1 -o2 -o3 -o4 some_file_name some_more_file_names more_stuff_because_we_love_stuff
Two things you should consider:
1. It's Saturday 02:29 over here and I'm just cooling down from a party with a lot of booze. You should all that up yourself.
2. If you found some strange construct in anything related to vim, you should keep your fingers away from it, as it probably is some sort of magic incantation to prevent the invasion of malevolent unicorns from another realm.
Offline
Oh no! The maple syrup supply is once again in danger.
Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way
Offline
Oh no! The maple syrup supply is once again in danger.
I'm already dressed accordingly.
Offline
Wow, thanks for the in-depth reply, Awebb. That all makes sense. Essentially, if something calls vimdoc.install with `vimdoc.install foo bar bar`, then these additional lines will execute a literal `$ foo bar baz`. However, what arguments are ever sent to a PKGBUILD install script? Also, makepkg runs the functions in the install script as needed, but what is the purpose of the non-function parts?
Hopefully you don't have too much of a hangover to respond!
Offline
Unless 'op' is also used in another context that combination is odd. The following are equivalent:
op=$1
shift
$op $*
$@
"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" - Richard Stallman
Offline
Yes, it does seem odd to me too, especially since removing it has no obvious consequence. For reference, I first noticed it in a few PKGBUILDs that I inherited. e.g. vim-airline-git. However, I just had a further search and noticed it was also referenced in the Danish Arch wiki, although slightly differently.
op=$1
shift
$op "$@"
Note the difference in the third line, where it's $@ not $*. Further the article says, rather cryptically (courtesy of Google translate):
The three lines at the bottom required of all installation files so that they can be run properly.
Offline
They were needed at the bottom of install files many, many years ago. I amazed that they still exist.
Offline
Note the difference in the third line, where it's $@ not $*.
Actually it is "$@" not $*. I never use the latter form, I would only ever use $@ or "$@" myself, so I'm not an expert on the differences - but from my interpretation of the bash documentation, $@ and $* are always (functionally) equivalent while "$@" can be different.
But that does point to one way that the three lines could be better than the single one. Consider the scripts named foo.install and bar.install each starting with identical post_install functions but ending with the following:
## foo.install
"$@"
## bar.install
op=$1
shift
$op "$@"
Then consider the different effects of running the following:
foo.install post_install arg1 arg2 arg3
foo.install "post_install arg1 arg2 arg3"
bar.install post_install arg1 arg2 arg3
bar.install "post_install arg1 arg2 arg3"
In these cases foo.install will only work in the first form, the second will give a "post_install arg1 arg2 arg3: command not found". bar.install will work as intended in either case.
But that explains the difference between the 3 line invocation and one (although only if the $@ is quoted, otherwise this difference vanishes). As for the purpose of their presence at all it seems it was so the .install script could be executed with a function name as a parameter rather than being sourced as it is now.
"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" - Richard Stallman
Offline
Thanks for that information, Trilby. TBH I do often skim over quoting in my shell scripts, much to my chagrin as I test.
Thank you also for the information about the purpose of the lines in the first place. I'll just remove them in the future. Cheers!
Offline