1.\" $MirOS: src/bin/mksh/lksh.1,v 1.16 2015/12/12 22:25:14 tg Exp $ 2.\"- 3.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015 4.\" mirabilos <m@mirbsd.org> 5.\" 6.\" Provided that these terms and disclaimer and all copyright notices 7.\" are retained or reproduced in an accompanying document, permission 8.\" is granted to deal in this work without restriction, including un‐ 9.\" limited rights to use, publicly perform, distribute, sell, modify, 10.\" merge, give away, or sublicence. 11.\" 12.\" This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to 13.\" the utmost extent permitted by applicable law, neither express nor 14.\" implied; without malicious intent or gross negligence. In no event 15.\" may a licensor, author or contributor be held liable for indirect, 16.\" direct, other damage, loss, or other issues arising in any way out 17.\" of dealing in the work, even if advised of the possibility of such 18.\" damage or existence of a defect, except proven that it results out 19.\" of said person’s immediate fault when using the work as intended. 20.\"- 21.\" Try to make GNU groff and AT&T nroff more compatible 22.\" * ` generates ‘ in gnroff, so use \` 23.\" * ' generates ’ in gnroff, \' generates ´, so use \*(aq 24.\" * - generates ‐ in gnroff, \- generates −, so .tr it to - 25.\" thus use - for hyphens and \- for minus signs and option dashes 26.\" * ~ is size-reduced and placed atop in groff, so use \*(TI 27.\" * ^ is size-reduced and placed atop in groff, so use \*(ha 28.\" * \(en does not work in nroff, so use \*(en 29.\" * <>| are problematic, so redefine and use \*(Lt\*(Gt\*(Ba 30.\" Also make sure to use \& especially with two-letter words. 31.\" The section after the "doc" macropackage has been loaded contains 32.\" additional code to convene between the UCB mdoc macropackage (and 33.\" its variant as BSD mdoc in groff) and the GNU mdoc macropackage. 34.\" 35.ie \n(.g \{\ 36. if \*[.T]ascii .tr \-\N'45' 37. if \*[.T]latin1 .tr \-\N'45' 38. if \*[.T]utf8 .tr \-\N'45' 39. ds <= \[<=] 40. ds >= \[>=] 41. ds Rq \[rq] 42. ds Lq \[lq] 43. ds sL \(aq 44. ds sR \(aq 45. if \*[.T]utf8 .ds sL ` 46. if \*[.T]ps .ds sL ` 47. if \*[.T]utf8 .ds sR ' 48. if \*[.T]ps .ds sR ' 49. ds aq \(aq 50. ds TI \(ti 51. ds ha \(ha 52. ds en \(en 53.\} 54.el \{\ 55. ds aq ' 56. ds TI ~ 57. ds ha ^ 58. ds en \(em 59.\} 60.\" 61.\" Implement .Dd with the Mdocdate RCS keyword 62.\" 63.rn Dd xD 64.de Dd 65.ie \\$1$Mdocdate: \{\ 66. xD \\$2 \\$3, \\$4 67.\} 68.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 69.. 70.\" 71.\" .Dd must come before definition of .Mx, because when called 72.\" with -mandoc, it might implement .Mx itself, but we want to 73.\" use our own definition. And .Dd must come *first*, always. 74.\" 75.Dd $Mdocdate: December 12 2015 $ 76.\" 77.\" Check which macro package we use, and do other -mdoc setup. 78.\" 79.ie \n(.g \{\ 80. if \*[.T]utf8 .tr \[la]\*(Lt 81. if \*[.T]utf8 .tr \[ra]\*(Gt 82. ie d volume-ds-1 .ds tT gnu 83. el .ds tT bsd 84.\} 85.el .ds tT ucb 86.\" 87.\" Implement .Mx (MirBSD) 88.\" 89.ie "\*(tT"gnu" \{\ 90. eo 91. de Mx 92. nr curr-font \n[.f] 93. nr curr-size \n[.ps] 94. ds str-Mx \f[\n[curr-font]]\s[\n[curr-size]u] 95. ds str-Mx1 \*[Tn-font-size]\%MirOS\*[str-Mx] 96. if !\n[arg-limit] \ 97. if \n[.$] \{\ 98. ds macro-name Mx 99. parse-args \$@ 100. \} 101. if (\n[arg-limit] > \n[arg-ptr]) \{\ 102. nr arg-ptr +1 103. ie (\n[type\n[arg-ptr]] == 2) \ 104. as str-Mx1 \~\*[arg\n[arg-ptr]] 105. el \ 106. nr arg-ptr -1 107. \} 108. ds arg\n[arg-ptr] "\*[str-Mx1] 109. nr type\n[arg-ptr] 2 110. ds space\n[arg-ptr] "\*[space] 111. nr num-args (\n[arg-limit] - \n[arg-ptr]) 112. nr arg-limit \n[arg-ptr] 113. if \n[num-args] \ 114. parse-space-vector 115. print-recursive 116.. 117. ec 118. ds sP \s0 119. ds tN \*[Tn-font-size] 120.\} 121.el \{\ 122. de Mx 123. nr cF \\n(.f 124. nr cZ \\n(.s 125. ds aa \&\f\\n(cF\s\\n(cZ 126. if \\n(aC==0 \{\ 127. ie \\n(.$==0 \&MirOS\\*(aa 128. el .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 129. \} 130. if \\n(aC>\\n(aP \{\ 131. nr aP \\n(aP+1 132. ie \\n(C\\n(aP==2 \{\ 133. as b1 \&MirOS\ #\&\\*(A\\n(aP\\*(aa 134. ie \\n(aC>\\n(aP \{\ 135. nr aP \\n(aP+1 136. nR 137. \} 138. el .aZ 139. \} 140. el \{\ 141. as b1 \&MirOS\\*(aa 142. nR 143. \} 144. \} 145.. 146.\} 147.\"- 148.Dt LKSH 1 149.Os MirBSD 150.Sh NAME 151.Nm lksh 152.Nd Legacy Korn shell built on mksh 153.Sh SYNOPSIS 154.Nm 155.Bk -words 156.Op Fl +abCefhiklmnprUuvXx 157.Op Fl +o Ar opt 158.Oo 159.Fl c Ar string \*(Ba 160.Fl s \*(Ba 161.Ar file 162.Op Ar args ... 163.Oc 164.Ek 165.Sh DESCRIPTION 166.Nm 167is a command interpreter intended exclusively for running legacy 168shell scripts. 169It is built on 170.Nm mksh ; 171refer to its manual page for details on the scripting language. 172It is recommended to port scripts to 173.Nm mksh 174instead of relying on legacy or idiotic POSIX-mandated behaviour, 175since the MirBSD Korn Shell scripting language is much more consistent. 176.Pp 177Note that it's strongly recommended to invoke 178.Nm 179with at least the 180.Fl o Ic posix 181option, if not both that 182.Em and Fl o Ic sh , 183to fully enjoy better compatibility to the 184.Tn POSIX 185standard (which is probably why you use 186.Nm 187over 188.Nm mksh 189in the first place) or legacy scripts, respectively. 190.Sh LEGACY MODE 191.Nm 192currently has the following differences from 193.Nm mksh : 194.Bl -bullet 195.It 196.\"XXX TODO: remove (some systems may wish to have lksh as ksh) 197There is no explicit support for interactive use, 198nor any command line editing or history code. 199Hence, 200.Nm 201is not suitable as a user's login shell, either; use 202.Nm mksh 203instead. 204.It 205The 206.Ev KSH_VERSION 207string identifies 208.Nm 209as 210.Dq LEGACY KSH 211instead of 212.Dq MIRBSD KSH . 213Note that the rest of the version string is identical between 214the two shell flavours, and the behaviour and differences can 215change between versions; see the accompanying manual page 216.Xr mksh 1 217for the versions this document applies to. 218.It 219.Nm 220uses 221.Tn POSIX 222arithmetics, which has quite a few implications: 223The data type for arithmetics is the host 224.Tn ISO 225C 226.Vt long 227data type. 228Signed integer wraparound is Undefined Behaviour; this means that... 229.Bd -literal -offset indent 230$ echo $((2147483647 + 1)) 231.Ed 232.Pp 233\&... is permitted to, e.g. delete all files on your system 234(the figure differs for non-32-bit systems, the rule doesn't). 235The sign of the result of a modulo operation with at least one 236negative operand is unspecified. 237Shift operations on negative numbers are unspecified. 238Division of the largest negative number by \-1 is Undefined Behaviour. 239The compiler is permitted to delete all data and crash the system 240if Undefined Behaviour occurs (see above for an example). 241.It 242.Nm 243only offers the traditional ten file descriptors to scripts. 244.It 245.\"XXX TODO: move this to FPOSIX 246The rotation arithmetic operators are not available. 247.It 248The shift arithmetic operators take all bits of the second operand into 249account; if they exceed permitted precision, the result is unspecified. 250.It 251.\"XXX TODO: move this to FPOSIX 252The 253.Tn GNU 254.Nm bash 255extension &\*(Gt to redirect stdout and stderr in one go is not parsed. 256.It 257.\"XXX TODO: drop along with allowing interactivity 258The 259.Nm mksh 260command line option 261.Fl T 262is not available. 263.It 264Unless 265.Ic set -o posix 266is active, 267.Nm 268always uses traditional mode for constructs like: 269.Bd -literal -offset indent 270$ set -- $(getopt ab:c "$@") 271$ echo $? 272.Ed 273.Pp 274POSIX mandates this to show 0, but traditional mode 275passes through the errorlevel from the 276.Xr getopt 1 277command. 278.It 279.\"XXX TODO: move to FPOSIX/FSH 280Unlike 281.At 282.Nm ksh , 283.Nm mksh 284in 285.Fl o Ic posix 286or 287.Fl o Ic sh 288mode and 289.Nm lksh 290do not keep file descriptors \*(Gt 2 private from sub-processes. 291.It 292Functions defined with the 293.Ic function 294reserved word share the shell options 295.Pq Ic set -o 296instead of locally scoping them. 297.El 298.Sh SEE ALSO 299.Xr mksh 1 300.Pp 301.Pa https://www.mirbsd.org/mksh.htm 302.Pp 303.Pa https://www.mirbsd.org/ksh\-chan.htm 304.Sh CAVEATS 305The distinction between the shell variants 306.Pq Nm lksh / Nm mksh 307and shell flags 308.Pq Fl o Ic posix / Ic sh 309will be reworked for an upcoming release. 310.Pp 311To use 312.Nm 313as 314.Pa /bin/sh , 315compilation to enable 316.Ic set -o posix 317by default if called as 318.Nm sh 319is highly recommended for better standards compliance. 320For better compatibility with legacy scripts, such as many 321.Tn Debian 322maintainer scripts, Upstart and SYSV init scripts, and other 323unfixed scripts, using the compile-time options for enabling 324.Em both 325.Ic set -o posix -o sh 326when the shell is run as 327.Nm sh 328is recommended. 329.Pp 330.Nm 331tries to make a cross between a legacy bourne/posix compatibl-ish 332shell and a legacy pdksh-alike but 333.Dq legacy 334is not exactly specified. 335.Pp 336The 337.Ic set 338built-in command does not currently have all options one would expect 339from a full-blown 340.Nm mksh 341or 342.Nm pdksh . 343.Pp 344Talk to the 345.Mx 346development team using the mailing list at 347.Aq miros\-mksh@mirbsd.org 348or the 349.Li \&#\&!/bin/mksh 350.Pq or Li \&#ksh 351IRC channel at 352.Pa irc.freenode.net 353.Pq Port 6697 SSL, 6667 unencrypted 354if you need any further quirks or assistance, 355and consider migrating your legacy scripts to work with 356.Nm mksh 357instead of requiring 358.Nm . 359