carstenh asked in IRC how
to make a shebang for mksh(1) scripts that works on both regular Unix
and Android.
This is not as easy as it looks, though. Most Unicēs will have mksh installed, either manually or by
means of the native package system
... [More]
, as /bin/mksh. Some put it
into package manager-specific directories; I saw /sw/bin/mksh,
/usr/local/bin/mksh and /usr/pkg/bin/mksh so far.
Some systems have it as /usr/bin/mksh but these are usually
those who got poettering’d and have /bin a symlink anyway.
Most of these systems also have env(1) as /usr/bin/env.
Android, on the contrary, ships with precisely one shell. This has
been mksh for a while, thankfully. There is, however, neither
a /bin nor a /usr directory. mksh usually lives as
/system/bin/mksh, with /system/bin/sh a symlink(7)
to the former location. Some broken Android versions ship the binary
in the latter location instead and do not ship anything that matches
mksh on the $PATH, but I hope they merge my AOSP patch to
revert this bad change (especially as some third-party Android toolkits
overwrite /system/bin/sh with busybox sh or GNU bash and you’d
lose mksh in the progress). However, on all official Android systems,
mksh is the system shell. This will be important later.
The obvious and correct fix is, of course, to chmod -x the
scripts and call them explicitly as mksh scriptname. This is
not always possible or desirable; sometimes, people will wish it to be
in the $PATH and executable, so we need a different solution.
There’s a neat trick with shebangs – the absence of one is handled
specifically by most systems in various ways. I remember reading
about it, but don’t remember where; I can’t find it on Sven Mascheck’s
excellent pages… but: the C shell variants run a script with the Bourne
Shell if its first line is a sole colon (‘:’), the Bourne family shells
run it with themselves or ${EXECSHELL:-/bin/sh} in those cases,
and the kernel with the system shell, AFAIK. So we have a way to get most
things that could call the script to interpret it as Bourne/POSIX shell
script on most systems. Then we just have to add a Bourne shell scriptlet
that switches to mksh iff the current shell isn’t it (lksh, or something
totally different). On Android, there is only ever one shell (or the
toolkit installer better preserve mksh as mksh), so this doesn’t do
anything (I hope – but did not test – that the kernel invokes the system
shell correctly despite it not lying under /bin/sh) nor does
it need to.
This leaves us with the following “shebang”:
:
case ${KSH_VERSION-} in
*MIRBSD\ KSH*) ;;
*) # re-run with The MirBSD Korn Shell, this is an mksh-specific script
test "${ZSH_VERSION+set}" = set && alias -g '${1+"$@"}'='"$@"'
exec mksh "$0" ${1+"$@"}
echo >&2 E: mksh re-exec failed, should not happen
exit 127 ;;
esac
The case argument not only does not need to,
but actually should not be quoted; the expansion is a set -u
guard; the entire scriptlet is set -e safe as well; comments
and expansions are safe. exec shall not return, but if it
does (GNU bash violates POSIX that way, for example), we use POSIX’
appropriate errorlevel. zsh is funny with the Bourne shell’s way of
using "$@" properly. But this should really be portable.
The snippet is both too short and too obvious (“only way to do it”)
to be protected by copyright law.
Thanks to carstenh and Ypnose for discussing things
like this with us in IRC, sending in
bugfixes (and changes we decline, with reason), etc. – it feels like we
have a real community, not just consuments ☺
[Less]
|
carstenh asked in IRC how
to make a shebang for mksh(1) scripts that works on both regular Unix
and Android.
This is not as easy as it looks, though. Most Unicēs will have mksh installed, either manually or by
means of the native package system
... [More]
, as /bin/mksh. Some put it
into package manager-specific directories; I saw /sw/bin/mksh,
/usr/local/bin/mksh and /usr/pkg/bin/mksh so far.
Some systems have it as /usr/bin/mksh but these are usually
those who got poettering’d and have /bin a symlink anyway.
Most of these systems also have env(1) as /usr/bin/env.
Android, on the contrary, ships with precisely one shell. This has
been mksh for a while, thankfully. There is, however, neither
a /bin nor a /usr directory. mksh usually lives as
/system/bin/mksh, with /system/bin/sh a symlink(7)
to the former location. Some broken Android versions ship the binary
in the latter location instead and do not ship anything that matches
mksh on the $PATH, but I hope they merge my AOSP patch to
revert this bad change (especially as some third-party Android toolkits
overwrite /system/bin/sh with busybox sh or GNU bash and you’d
lose mksh in the progress). However, on all official Android systems,
mksh is the system shell. This will be important later.
The obvious and correct fix is, of course, to chmod -x the
scripts and call them explicitly as mksh scriptname. This is
not always possible or desirable; sometimes, people will wish it to be
in the $PATH and executable, so we need a different solution.
There’s a neat trick with shebangs — the absence of one is handled
specifically by most systems in various ways. I remember reading
about it, but don’t remember where; I can’t find it on Sven Mascheck’s
excellent pages… but: the C shell variants run a script with the Bourne
Shell if its first line is a sole colon (‘:’), the Bourne family shells
run it with themselves or ${EXECSHELL:-/bin/sh} in those cases,
and the kernel with the system shell, AFAIK. So we have a way to get most
things that could call the script to interpret it as Bourne/POSIX shell
script on most systems. Then we just have to add a Bourne shell scriptlet
that switches to mksh iff the current shell isn’t it (lksh, or something
totally different). On Android, there is only ever one shell (or the
toolkit installer better preserve mksh as mksh), so this doesn’t do
anything (I hope — but did not test — that the kernel invokes the system
shell correctly despite it not lying under /bin/sh) nor does
it need to.
This leaves us with the following “shebang”:
:
case ${KSH_VERSION-} in
*MIRBSD\ KSH*) ;;
*) # re-run with The MirBSD Korn Shell, this is an mksh-specific script
test "${ZSH_VERSION+set}" = set && alias -g '${1+"$@"}'='"$@"'
exec mksh "$0" ${1+"$@"}
echo >&2 E: mksh re-exec failed, should not happen
exit 127 ;;
esac
The case argument not only does not need to,
but actually should not be quoted; the expansion is a set -u
guard; the entire scriptlet is set -e safe as well; comments
and expansions are safe. exec shall not return, but if it
does (GNU bash violates POSIX that way, for example), we use POSIX’
appropriate errorlevel. zsh is funny with the Bourne shell’s way of
using "$@" properly. But this should really be portable.
The snippet is both too short and too obvious (“only way to do it”)
to be protected by copyright law.
Thanks to carstenh and Ypnose for discussing things
like this with us in IRC, sending in
bugfixes (and changes we decline, with reason), etc. — it feels like we
have a real community, not just consuments ☺
[Less]
|
Posted
almost 9 years
ago
by
Thorsten Glaser
https://bugs.launchpad.net/~mirabilos
|
Posted
almost 9 years
ago
by
Thorsten Glaser
|
Please test mksh-current from CVS (or
the inofficial git mirror)!
There are security-related fixes I’ll MFC in a few days, for which I’d
prefer for them (and the other changes) to not introduce any regressions.
Thanks!
|
Please test mksh-current from CVS (or
the inofficial git mirror)!
There are security-related fixes I’ll MFC in a few days, for which I’d
prefer for them (and the other changes) to not introduce any regressions.
Thanks!
|
Please test mksh-current from CVS (or
the inofficial git mirror)!
There are security-related fixes I’ll MFC in a few days, for which I’d
prefer for them (and the other changes) to not introduce any regressions.
Thanks!
|
Posted
about 9 years
ago
by
Thorsten Glaser
https://bugs.launchpad.net/~mirabilos
|
Posted
about 9 years
ago
by
Thorsten Glaser
|
I implemented <? support (including <?php…)
script embedding support for *.inc in MirWebseite today; the
specific syntax was explicitely requested by Natureshadow. Ugh.
My own hacking activities are progressing, even if slowly. I do some
... [More]
other interesting, funny, social, beneficial, etc. stuff in between, though.
I’ll even have to get some of my DD buddies to sponsor me some QA uploads
of packages I formerly maintained, whereever changes are queued up… such as
better old-format repo compatibility in cvs(GNU) ☺ Though some of the stuff
I do at work is currently done only there… sorry.
Also: prepare to be fully enlightened about just what
evil (nice picture) Docker
is. I especially liked the comparison of containers to a herd of cattle,
mere numbers, replaceable, whereas VMs are cats, each with their individual
name, lovely petted each day, etc.
ObHint: Some may have noticed I do have a Twitter account now. I do not
really use it much. I got it because I wanted to rant at someone who only
gave Twitter as means to contact them (a European company running a lottery
for USA citizens only). But I found one nice thing: @HourlyCats (though
@FacesPics and @BahnAnsagen are funny too, and the Postillon anyway).
The internet is there for cat content, anyway.Ahem. Do not contact
me there, use IRC, more specifically, the
Freenode network, and possibly memoserv to mirabilos
instead, I can’t fit things into 140 chars, that’s just ridiculous. Also,
don’t follow me. It may contain rants, it’s NSFW, and I’m not censoring
there. As I said: I do not use it. So should you. (But kudos for having a
mostly functional “fallback” site (the “mobile” one), which even works in
PocketIE (Windows Mobile) and Opera 9, though not so much lynx(1)…)
odc (from #!/bin/mksh on IRC) is hacking support to use mksh instead of GNU bash for bootstrapping
pkgsrc® (e.g. on Solaris). Nice! Good luck!
… à propos mksh(1), dear Debian armel and armhf buildd
maintainer colleagues, pretty please with strawberries and chocolate ice
on top (I just had that on waffles at my favourite ice salon, so I may be
biased), do like s390x and update your chroots and wanna-build give-back mksh, as we
requested, so the privacy fix makes it into jessie. Thanks in advance!
Oh, and Y_Plentyn and I both have been putting more and updated packages into
my APT repository.
XTaran held a talk at CLT 2015 mentioning it… maybe I should write up some
docs about how to use it for which purposes (e.g. how to avoid systemd but
not get the other packages from it, or how to use it with systemd (trivial
but has to be stated, it’s freedom of choice after all), etc.)?
Besides decent fanfiction (the stories in the Uzumaki Naruto universe
seem, on average, to be much longer than those in the Harry Potter one), the
weather is becoming good, so I’ve already been enjoying going out for some
geocaching and will have the bike fixed at the shop RSN (it suffers a bit
each winter, as it stands outside, since our basement is mouldy, which is
worse than a bit of rust IMHO) to get more activity in. Also planning to
head to the GPS Maze in Mainz and, besides what time FrOSCon (including
preparation) allows, heading to DebConf for a while.
(read more…) [Less]
|