Date: Thu, 1 Apr 2021 11:36:14 -0400 From: Greg Wooledge <g...@wooledge.org> Message-ID: <YGXobn5/dqmiu...@wooledge.org>
| On Thu, Apr 01, 2021 at 01:36:59AM -0700, greyw...@starwolf.com wrote: | > The following is valid shell code: | > | > d=($(ls /usr/src/pkg/*/$1)); | | Syntactically valid, but semantically wrong. Greg managed to comment on everything in the original message, except the actual point of it ... Chet answered that, so I won't bother, but: | If $1 is not a directory, then you want: It is a directory, or I'd guess, quite likely a pattern chosen to find where the package that is wanted lives. The '/*/' represents a category grouping, and it is not unusual to not know which one applies to any particular package. My guess is that $1 might be something like *sed* to find any package with "sed" in its name. Or p5-* to select from the perl5 (script) packages. So: | d=(/usr/src/pkg/*/"$1") definitely not that, the quotes are wrong in any case (but apart from that, if filename expansion happens in array assignments (it doesn't in normal ones, and I dislike arrays, so ...) then without the quotes that might work. Alternatively d=( $( ls -d /usr/src/pkg/*/$1 ) ) or just d=( $( printf %s\\n /usr/src/pkg/*/$1 ) ) Just to be sure. Personally I'd do set -- /usr/src/pkg/*/$1 and then simply use the positional parameters. | If $1 is supposed to be a directory, and therefore you want only filenames | and not full pathnames in the array, It is, but he almost certainly wants the directory names, not the contents of the directories. He's going to want the full pathname so once selected, he can cd to it. | > cd ${dir} && | | Quotes. Yes. But it turns out not to matter in this case, as none of the names will ever contain anything but "normal" characters (no spaces, newlines, asterisks, ...) But that's the cd which requires dir to be the full pathname. | > make clean && { | > make update || | > make install; | > } | | Is the inner || supposed to be && by chance? Probably not. This is "if the package is already installed, update it, if not, install it". "make update" will succeed and update the package if needed, if it is installed already, otherwise it will fail. In that case make install will install it (it would fail if a some other version of the package was already installed). (The preceding "make clean" just gets rid of the left overs from any previous compilation, but will fail if there's insufficient permission, or similar, in which case attempting an update or install would also fail). | > if ((n > 1)); then { | > select dir in ${d[@]}; do { | > break; | > } done; | > } | | "${d[@]}" with quotes. Again, yes, but in practice here, not needed. | What purpose do the extra curly braces serve? Good question, wondered that myself. Note that if they were omitted the odd syntax issue wouldn't have arisen, as the done would follow "break;" and be recognised. After all that, and ignoring select's syntax (it was invented by ksh, long long ago, and isn't going to change) it is a dumb interface that can always be coded better using other mechanisms. And when you do that you can allow for much more flexible input than just the line number the select demands. If you avoid select, and avoid arrays, then any Bourne style shell will work. So, do that. kre