1.\" $MirOS: src/bin/mksh/lksh.1,v 1.25 2018/12/25 19:38:08 tg Exp $ 2.\"- 3.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2016, 2017, 2018 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 \& *before* a punctuation char that is to not 31.\" be interpreted as punctuation, and especially with two-letter words 32.\" but also (after) a period that does not end a sentence (“e.g.\&”). 33.\" The section after the "doc" macropackage has been loaded contains 34.\" additional code to convene between the UCB mdoc macropackage (and 35.\" its variant as BSD mdoc in groff) and the GNU mdoc macropackage. 36.\" 37.ie \n(.g \{\ 38. if \*[.T]ascii .tr \-\N'45' 39. if \*[.T]latin1 .tr \-\N'45' 40. if \*[.T]utf8 .tr \-\N'45' 41. ds <= \[<=] 42. ds >= \[>=] 43. ds Rq \[rq] 44. ds Lq \[lq] 45. ds sL \(aq 46. ds sR \(aq 47. if \*[.T]utf8 .ds sL ` 48. if \*[.T]ps .ds sL ` 49. if \*[.T]utf8 .ds sR ' 50. if \*[.T]ps .ds sR ' 51. ds aq \(aq 52. ds TI \(ti 53. ds ha \(ha 54. ds en \(en 55.\} 56.el \{\ 57. ds aq ' 58. ds TI ~ 59. ds ha ^ 60. ds en \(em 61.\} 62.\" 63.\" Implement .Dd with the Mdocdate RCS keyword 64.\" 65.rn Dd xD 66.de Dd 67.ie \\$1$Mdocdate: \{\ 68. xD \\$2 \\$3, \\$4 69.\} 70.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 71.. 72.\" 73.\" .Dd must come before definition of .Mx, because when called 74.\" with -mandoc, it might implement .Mx itself, but we want to 75.\" use our own definition. And .Dd must come *first*, always. 76.\" 77.Dd $Mdocdate: December 25 2018 $ 78.\" 79.\" Check which macro package we use, and do other -mdoc setup. 80.\" 81.ie \n(.g \{\ 82. if \*[.T]utf8 .tr \[la]\*(Lt 83. if \*[.T]utf8 .tr \[ra]\*(Gt 84. ie d volume-ds-1 .ds tT gnu 85. el .ie d doc-volume-ds-1 .ds tT gnp 86. el .ds tT bsd 87.\} 88.el .ds tT ucb 89.\" 90.\" Implement .Mx (MirBSD) 91.\" 92.ie "\*(tT"gnu" \{\ 93. eo 94. de Mx 95. nr curr-font \n[.f] 96. nr curr-size \n[.ps] 97. ds str-Mx \f[\n[curr-font]]\s[\n[curr-size]u] 98. ds str-Mx1 \*[Tn-font-size]\%MirBSD\*[str-Mx] 99. if !\n[arg-limit] \ 100. if \n[.$] \{\ 101. ds macro-name Mx 102. parse-args \$@ 103. \} 104. if (\n[arg-limit] > \n[arg-ptr]) \{\ 105. nr arg-ptr +1 106. ie (\n[type\n[arg-ptr]] == 2) \ 107. as str-Mx1 \~\*[arg\n[arg-ptr]] 108. el \ 109. nr arg-ptr -1 110. \} 111. ds arg\n[arg-ptr] "\*[str-Mx1] 112. nr type\n[arg-ptr] 2 113. ds space\n[arg-ptr] "\*[space] 114. nr num-args (\n[arg-limit] - \n[arg-ptr]) 115. nr arg-limit \n[arg-ptr] 116. if \n[num-args] \ 117. parse-space-vector 118. print-recursive 119.. 120. ec 121. ds sP \s0 122. ds tN \*[Tn-font-size] 123.\} 124.el .ie "\*(tT"gnp" \{\ 125. eo 126. de Mx 127. nr doc-curr-font \n[.f] 128. nr doc-curr-size \n[.ps] 129. ds doc-str-Mx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] 130. ds doc-str-Mx1 \*[doc-Tn-font-size]\%MirBSD\*[doc-str-Mx] 131. if !\n[doc-arg-limit] \ 132. if \n[.$] \{\ 133. ds doc-macro-name Mx 134. doc-parse-args \$@ 135. \} 136. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ 137. nr doc-arg-ptr +1 138. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \ 139. as doc-str-Mx1 \~\*[doc-arg\n[doc-arg-ptr]] 140. el \ 141. nr doc-arg-ptr -1 142. \} 143. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Mx1] 144. nr doc-type\n[doc-arg-ptr] 2 145. ds doc-space\n[doc-arg-ptr] "\*[doc-space] 146. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) 147. nr doc-arg-limit \n[doc-arg-ptr] 148. if \n[doc-num-args] \ 149. doc-parse-space-vector 150. doc-print-recursive 151.. 152. ec 153. ds sP \s0 154. ds tN \*[doc-Tn-font-size] 155.\} 156.el \{\ 157. de Mx 158. nr cF \\n(.f 159. nr cZ \\n(.s 160. ds aa \&\f\\n(cF\s\\n(cZ 161. if \\n(aC==0 \{\ 162. ie \\n(.$==0 \&MirBSD\\*(aa 163. el .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 164. \} 165. if \\n(aC>\\n(aP \{\ 166. nr aP \\n(aP+1 167. ie \\n(C\\n(aP==2 \{\ 168. as b1 \&MirBSD\ #\&\\*(A\\n(aP\\*(aa 169. ie \\n(aC>\\n(aP \{\ 170. nr aP \\n(aP+1 171. nR 172. \} 173. el .aZ 174. \} 175. el \{\ 176. as b1 \&MirBSD\\*(aa 177. nR 178. \} 179. \} 180.. 181.\} 182.\"- 183.Dt LKSH 1 184.Os MirBSD 185.Sh NAME 186.Nm lksh 187.Nd Legacy Korn shell built on mksh 188.Sh SYNOPSIS 189.Nm 190.Bk -words 191.Op Fl +abCefhiklmnprUuvXx 192.Op Fl +o Ar opt 193.Oo 194.Fl c Ar string \*(Ba 195.Fl s \*(Ba 196.Ar file 197.Op Ar args ... 198.Oc 199.Ek 200.Sh DESCRIPTION 201.Nm 202is a command interpreter intended exclusively for running legacy 203shell scripts. 204It is built on 205.Nm mksh ; 206refer to its manual page for details on the scripting language. 207It is recommended to port scripts to 208.Nm mksh 209instead of relying on legacy or objectionable POSIX-mandated behaviour, 210since the MirBSD Korn Shell scripting language is much more consistent. 211.Pp 212Do not use 213.Nm 214as an interactive or login shell; use 215.Nm mksh 216instead. 217.Pp 218Note that it's strongly recommended to invoke 219.Nm 220with 221.Fl o Ic posix 222to fully enjoy better compatibility to the 223.Tn POSIX 224standard (which is probably why you use 225.Nm 226over 227.Nm mksh 228in the first place); 229.Fl o Ic sh 230(possibly additionally to the above) may be needed for some legacy scripts. 231.Sh LEGACY MODE 232.Nm 233currently has the following differences from 234.Nm mksh : 235.Bl -bullet 236.It 237The 238.Ev KSH_VERSION 239string identifies 240.Nm 241as 242.Dq Li LEGACY KSH 243instead of 244.Dq Li MIRBSD KSH . 245Note that the rest of the version string is identical between 246the two shell flavours, and the behaviour and differences can 247change between versions; see the accompanying manual page 248.Xr mksh 1 249for the versions this document applies to. 250.It 251.Nm 252uses 253.Tn POSIX 254arithmetic, which has quite a few implications: 255The data type for arithmetic operations is the host 256.Tn ISO 257C 258.Vt long 259data type. 260Signed integer wraparound is Undefined Behaviour; this means that... 261.Bd -literal -offset indent 262$ echo $((2147483647 + 1)) 263.Ed 264.Pp 265\&... is permitted to, e.g. delete all files on your system 266(the figure differs for non-32-bit systems, the rule doesn't). 267The sign of the result of a modulo operation with at least one 268negative operand is unspecified. 269Shift operations on negative numbers are unspecified. 270Division of the largest negative number by \-1 is Undefined Behaviour. 271The compiler is permitted to delete all data and crash the system 272if Undefined Behaviour occurs (see above for an example). 273.It 274The rotation arithmetic operators are not available. 275.It 276The shift arithmetic operators take all bits of the second operand into 277account; if they exceed permitted precision, the result is unspecified. 278.It 279Unless 280.Ic set -o posix 281is active, 282.Nm 283always uses traditional mode for constructs like: 284.Bd -literal -offset indent 285$ set -- $(getopt ab:c "$@") 286$ echo $? 287.Ed 288.Pp 289POSIX mandates this to show 0, but traditional mode 290passes through the errorlevel from the 291.Xr getopt 1 292command. 293.It 294Functions defined with the 295.Ic function 296reserved word share the shell options 297.Pq Ic set -o 298instead of locally scoping them. 299.El 300.Sh SEE ALSO 301.Xr mksh 1 302.Pp 303.Pa http://www.mirbsd.org/mksh.htm 304.Pp 305.Pa http://www.mirbsd.org/ksh\-chan.htm 306.Sh CAVEATS 307To use 308.Nm 309as 310.Pa /bin/sh , 311compilation to enable 312.Ic set -o posix 313by default if called as 314.Nm sh 315.Pq adding Dv \-DMKSH_BINSHPOSIX to Dv CPPFLAGS 316is highly recommended for better standards compliance. 317.Pp 318For better compatibility with legacy scripts, such as many 319.Tn Debian 320maintainer scripts, Upstart and SYSV init scripts, and other 321unfixed scripts, also adding the 322.Dv \-DMKSH_BINSHREDUCED 323compile-time option to enable 324.Em both 325.Ic set -o posix -o sh 326when the shell is run as 327.Nm sh , 328as well as integrating the optional disrecommended 329.Xr printf 1 330builtin, might be necessary. 331.Pp 332.Nm 333tries to make a cross between a legacy bourne/posix compatibl-ish 334shell and a legacy pdksh-alike but 335.Dq legacy 336is not exactly specified. 337.Pp 338Talk to the 339.Mx 340development team and users using the mailing list at 341.Aq Mt miros\-mksh@mirbsd.org 342(please note the EU-DSGVO/GDPR notice on 343.Pa http://www.mirbsd.org/rss.htm#lists 344and in the SMTP banner!) or the 345.Li \&#\&!/bin/mksh 346.Pq or Li \&#ksh 347IRC channel at 348.Pa irc.freenode.net 349.Pq Port 6697 SSL, 6667 unencrypted 350if you need any further quirks or assistance, 351and consider migrating your legacy scripts to work with 352.Nm mksh 353instead of requiring 354.Nm . 355