Suppose you have a variable whose content you want to pass to a sub-process as argument to an option but only if that variable is set. Rather than if test -n "${var+1}"; then cmd -x "$var" else cmd fi I thought that cmd ${var+-x "$var"} would do the trick. Turns out that with most shells, it doesn't if $var is set but empty. - Dash 0.5.7 expands ��${var+something "$var"}�� to two words containing "something" and the value of $var respectively, which is what I wanted. - Ksh 93u+ omits the second word if $var is empty. - Bash 4.3.30 follows Ksh, on purpose or by accident. - Zsh 5.0.7 expands it to one word : "something $var". Haven't mustered the energy to dig into the standard to see which behaviours are compliant but I'm certainly curious. -- Andr� Majorel http://www.teaser.fr/~amajorel/ "Pauvret� n'est pas vice ! Parbleu ! Un vice est agr�able." -- _Passe-temps_
![]() |
0 |
![]() |
On 16.12.2016 13:26, Andre Majorel wrote: > Suppose you have a variable whose content you want to pass to a > sub-process as argument to an option but only if that variable > is set. > > Rather than > > if test -n "${var+1}"; then > cmd -x "$var" > else > cmd > fi > > I thought that > > cmd ${var+-x "$var"} > > would do the trick. Turns out that with most shells, it doesn't > if $var is set but empty. > > - Dash 0.5.7 expands � ${var+something "$var"} � to two words > containing "something" and the value of $var respectively, > which is what I wanted. > > - Ksh 93u+ omits the second word if $var is empty. Just to be sure; you say that ksh omits the second = _empty_ word? But this seems not to be true. If you quote your outer expression cmd "${var+-x "$var"}" you will see that ksh expands it to '-x ' (i.e. '-x <empty>'). But in case of cmd ${var+-x "$var"} the final space is removed before it's passed to cmd, since the expression is unquoted. To me this looks pretty much like standard behaviour. Janis > > - Bash 4.3.30 follows Ksh, on purpose or by accident. > > - Zsh 5.0.7 expands it to one word : "something $var". > > Haven't mustered the energy to dig into the standard to see > which behaviours are compliant but I'm certainly curious. >
![]() |
0 |
![]() |
On 16.12.2016 14:03, Janis Papanagnou wrote: > On 16.12.2016 13:26, Andre Majorel wrote: >> Suppose you have a variable whose content you want to pass to a >> sub-process as argument to an option but only if that variable >> is set. >> >> Rather than >> >> if test -n "${var+1}"; then >> cmd -x "$var" >> else >> cmd >> fi >> >> I thought that >> >> cmd ${var+-x "$var"} >> >> would do the trick. Turns out that with most shells, it doesn't >> if $var is set but empty. >> >> - Dash 0.5.7 expands � ${var+something "$var"} � to two words >> containing "something" and the value of $var respectively, >> which is what I wanted. >> >> - Ksh 93u+ omits the second word if $var is empty. > > Just to be sure; you say that ksh omits the second = _empty_ word? > > But this seems not to be true. If you quote your outer expression > > cmd "${var+-x "$var"}" > > you will see that ksh expands it to '-x ' (i.e. '-x <empty>'). But > in case of > > cmd ${var+-x "$var"} > > the final space is removed before it's passed to cmd, since the > expression is unquoted. To me this looks pretty much like standard > behaviour. PS (just in case it's not obvious from what I've written above): If you want the second argument to be there in any case, and also want to separate the option from the argument to pass to cmd, you can add single quotes around $var, as in cmd ${var+-x "'$var'"} You will get consistent output with ksh, bash, dash (and can likely let zsh behave that way as well with appropriate settings). Janis >> >> - Bash 4.3.30 follows Ksh, on purpose or by accident. >> >> - Zsh 5.0.7 expands it to one word : "something $var". >> >> Haven't mustered the energy to dig into the standard to see >> which behaviours are compliant but I'm certainly curious. >> >
![]() |
0 |
![]() |
On Friday, 16 December 2016 17:56:42 UTC+5:30, Andre Majorel wrote: > > Suppose you have a variable whose content you want to pass to a > sub-process as argument to an option but only if that variable > is set. > > Rather than > > if test -n "${var+1}"; then > cmd -x "$var" > else > cmd > fi > > > I thought that > > cmd ${var+-x "$var"} > > would do the trick. Turns out that with most shells, it doesn't > if $var is set but empty. > This would do the trick cmd ${var:+-x "$var"} Note the : before the +
![]() |
0 |
![]() |
On Fri, 16 Dec 2016 11:07:19 -0800, Rakesh Sharma wrote: > This would do the trick > cmd ${var:+-x "$var"} > > Note the : before the + Could you please give more notes on this solution? Regards -- ..: Hongyi Zhao [ hongyi.zhao AT gmail.com ] Free as in Freedom :.
![]() |
0 |
![]() |
Andre Majorel <cheney@halliburton.com>: > Suppose you have a variable whose content you want to pass to a > sub-process as argument to an option but only if that variable > is set. > > Rather than > > if test -n "${var+1}"; then > cmd -x "$var" > else > cmd > fi cmd ${var+"-x"} ${var+"$var"} will run cmd -x "$var" if var is set. Otherwise, it will run cmd
![]() |
0 |
![]() |
On Saturday, 17 December 2016 20:16:33 UTC+5:30, Helmut Waitzmann wrote: > > cmd ${var+"-x"} ${var+"$var"} > > will run > > cmd -x "$var" > > if var is set. Otherwise, it will run > > cmd > Just remember that a var can be set AND null. In that scenario cmd -x '' will happen. This is not what the OP wanted. This is somewhat subtle, that cmd sees 2 arguments, '-x' and an empty argument ''. The solution to this is the :+ meaning ${VAR:+alternate_value} => use the alternate value only when VAR is set AND nonnull otherwise replace everything with a null. Now this `otherwise' comprises cases of a variable that is set BUT null || a variable is not set. HTH
![]() |
0 |
![]() |
On Sat, 17 Dec 2016 13:57:42 -0800, Rakesh Sharma wrote: > Just remember that a var can be set AND null. In that scenario > cmd -x '' > will happen. This is not what the OP wanted. This is somewhat subtle, > that cmd sees 2 arguments, '-x' and an empty argument ''. What's the meaning of -x here? Regards -- ..: Hongyi Zhao [ hongyi.zhao AT gmail.com ] Free as in Freedom :.
![]() |
0 |
![]() |
On Sunday, 18 December 2016 05:25:24 UTC+5:30, Hongyi Zhao wrote: > > What's the meaning of -x here? > Nothing. It could be anything for that matter.
![]() |
0 |
![]() |
Hongyi Zhao wrote: > On Sat, 17 Dec 2016 13:57:42 -0800, Rakesh Sharma wrote: >> Just remember that a var can be set AND null. In that scenario >> cmd -x '' >> will happen. This is not what the OP wanted. This is somewhat subtle, >> that cmd sees 2 arguments, '-x' and an empty argument ''. > > What's the meaning of -x here? Placeholder for an option argument. -- PointedEars Twitter: @PointedEars2 Please do not cc me. / Bitte keine Kopien per E-Mail.
![]() |
0 |
![]() |
Rakesh Sharma <sharma__r@hotmail.com>: > On Saturday, 17 December 2016 20:16:33 UTC+5:30, Helmut Waitzmann wrote: > >>=20 >> cmd ${var+"-x"} ${var+"$var"} >>=20 >> will run >>=20 >> cmd -x "$var" >>=20 >> if var is set. Otherwise, it will run >>=20 >> cmd >>=20 > > Just remember that a var can be set AND null. In that scenario=20 > cmd -x '' > will happen.=20 That's correct. And if I understand the OP correctly, that is, what he wants. He wrote: Suppose you have a variable whose content you want to pass to a sub-process as argument to an option but only if that variable is set. In his statement, there is nothing about =E2=80=9Conly if that variable set and not null=E2=80=9D. > This is not what the OP wanted. As far as I understad the OP, he wished to achieve the semantics of the following =E2=80=9Cif=E2=80=9D command. He wrote: Rather than if test -n "${var+1}"; then cmd -x "$var" else cmd fi The condition of the =E2=80=9Cif=E2=80=9D statement will be true iff the va= riable =E2=80=9Cvar=E2=80=9D is set, not regarding whether null or not. And then he hoped to get those same semantics using a more compact syntax: I thought that cmd ${var+-x "$var"} would do the trick.=20 But then he learned, that this is not the case with most shells: Turns out that with most shells, it doesn't if $var is set but empty. - Dash 0.5.7 expands =C2=AB=C2=A0${var+something "$var"}=C2=A0=C2=BB to t= wo words containing "something" and the value of $var respectively, which is what I wanted. That is, he blesses Dash's behaviour and puts it in opposition to some different shells: - Ksh 93u+ omits the second word if $var is empty. Apparently he wishes, that Ksh wouldn't omit an empty $var. - Bash 4.3.30 follows Ksh, on purpose or by accident. - Zsh 5.0.7 expands it to one word : "something $var". Apparently he wishes, that Zsh wouldn't join the two words into one.
![]() |
0 |
![]() |
On Tuesday, 20 December 2016 20:54:02 UTC+5:30, Helmut Waitzmann wrote: >=20 > In his statement, there is nothing about =E2=80=9Conly if that variable > set and not null=E2=80=9D. >=20 No, the OP does mention about the set variable being null... >[OP] I thought that=20 >[OP] cmd ${var+-x "$var"}=20 >[OP] would do the trick. Turns out that with most shells, it doesn't=20 >[OP] if $var is set but empty.=20
![]() |
0 |
![]() |
On 2016-12-20, Helmut Waitzmann <nn.throttle@xoxy.net> wrote: > Rakesh Sharma <sharma__r@hotmail.com>: >> On Saturday, 17 December 2016 20:16:33 UTC+5:30, Helmut Waitzmann wrote: >> >>> >>> cmd ${var+"-x"} ${var+"$var"} >>> >>> will run >>> >>> cmd -x "$var" >>> >>> if var is set. Otherwise, it will run >>> >>> cmd >>> >> >> Just remember that a var can be set AND null. In that scenario >> cmd -x '' >> will happen. > > That's correct. And if I understand the OP correctly, that is, > what he wants. He wrote: > > Suppose you have a variable whose content you want to pass to a > sub-process as argument to an option but only if that variable > is set. > > In his statement, there is nothing about ???only if that variable > set and not null???. Right. I wrote "is set" and that is what I meant. Had I wanted the semantics of ${:+}, the phrasing would have included "non-empty" or something like that. >> This is not what the OP wanted. > > As far as I understad the OP, he wished to achieve the semantics > of the following ???if??? command. He wrote: > > Rather than > > if test -n "${var+1}"; then > cmd -x "$var" > else > cmd > fi > > The condition of the ???if??? statement will be true iff the variable > ???var??? is set, not regarding whether null or not. > > And then he hoped to get those same semantics using a more compact > syntax: > > I thought that > > cmd ${var+-x "$var"} > > would do the trick. > > But then he learned, that this is not the case with most shells: > > Turns out that with most shells, it doesn't if $var is set but > empty. > > - Dash 0.5.7 expands ��${var+something "$var"}�� to two words > containing "something" and the value of $var respectively, > which is what I wanted. > > That is, he blesses Dash's behaviour and puts it in opposition to > some different shells: > > - Ksh 93u+ omits the second word if $var is empty. > > Apparently he wishes, that Ksh wouldn't omit an empty $var. > > - Bash 4.3.30 follows Ksh, on purpose or by accident. > > - Zsh 5.0.7 expands it to one word : "something $var". > > Apparently he wishes, that Zsh wouldn't join the two words into > one. Right again. To my surprise, your syntax does get the desired result with Dash, Bash and Zsh. Ksh persists in omitting the second word (the one where the value of $var goes), though. No idea why a shell would expand ${var+-x} ${var+"$var"} differently from ${var+-x "$var"} but Bash and Zsh do. Well played. The Ksh exception doesn't bother me so much because I don't know of any platforms where a script beginning with "#!/bin/sh" would be executed by Ksh. I'd like to know whether the ��${var+-x} ${var+"$var"}�� syntax works in other Bourne and POSIX shells, however. -- Andr� Majorel http://www.teaser.fr/~amajorel/ "Pauvret� n'est pas vice ! Parbleu ! Un vice est agr�able." -- _Passe-temps_
![]() |
0 |
![]() |
On 2016-12-16, Janis Papanagnou <janis_papanagnou@hotmail.com> wrote: > On 16.12.2016 14:03, Janis Papanagnou wrote: >> On 16.12.2016 13:26, Andre Majorel wrote: >>> Suppose you have a variable whose content you want to pass to a >>> sub-process as argument to an option but only if that variable >>> is set. >>> >>> Rather than >>> >>> if test -n "${var+1}"; then >>> cmd -x "$var" >>> else >>> cmd >>> fi >>> >>> I thought that >>> >>> cmd ${var+-x "$var"} >>> >>> would do the trick. Turns out that with most shells, it doesn't >>> if $var is set but empty. >>> >>> - Dash 0.5.7 expands � ${var+something "$var"} � to two words >>> containing "something" and the value of $var respectively, >>> which is what I wanted. >>> >>> - Ksh 93u+ omits the second word if $var is empty. >> >> Just to be sure; you say that ksh omits the second = _empty_ word? Yes. >> But this seems not to be true. If you quote your outer expression >> >> cmd "${var+-x "$var"}" >> >> you will see that ksh expands it to '-x ' (i.e. '-x <empty>'). Ah yes, but then the expression would be expanded into one word, which is not the objective. >> But in case of >> >> cmd ${var+-x "$var"} >> >> the final space is removed before it's passed to cmd, since the >> expression is unquoted. To me this looks pretty much like standard >> behaviour. Does that means that Dash's behaviour is non-standard, then ? > PS (just in case it's not obvious from what I've written above): > If you want the second argument to be there in any case, and also > want to separate the option from the argument to pass to cmd, you > can add single quotes around $var, as in > > cmd ${var+-x "'$var'"} > > You will get consistent output with ksh, bash, dash (and can > likely let zsh behave that way as well with appropriate settings). This gives consistent results with Dash, Bash and Ksh but not useful ones (the inverted commas end up in argv[]). -- Andr� Majorel http://www.teaser.fr/~amajorel/ "Pauvret� n'est pas vice ! Parbleu ! Un vice est agr�able." -- _Passe-temps_
![]() |
0 |
![]() |
On 21.12.2016 15:41, Andre Majorel wrote: [...] > This gives consistent results with Dash, Bash and Ksh but not > useful ones (the inverted commas end up in argv[]). Ah, yes, you're right. I suppose it's probably best to use Helmut's suggestion - but in quoted form! - to keep the args (specifically the second one) together and also take an empty argument as an empty field instead of removing it cmd "${var+"-x"}" "${var+"$var"}" Janis
![]() |
0 |
![]() |
On 21.12.2016 15:27, Andre Majorel wrote: [...] > > The Ksh exception doesn't bother me so much because I don't know > of any platforms where a script beginning with "#!/bin/sh" would > be executed by Ksh. What about AIX ? Janis
![]() |
0 |
![]() |
Andre Majorel wrote: > On 2016-12-16, Janis Papanagnou <janis_papanagnou@hotmail.com> wrote: >> On 16.12.2016 14:03, Janis Papanagnou wrote: >>> On 16.12.2016 13:26, Andre Majorel wrote: >>>> […] >>>> I thought that >>>> >>>> cmd ${var+-x "$var"} >>>> >>>> would do the trick. Turns out that with most shells, it doesn't >>>> if $var is set but empty. >>>> >>>> - Dash 0.5.7 expands « ${var+something "$var"} » to two words >>>> containing "something" and the value of $var respectively, >>>> which is what I wanted. >>>> >>>> - Ksh 93u+ omits the second word if $var is empty. >>> >>> Just to be sure; you say that ksh omits the second = _empty_ word? > > Yes. > > […] >>> But in case of >>> >>> cmd ${var+-x "$var"} >>> >>> the final space is removed before it's passed to cmd, Which “final space” are you referring to? >>> since the expression is unquoted. To me this looks pretty much like >>> standard behaviour. > > Does that means that Dash's behaviour is non-standard, then ? According to POSIX.1-2008 chapter “2. Shell Command Language”, section “2.6.2 Parameter Expansion” [1], ${parameter+word} shall be substituted with “word” if “parameter” is “Set But Null” (whereas the standard uses “null” and “Null” to mean the string of length zero, presumably because then the NUL character would be the value in C). AIUI this means that ${var+something "$var"} shall be substituted with something "$var" if “var” is “Set But Null”. The standard also says: | If a parameter expansion occurs inside double-quotes: | | * Pathname expansion shall not be performed on the results of the | expansion. | | * Field splitting shall not be performed on the results of the | expansion. From which we can assume that if parameter expansion does _not_ occur inside double-quotes (so without quotes, as single-quotes would prevent expansion altogether), both pathname expansion and field splitting shall be performed. This is also substantiated by | 2.6.5 Field Splitting | | After parameter expansion (Parameter Expansion), […] the shell shall scan | the results of expansions and substitutions that did not occur in double- | quotes for field splitting and multiple fields can result. | | The shell shall treat each character of the IFS as a delimiter and use the | delimiters as field terminators to split the results of parameter | expansion, command substitution, and arithmetic expansion into fields. There are no pathnames, and field splitting with the default $IFS value would leave 'something' "$var" Since “$var” is syntactically a parameter reference, and parameter expansion is _not_ one of the forms of expansion that “shall not be performed on the results of the expansion” if it “occurs inside double-quotes”, the shell then shall perform parameter expansion again, substituting the above with 'something' "" because “If the parameter is not enclosed in braces, and is a name, the expansion shall use the longest valid name (see XBD Name), whether or not the variable represented by that name exists” and “The value, if any, of ‘parameter’ shall be substituted”, the empty string shall be substituted. So ISTM that there should be two words according to the standard, one non- empty and one empty, and as dash is doing that – test code: (x=''; printf '"%s"\n' ${x+-x "$x"}) –, it is standards-compliant there while the shells that do not are not. [1] <http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02> -- PointedEars Twitter: @PointedEars2 Please do not cc me. / Bitte keine Kopien per E-Mail.
![]() |
0 |
![]() |
On Wednesday, 21 December 2016 19:57:48 UTC+5:30, Andre Majorel wrote: >=20 > The Ksh exception doesn't bother me so much because I don't know > of any platforms where a script beginning with "#!/bin/sh" would > be executed by Ksh. I'd like to know whether the =C2=AB=C2=A0${var+-x} > ${var+"$var"}=C2=A0=C2=BB syntax works in other Bourne and POSIX shells, > however. >=20 I misunderstood the requirements of the OP, i.e. you, completely.=20 Helmut's suggestion is the perfect workaround for the issue at hand. What I'd like to point out is that the shell only expands into space-separa= ted words when the argument is a "$@" that is, ${var+"$@"} =3D> will yield multiple words even if some be empty set -- '-x' "${var-}" cmd ${var+"$@"}
![]() |
0 |
![]() |
Andre Majorel <cheney@halliburton.com>: > On 2016-12-20, Helmut Waitzmann <nn.throttle@xoxy.net> wrote: [Citing the OP:] >> - Dash 0.5.7 expands =C2=AB=C2=A0${var+something "$var"}=C2=A0=C2=BB t= o two words >> containing "something" and the value of $var respectively, >> which is what I wanted. > To my surprise, your syntax=20 [ ${var+-x} ${var+"$var"} ] > does get the desired result with Dash, Bash and Zsh. Ksh > persists in omitting the second word (the one where the value of > $var goes), though. Just to be sure: What does Ksh print, if given the command line var=3D'' ; printf '>%s<\n' ${var+-x} ${var+"$var"} to it? > I'd like to know whether the =C2=AB=C2=A0${var+-x} ${var+"$var"}=C2=A0=C2= =BB syntax > works in other Bourne and POSIX shells, however. As Thomas pointed out, at least in POSIX shells it should work. I'm not sure, whether POSIX mandates, that =E2=80=9C${var+-x "$var"}=E2=80=9D shall be the same as =E2=80=9C${var+-x} ${var+"$var"}=E2=80=9D, though.
![]() |
0 |
![]() |
On Thursday, 22 December 2016 05:05:05 UTC+5:30, Rakesh Sharma wrote: > > set -- '-x' "${var-}" > cmd ${var+"$@"} > Actually the following: set -- "${var-}" cmd ${var+-x "$@"}
![]() |
0 |
![]() |
On Friday, 16 December 2016 17:56:42 UTC+5:30, Andre Majorel wrote: > > Suppose you have a variable whose content you want to pass to a > sub-process as argument to an option but only if that variable > is set. > > > cmd ${var+-x "$var"} > > would do the trick. Turns out that with most shells, it doesn't > if $var is set but empty. > The answer to this is provided by the posix shell manual: **** If the complete expansion appropriate for a word results in an empty field, that empty field shall be deleted from the list of fields that form the completely expanded command, unless the original word contained single-quote or double-quote characters. **** http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
![]() |
0 |
![]() |
Janis Papanagnou <janis_papanagnou@hotmail.com> wrote: > On 21.12.2016 15:27, Andre Majorel wrote: > [...] >> >> The Ksh exception doesn't bother me so much because I don't know >> of any platforms where a script beginning with "#!/bin/sh" would >> be executed by Ksh. > > What about AIX ? Also Solaris (ksh93) and OpenBSD (pdksh).
![]() |
0 |
![]() |
On 2016-12-22, <william@wilbur.25thandClement.com> wrote: > Janis Papanagnou <janis_papanagnou@hotmail.com> wrote: >> On 21.12.2016 15:27, Andre Majorel wrote: >> [...] >>> >>> The Ksh exception doesn't bother me so much because I don't know >>> of any platforms where a script beginning with "#!/bin/sh" would >>> be executed by Ksh. >> >> What about AIX ? Are you asking me or telling me ? If the former, I can't recall, it's been too long. > Also Solaris (ksh93) and OpenBSD (pdksh). Are you saying that Solaris and OpenBSD symlink /bin/sh to some flavour of Ksh ? Don't know about OpenBSD but IME, Solaris comes with a very old pre-POSIX /bin/sh which couldn't possibly pass for Ksh. -- Andr� Majorel http://www.teaser.fr/~amajorel/ "Pauvret� n'est pas vice ! Parbleu ! Un vice est agr�able." -- _Passe-temps_
![]() |
0 |
![]() |
Andre Majorel <cheney@halliburton.com> writes: >Are you saying that Solaris and OpenBSD symlink /bin/sh to some >flavour of Ksh ? True in Solaris 11/11 (2011) and later. >Don't know about OpenBSD but IME, Solaris comes with a very old >pre-POSIX /bin/sh which couldn't possibly pass for Ksh. That is the case in Solaris 10 (2005) and earlier. Casper
![]() |
0 |
![]() |
On 2016-12-22, Helmut Waitzmann <nn.throttle@xoxy.net> wrote: > Andre Majorel <cheney@halliburton.com>: >> On 2016-12-20, Helmut Waitzmann <nn.throttle@xoxy.net> wrote: > > [Citing the OP:] > >>> - Dash 0.5.7 expands ��${var+something "$var"}�� to two words >>> containing "something" and the value of $var respectively, >>> which is what I wanted. > >> To my surprise, your syntax > > [ ${var+-x} ${var+"$var"} ] > >> does get the desired result with Dash, Bash and Zsh. Ksh >> persists in omitting the second word (the one where the value of >> $var goes), though. > > Just to be sure: What does Ksh print, if given the command line > > var='' ; printf '>%s<\n' ${var+-x} ${var+"$var"} > > to it? With Debian's ksh 93u+20120801 $ ksh <<\EOF var='' ; printf '>%s<\n' ${var+-x} ${var+"$var"} EOF >-x< Since william@ mentioned pdksh, I tried the nearest thing in Debian, MirBSD Ksh 50d-5 and had some luck : $ mksh <<\EOF var='' ; printf '>%s<\n' ${var+-x} ${var+"$var"} EOF >-x< >< Bash 4.3.30, Dash 0.5.7, mksh 50d, Posh 0.12.3 and Zsh 5.0.7 all get the same results. The odd man out is Ksh 93u+20120801. You can make Ksh produce an empty argument by following Janis' recommendation and putting double quotation marks around the second word as in either of the following : ${var+-x} "${var+"$var"}" ${var+-x} "${var+$var}" But that has the undesirable side-effet of creating an empty argument when the variable is unset. So far, we don't have any syntax that works in all cases and on all shells. >> I'd like to know whether the ��${var+-x} ${var+"$var"}�� syntax >> works in other Bourne and POSIX shells, however. > > As Thomas pointed out, at least in POSIX shells it should work. > > I'm not sure, whether POSIX mandates, that > > ???${var+-x "$var"}??? > > shall be the same as > > ???${var+-x} ${var+"$var"}???, though. -- Andr� Majorel http://www.teaser.fr/~amajorel/ "Pauvret� n'est pas vice ! Parbleu ! Un vice est agr�able." -- _Passe-temps_
![]() |
0 |
![]() |
On Thursday, 22 December 2016 17:17:22 UTC+5:30, Andre Majorel wrote: > > So far, we don't have any syntax that works in all cases and on > all shells. > You may try this on your various shells (I don't have access to them all): set 'X' '-x' "${var-}"; shift; cmd ${var+"$@"}
![]() |
0 |
![]() |
On 22.12.2016 11:59, Andre Majorel wrote: >> Janis Papanagnou <janis_papanagnou@hotmail.com> wrote: >>> On 21.12.2016 15:27, Andre Majorel wrote: >>> [...] >>>> >>>> The Ksh exception doesn't bother me so much because I don't know >>>> of any platforms where a script beginning with "#!/bin/sh" would >>>> be executed by Ksh. >>> >>> What about AIX ? > > Are you asking me or telling me ? It was meant as a hint. Since I assumed you may have missed it given the impression I got from your statement ("I don't know of any platforms") that you have inspected the common (including commercial) Unix platforms which you obviously didn't. Sorry, that this question mark was confusing. > > If the former, I can't recall, it's been too long. I do recall, and it had been the case at least until AIX 4.x. (Don't know about current AIX'es; but why should they change that? [just a rhetorical question here]) Janis > [...]
![]() |
0 |
![]() |
Andre Majorel wrote: > The Ksh exception doesn't bother me so much because I don't know > of any platforms where a script beginning with "#!/bin/sh" would > be executed by Ksh. http://www.in-ulm.de/~mascheck/various/shells/ tries to break down that in detail. But it does not try to judge age, market share, and alike, just collecting the very information.
![]() |
0 |
![]() |
Andre Majorel <cheney@halliburton.com> wrote: > On 2016-12-22, <william@wilbur.25thandClement.com> wrote: >> Janis Papanagnou <janis_papanagnou@hotmail.com> wrote: >>> On 21.12.2016 15:27, Andre Majorel wrote: >>> [...] >>>> >>>> The Ksh exception doesn't bother me so much because I don't know >>>> of any platforms where a script beginning with "#!/bin/sh" would >>>> be executed by Ksh. >>> >>> What about AIX ? > > Are you asking me or telling me ? That was Janis Papanagnou, not me. > If the former, I can't recall, it's been too long. /bin/sh on AIX is ksh88 $ uname -a AIX aix7 1 7 000ACFDE4C00 $ cmp /bin/sh /bin/ksh; echo RC=$? RC=0 >> Also Solaris (ksh93) and OpenBSD (pdksh). > > Are you saying that Solaris and OpenBSD symlink /bin/sh to some > flavour of Ksh ? Yes, except OpenBSD uses a hardlink. > Don't know about OpenBSD but IME, Solaris comes with a very old > pre-POSIX /bin/sh which couldn't possibly pass for Ksh. That changed 5 years ago with Solaris 11 solaris-11-3:~$ ls -go /bin/sh lrwxrwxrwx 1 11 Aug 16 15:39 /bin/sh -> amd64/ksh93 See https://blogs.oracle.com/OTNGarage/entry/new_shell_in_oracle_solaris
![]() |
0 |
![]() |
In article <585bb9c8$0$21513$e4fe514c@news.xs4all.nl>, Casper H.S. Dik <Casper.Dik@OrSPaMcle.COM> wrote: >Andre Majorel <cheney@halliburton.com> writes: > >>Are you saying that Solaris and OpenBSD symlink /bin/sh to some >>flavour of Ksh ? > >True in Solaris 11/11 (2011) and later. > >>Don't know about OpenBSD but IME, Solaris comes with a very old >>pre-POSIX /bin/sh which couldn't possibly pass for Ksh. > >That is the case in Solaris 10 (2005) and earlier. Well, Solaris now comes with ksh93 installed as /bin/sh and given that ksh93 is not POSIX compliant, the effect is pretty much the same: - You cannot expect a POSIX shell under /bin/sh - POSIX even does not require /bin/sh to be POSIX compliant. - PATH=`getconf PATH` sh gives you a POSIX shell and this is why #!/bin/sh in a script does not grant you a POSIX shell. AFAIK, the latter method still gives you a POSIX shell - even under Solaris 11, but I am not sure whether the POSIX shell you get on Solaris has been updated to follow recent changes and fixes in POSIX. Ksh93 is mainly POSIX compliant (so it is closer to the POSIX standard than the SVr4 Bourne Shell used by Solaris 10), but some of the builtins do not create the right output and some commands that must be implemented as builtins to work as documented are just aliases in ksh93. Note that the POSIX shell on Solaris is based on ksh88 but differs from ksh88 as even a vanilla ksh88 is not POSIX compliant. The behavior of the Solaris enhanced ksh88 is however frequently used by the POSIX commitee when investigating in shell behavior. Because of all these problems, the OpenSolaris based SchilliX uses an enhanced and expected to be POSIX compliant version of the Bourne Shell as /bin/sh, called "bosh". See: http://schilytools.sourceforge.net/bosh.html In general the idea used on recent Linux distros is not that bad: - use a mainly POSIX compliant shell as /bin/sh - Avoid kshisms and bashisms in system srcipts this way. Unfortunately, the shell usually used as /bin/sh on Linux (dash) does not implement support for multi-byte locales. This way, you can certify Linux only for "embedded use", as a full blown POSIX platform is expected to support "XSI" enhancements. BTW: "bosh" has been verified to work on Gentoo Linux when installed as /bin/sh. -- EMail:joerg@schily.net (home) J�rg Schilling D-13353 Berlin joerg.schilling@fokus.fraunhofer.de (work) Blog: http://schily.blogspot.com/ URL: http://cdrecord.org/private/ http://sf.net/projects/schilytools/files/
![]() |
0 |
![]() |
On 23.12.2016 10:49, Joerg.Schilling@fokus.fraunhofer.de wrote: > [...] > > Ksh93 is mainly POSIX compliant (so it is closer to the POSIX standard than the > SVr4 Bourne Shell used by Solaris 10), but some of the builtins do not create > the right output and some commands that must be implemented as builtins to work > as documented are just aliases in ksh93. ("just aliases"? - I suppose you don't mean aliases to builtins like fc/hist/history; or what would the issue be here? - Other predefined aliases seem to refer to ksh-specific commands, mostly typeset's, so I'd say there shouldn't be a relation to POSIX anyway in those cases.) Mind to be more specific on each of those points you mentioned, and elaborate on why it's non-POSIX, please? Janis > > [...]
![]() |
0 |
![]() |
On 2016-12-22, Andre Majorel <cheney@halliburton.com> wrote: >> Also Solaris (ksh93) and OpenBSD (pdksh). > > Are you saying that Solaris and OpenBSD symlink /bin/sh to some > flavour of Ksh ? OpenBSD's /bin/sh is (by now a somewhat modified) pdksh and has been for twenty years. I think it also behaves slightly different depending on whether it is called as sh or ksh, but that's already a level of detail that is of little practical interest in a world where too many people expect /bin/sh to be bash or, alternatively, /bin/bash to be universally available. -- Christian "naddy" Weisgerber naddy@mips.inka.de
![]() |
0 |
![]() |
Joerg.Schilling@fokus.fraunhofer.de wrote: <snip> > Note that the POSIX shell on Solaris is based on ksh88 but differs from ksh88 > as even a vanilla ksh88 is not POSIX compliant. The behavior of the Solaris > enhanced ksh88 is however frequently used by the POSIX commitee when > investigating in shell behavior. I didn't realize Solaris had a ksh88 variant. Cool. I guess I should have read the manual closer. I've encountered these two particularly annoying ksh88 bugs that required workarounds: # trap EXIT) ksh88 (confirmed AIX 7.1) wrongly executes an EXIT trap when # the calling function returns, rather than when the shell exits. Note # ksh93 does not exhibit this bug. # # $@ and null IFS) ksh88 (confirmed AIX 7.1) pdksh (confirmed pdksh 5.2.14) # and pdksh derivatives (confirmed OpenBSD 5.6 ksh, NetBSD 6.1 ksh) will # expand $@ as a single field if IFS is null (set but empty). As a # workaround we set IFS to a control character when juggling paths. ksh93, # bash, and ash correctly expand $@ when IFS is null. Testing /usr/xpg4/bin/sh on Solaris 11.3 (which the manual says is ksh88 + POSIX corrections), only the former is fixed. The latter issue remains. The script null_ifs() { IFS= set -- "$@" printf "\$# -> %d\n" $# } null_ifs 1 2 3 produces $# -> 1 instead of $# -> 3 It's a shame because it's possible to walk and juggle paths with embedded whitespace (including newlines) using POSIX shell semantics. It's not even that tricky as long as you can reliably disable field splitting and rely on positional parameters in lieu of arrays.[1] Every native (/bin/sh) shell I've tested gets it right except for the ksh88 derivatives. ksh93 might be less standard's compliant, but not all deviations are equal. [1] The latter--the ability to use positional parameters--probably isn't strictly necessary. Once or twice I've implemented "arrays" using serially incremented global names. But supporting 8-bit clean paths in my scripts is mostly an intellectual exercise on my part. Without the ability to easily pass lists of filenames to internal functions, it's not worth the bother to accomodate broken implementations. Thus the hack of using a control character.[2] [2] Interestingly, bash chokes on \1 as a field separator, producing wierd results. That's why I use \2 in the following routine for printing the string value for "null" IFS. # see porting note "$@ and null IFS" null_ifs() { IFS= set -- x y z set -- "$@" unset IFS [ $# -gt 1 ] || printf "\2" } That code will evaluate to the empty string for bash because it can handle a null IFS properly, but I didn't want to forget about that quirk of bash.
![]() |
0 |
![]() |