1 | # 1-Feb-86 09:37:35-MST,30567;000000000001
|
---|
2 | # Return-Path: <unix-sources-request@BRL.ARPA>
|
---|
3 | # Received: from BRL-TGR.ARPA by SIMTEL20.ARPA with TCP; Sat 1 Feb 86 09:36:16-MST
|
---|
4 | # Received: from usenet by TGR.BRL.ARPA id a002623; 1 Feb 86 9:33 EST
|
---|
5 | # From: chris <chris@globetek.uucp>
|
---|
6 | # Newsgroups: net.sources
|
---|
7 | # Subject: Improved Bcsh (Bourne Shell Cshell-Emulator)
|
---|
8 | # Message-ID: <219@globetek.UUCP>
|
---|
9 | # Date: 30 Jan 86 17:34:26 GMT
|
---|
10 | # To: unix-sources@BRL-TGR.ARPA
|
---|
11 | #
|
---|
12 | # This is a new, improved version of my Bourne shell cshell-emulator.
|
---|
13 | # The code has been cleaned up quite a bit, and a couple of new features
|
---|
14 | # added (now supports 'noclobber' and 'iclobber' variables). A bug with
|
---|
15 | # 'eval' that caused "illegal I/O" error messages on vanilla V7 shells has
|
---|
16 | # also been fixed.
|
---|
17 |
|
---|
18 | # I have posted the program in its entirety because a context diff of the
|
---|
19 | # old and new versions was longer than the new version...
|
---|
20 |
|
---|
21 | # --Chris
|
---|
22 | # Bcsh -- A Simple Cshell-Like Command Pre-Processor For The Bourne Shell
|
---|
23 | #
|
---|
24 | # "Copyright (c) Chris Robertson, December 1985"
|
---|
25 | #
|
---|
26 | # This software may be used for any purpose provided the original
|
---|
27 | # copyright notice and this notice are affixed thereto. No warranties of
|
---|
28 | # any kind whatsoever are provided with this software, and it is hereby
|
---|
29 | # understood that the author is not liable for any damagages arising
|
---|
30 | # from the use of this software.
|
---|
31 | #
|
---|
32 | # Features Which the Cshell Does Not Have:
|
---|
33 | # ----------------------------------------
|
---|
34 | #
|
---|
35 | # + command history persists across bcsh sessions
|
---|
36 | # + global last-command editing via 'g^string1^string2^' syntax
|
---|
37 | # + edit any command via $EDITOR or $VISUAL editors
|
---|
38 | # + history file name, .bcshrc file name, alias file name, and number
|
---|
39 | # of commands saved on termination can be set by environment variables
|
---|
40 | # + prompt may evaluate commands, such as `pwd`, `date`, etc.
|
---|
41 | # + the whole text of interactive 'for' and 'while' loops and 'if'
|
---|
42 | # statements goes into the history list and may be re-run or edited
|
---|
43 | # + multiple copies of commands and requests to see command history
|
---|
44 | # are not added to the history list
|
---|
45 | # + the history mechanism actually stores all commands entered in a
|
---|
46 | # current session, not just $history of them. This means that you
|
---|
47 | # can increase $history on the fly and at once have a larger history.
|
---|
48 | #
|
---|
49 | #
|
---|
50 | # Synonyms:
|
---|
51 | # ---------
|
---|
52 | #
|
---|
53 | # logout, exit, bye write out history file and exit
|
---|
54 | # h, history show current history list
|
---|
55 | #
|
---|
56 | #
|
---|
57 | # Aliases:
|
---|
58 | # --------
|
---|
59 | #
|
---|
60 | # alias NAME CMND create an alias called NAME to run CMND
|
---|
61 | # unalias NAME remove the alias NAME
|
---|
62 | #
|
---|
63 | # There are no 'current-session only' aliases -- all alias and unalias
|
---|
64 | # commands are permanent, and stored in the $aliasfile.
|
---|
65 | #
|
---|
66 | # If an alias contains positional variables -- $1, $2, $*, etc. -- any
|
---|
67 | # arguments following the alias name are considered to be values for
|
---|
68 | # those variables, and the alias is turned into a command of the form
|
---|
69 | # 'set - arguments;alias'. Otherwise, a simple substitution is performed
|
---|
70 | # for the alias and the rest of the command preserved. The cshell
|
---|
71 | # convention of using '\!:n' in an alias to get bits of the current
|
---|
72 | # command is mercifully abandoned.
|
---|
73 | #
|
---|
74 | # Quotes are not necessary around the commands comprising an alias;
|
---|
75 | # in fact, any enclosing quotes are stripped when the alias is added
|
---|
76 | # to the file.
|
---|
77 | #
|
---|
78 | # A couple of typical aliases might be:
|
---|
79 | #
|
---|
80 | # goto cd $1;pwd
|
---|
81 | # l ls -F
|
---|
82 | #
|
---|
83 | # Note that aliasing something to "commands;logout" will not work -- if
|
---|
84 | # you want something to happen routinely on logout put it in the file
|
---|
85 | # specified by $logoutfile, default = $HOME/.blogout.
|
---|
86 | #
|
---|
87 | #
|
---|
88 | # Command Substitutions:
|
---|
89 | # ----------------------
|
---|
90 | #
|
---|
91 | # !! substitute last command from history list
|
---|
92 | # !!:N substitute Nth element of last command from
|
---|
93 | # history list -- 0 = command name, 1 = 1st arg
|
---|
94 | # !!:$ substitute last element of last command from
|
---|
95 | # history list
|
---|
96 | # !!:* substitute all arguments to last command
|
---|
97 | # from history list
|
---|
98 | # !NUMBER substitute command NUMBER from the history list
|
---|
99 | # !NUMBER:N as above, but substitute Nth element, where
|
---|
100 | # 0 = command name, 1 = 1st arg, etc.
|
---|
101 | # !NUMBER:$ as above, but substitute last element
|
---|
102 | # !NUMBER:* as above, but substitute all arguments
|
---|
103 | # !-NUMBER substitute the command NUMBER lines from the
|
---|
104 | # end of the history list; 1 = last command
|
---|
105 | # !-NUMBER:N as above, but substitute Nth element, where
|
---|
106 | # 0 = command name, 1 = 1st arg, etc.
|
---|
107 | # !-NUMBER:$ as above, but substitute last element
|
---|
108 | # !-NUMBER:* as above, but substitute all arguments
|
---|
109 | # !?STRING substitute most-recent command from history list
|
---|
110 | # containing STRING -- STRING must be enclosed in
|
---|
111 | # braces if followed by any other characters
|
---|
112 | # !?STRING:N as above, but substitute Nth element, where
|
---|
113 | # 0 = command name, 1 = 1st arg, etc.
|
---|
114 | # !?STRING:$ as above, but substitute last element
|
---|
115 | # !?STRING:* as above, but substitute all arguments
|
---|
116 | #
|
---|
117 | #
|
---|
118 | # Command Editing:
|
---|
119 | # ----------------
|
---|
120 | #
|
---|
121 | # CMND~e edit CMND using $EDITOR, where CMND may be found
|
---|
122 | # using a history substitution
|
---|
123 | # CMND~v edit CMND using $VISUAL, where CMND may be found
|
---|
124 | # using a history substitution
|
---|
125 | # " ^string1^string2^ substitute string2 for string1 in last command"
|
---|
126 | # command and run it
|
---|
127 | # " g^string1^string2^ globally substitute string2 for string1 in "
|
---|
128 | # last command and run it
|
---|
129 | # !NUMBER:s/string1/string2/
|
---|
130 | # substitute string2 for string1 in
|
---|
131 | # command NUMBER and run it
|
---|
132 | # !NUMBER:gs/string1/string2/
|
---|
133 | # globally substitute string2 for string1 in
|
---|
134 | # command NUMBER and run it
|
---|
135 | # !?STRING:s/string1/string2/
|
---|
136 | # substitute string2 for string1 in last command
|
---|
137 | # containing STRING and run it
|
---|
138 | # !?STRING:gs/string1/string2/
|
---|
139 | # globally substitute string2 for string1 in last
|
---|
140 | # command containing STRING and run it
|
---|
141 | #
|
---|
142 | # Any command which ends in the string ":p" is treated as a normal
|
---|
143 | # command until all substitutions have been completed. The trailing
|
---|
144 | # ":p" is then stripped, and the command is simply echoed and added to
|
---|
145 | # the history list instead of being executed.
|
---|
146 | #
|
---|
147 | # None of the other colon extensions of the cshell are supported.
|
---|
148 | #
|
---|
149 | #
|
---|
150 | # Shell Environment Variables:
|
---|
151 | # ----------------------------
|
---|
152 | #
|
---|
153 | # EDITOR editor used by ~e command, default = "ed"
|
---|
154 | # VISUAL editor used by ~v command, default = "vi"
|
---|
155 | # MAIL your system mailbox
|
---|
156 | # PAGER paging program used by history command, default = "more"
|
---|
157 | # PS1 primary prompt
|
---|
158 | # PS2 secondary prompt
|
---|
159 | # history number of commands in history list, default = 22
|
---|
160 | # histfile file history list is saved in, default = $HOME/.bhistory
|
---|
161 | # savehist number of commands remembered from last bcsh session
|
---|
162 | # aliasfile file of aliased commands, default = $HOME/.baliases
|
---|
163 | # logoutfile file of commands to be executed before termination
|
---|
164 | # inc_cmdno yes/no -- keep track of command numbers or not
|
---|
165 | # noclobber if set, existing files are not overwritten by '>'
|
---|
166 | # iclobber if both noclobber and iclobber are set, the user is
|
---|
167 | # prompted for confirmation before existing files are
|
---|
168 | # overwritten by '>'
|
---|
169 | #
|
---|
170 | # Note: if you are setting either noclobber or iclobber mid-session,
|
---|
171 | # set them to 'yes'
|
---|
172 | #
|
---|
173 | #
|
---|
174 | # Regular Shell Variables:
|
---|
175 | # ------------------------
|
---|
176 | #
|
---|
177 | # Shell variables may be set via Bourne or cshell syntax, e.g., both
|
---|
178 | # "set foo=bar" and "foo=bar" set a variable called "foo" with the value
|
---|
179 | # "bar". However, all variables are automatically set as environment
|
---|
180 | # variables, so there is no need to export them. Conversely, there
|
---|
181 | # are NO local variables. Sorry, folks.
|
---|
182 | #
|
---|
183 | # A cshell-style "setenv" command is turned into a regular "set" command.
|
---|
184 | #
|
---|
185 | #
|
---|
186 | # The Prompt:
|
---|
187 | # ----------
|
---|
188 | #
|
---|
189 | # You may, if you wish, have a command executed in your prompt. If
|
---|
190 | # the variable PS1 contains a dollar sign or a backquote, it is
|
---|
191 | # evaluated and the result used as the prompt, provided the evaluation
|
---|
192 | # did not produce a "not found" error message. The two special cases
|
---|
193 | # of PS1 consisting solely of "$" or "$ " are handled correctly. For
|
---|
194 | # example, to have the prompt contain the current directory followed
|
---|
195 | # by a space, enter:
|
---|
196 | #
|
---|
197 | # PS1=\'echo "`pwd` "\'
|
---|
198 | #
|
---|
199 | # You need the backslashed single quotes to prevent the command being
|
---|
200 | # evaluated by the variable-setting mechanism and the shell before it
|
---|
201 | # is assigned to PS1.
|
---|
202 | #
|
---|
203 | # To include the command number in your prompt, enter the command:
|
---|
204 | #
|
---|
205 | # PS1=\'echo "$cmdno "\'
|
---|
206 | #
|
---|
207 | #
|
---|
208 | # Shell Control-Flow Syntax:
|
---|
209 | # --------------------------
|
---|
210 | #
|
---|
211 | # 'While', 'for', 'case', and 'if' commands entered in Bourne shell
|
---|
212 | # syntax are executed as normal.
|
---|
213 | #
|
---|
214 | # A valiant attempt is made to convert 'foreach' loops into 'for' loops,
|
---|
215 | # cshell-syntax 'while' loops into Bourne shell syntax, and 'switch'
|
---|
216 | # statements into 'case' statements. I cannot guarantee to always get it
|
---|
217 | # right. If you forget the 'do' in a 'while' or 'for' loop, or finish
|
---|
218 | # them with 'end' instead of 'done', this will be corrected.
|
---|
219 | #
|
---|
220 | # Note that cshell-to-Bourne control flow conversions do not take place
|
---|
221 | # if control is nested -- e.g., a 'foreach' inside a 'while' will fail.
|
---|
222 | #
|
---|
223 | # The simple-case cshell "if (condition) command" is turned into Bourne
|
---|
224 | # syntax. Other 'if' statements are left alone apart from making the
|
---|
225 | # 'then' a separate statement, because constructing a valid interactive
|
---|
226 | # cshell 'if' statement is essentially an exercise in frustration anyway.
|
---|
227 | # The cshell and Bourne shell have sufficiently different ideas about
|
---|
228 | # conditions that if is probably best to resign yourself to learning
|
---|
229 | # the Bourne shell conventions.
|
---|
230 | #
|
---|
231 | # Note that since most of the testing built-ins of the cshell are
|
---|
232 | # not available in the Bourne shell, a complex condition in a 'while'
|
---|
233 | # loop or an 'if' statement will probably fail.
|
---|
234 | #
|
---|
235 | #
|
---|
236 | # Bugs, Caveats, etc.:
|
---|
237 | # --------------------
|
---|
238 | #
|
---|
239 | # This is not a super-speedy program. Be patient, especially on startup.
|
---|
240 | #
|
---|
241 | # To the best of my knowledge this program should work on ANY Bourne
|
---|
242 | # shell -- note that if your shell does not understand 'echo -n' you
|
---|
243 | # will have to re-set the values of '$n' and '$c'.
|
---|
244 | #
|
---|
245 | # This program may run out of stack space on a 16-bit machine where
|
---|
246 | # /bin/sh is not split-space.
|
---|
247 | #
|
---|
248 | # Mail checking is done every 10 commands if $MAIL is set in your
|
---|
249 | # environment. For anything fancier, you will have to hack the code.
|
---|
250 | #
|
---|
251 | # Because commands are stuffed in a file before sh is invoked on them,
|
---|
252 | # error messages from failed commands are ugly.
|
---|
253 | #
|
---|
254 | # Failed history substitutions either give nothing at all, or a
|
---|
255 | # "not found" style of error message.
|
---|
256 | #
|
---|
257 | # A command history is kept whether you want it or not. This may be
|
---|
258 | # perceived as a bug or a feature, depending on which side of bed you
|
---|
259 | # got out on.
|
---|
260 | #
|
---|
261 | # If you want a real backslash in a command, you will have to type two
|
---|
262 | # of them because the shell swallows the first backslash in the initial
|
---|
263 | # command pickup. This means that to include a non-history '!' in a
|
---|
264 | # command you need '\\!' -- a real wart, especially for net mail,
|
---|
265 | # but unavoidable.
|
---|
266 | #
|
---|
267 | # Commands containing an '@' will break all sorts of things.
|
---|
268 | #
|
---|
269 | # Very complex history substitutions may fail.
|
---|
270 | #
|
---|
271 | # File names containing numbers may break numeric history sustitutions.
|
---|
272 | #
|
---|
273 | # Commands containing bizzare sequences of characters may conflict
|
---|
274 | # with internal kludges.
|
---|
275 | #
|
---|
276 | # Aliasing something to "commands;logout" will not work -- if you
|
---|
277 | # want something to happen routinely on logout, put it in the file
|
---|
278 | # specified by $logoutfile, default = $HOME/.blogout.
|
---|
279 | #
|
---|
280 | # Please send all bug reports to ihnp4!utzoo!globetek!chris.
|
---|
281 | # Flames will be posted to net.general with 'Reply-to' set to your
|
---|
282 | # ' path... :-) '
|
---|
283 | #
|
---|
284 | #
|
---|
285 | #
|
---|
286 | # ************* VERY IMPORTANT NOTICE *************
|
---|
287 | #
|
---|
288 | # If your shell supports # comments, then REPLACE all the colon 'comments'
|
---|
289 | # with # comments. If it does not, then REMOVE all the 'comment' lines from the
|
---|
290 | # working copy of the file, as it will run MUCH faster -- the shell evaluates
|
---|
291 | # lines starting with a colon but does not actually execute them, so you will
|
---|
292 | # save the read-and-evaluate time by removing them.
|
---|
293 |
|
---|
294 | case "`echo -n foo`" in
|
---|
295 | -n*)
|
---|
296 | n=
|
---|
297 | c="\c"
|
---|
298 | ;;
|
---|
299 | foo)
|
---|
300 | n=-n
|
---|
301 | c=
|
---|
302 | ;;
|
---|
303 | *)
|
---|
304 | echo "Your 'echo' command is broken."
|
---|
305 | exit 1
|
---|
306 | ;;
|
---|
307 | esac
|
---|
308 | history=${history-22}
|
---|
309 | savehist=${savehist-22}
|
---|
310 | histfile=${histfile-$HOME/.bhistory}
|
---|
311 | logoutfile=${logoutfile-$HOME/.blogout}
|
---|
312 | EDITOR=${EDITOR-ed}
|
---|
313 | VISUAL=${VISUAL-vi}
|
---|
314 | PAGER=${PAGER-more}
|
---|
315 |
|
---|
316 | aliasfile=${aliasfile-$HOME/.baliases}
|
---|
317 |
|
---|
318 | # the alias file may contain 1 blank line, so a test -s will not work
|
---|
319 |
|
---|
320 | case "`cat $aliasfile 2> /dev/null`" in
|
---|
321 | "")
|
---|
322 | doalias=no
|
---|
323 | ;;
|
---|
324 | *)
|
---|
325 | doalias=yes
|
---|
326 | ;;
|
---|
327 | esac
|
---|
328 |
|
---|
329 | if test -s "${sourcefile-$HOME/.bcshrc}"
|
---|
330 | then
|
---|
331 | . ${sourcefile-$HOME/.bcshrc}
|
---|
332 | fi
|
---|
333 |
|
---|
334 | if test -s "$histfile"
|
---|
335 | then
|
---|
336 | cmdno="`set - \`wc -l $histfile\`;echo $1`"
|
---|
337 | cmdno="`expr \"$cmdno\" + 1`"
|
---|
338 | lastcmd="`sed -n '$p' $histfile`"
|
---|
339 | copy=false
|
---|
340 | ohist=$histfile
|
---|
341 | while test ! -w "$histfile"
|
---|
342 | do
|
---|
343 | echo "Cannot write to history file '$histfile'."
|
---|
344 | echo $n "Please enter a new history filename: $c"
|
---|
345 | read histfile
|
---|
346 | copy=true
|
---|
347 | done
|
---|
348 | if $copy
|
---|
349 | then
|
---|
350 | cp $ohist $histfile
|
---|
351 | fi
|
---|
352 | else
|
---|
353 | cat /dev/null > $histfile
|
---|
354 | cmdno=1
|
---|
355 | lastcmd=
|
---|
356 | fi
|
---|
357 |
|
---|
358 | # keep track of command number as the default
|
---|
359 |
|
---|
360 | inc_cmdno=${inc_cmdo-yes}
|
---|
361 |
|
---|
362 | # default prompts -- PS1 and PS2 may be SET but EMPTY, so '${PS1-% }' syntax
|
---|
363 | # is not used here
|
---|
364 |
|
---|
365 | case "$PS1" in
|
---|
366 | "")
|
---|
367 | PS1="% "
|
---|
368 | ;;
|
---|
369 | esac
|
---|
370 | case "$PS2" in
|
---|
371 | "")
|
---|
372 | PS2="> "
|
---|
373 | ;;
|
---|
374 | esac
|
---|
375 |
|
---|
376 | export histfile savehist history aliasfile EDITOR VISUAL PAGER cmdno PS1 PS2
|
---|
377 |
|
---|
378 | case "$MAIL" in
|
---|
379 | "")
|
---|
380 | ;;
|
---|
381 | *)
|
---|
382 | if [ -f $MAIL ]; then
|
---|
383 | mailsize=`set - \`wc -c $MAIL\`;echo $1`
|
---|
384 | else
|
---|
385 | mailsize=0
|
---|
386 | fi
|
---|
387 | ;;
|
---|
388 | esac
|
---|
389 |
|
---|
390 | trap ':' 2
|
---|
391 | trap exit 3
|
---|
392 | trap "tail -n $savehist $histfile>/tmp/hist$$;uniq /tmp/hist$$ > $histfile;\
|
---|
393 | rm -f /tmp/*$$;exit 0" 15
|
---|
394 |
|
---|
395 | getcmd=yes
|
---|
396 | mailcheck=
|
---|
397 | exclaim=
|
---|
398 | echoit=
|
---|
399 | mailprompt=
|
---|
400 |
|
---|
401 | while :
|
---|
402 | do
|
---|
403 |
|
---|
404 | run=yes
|
---|
405 | case "$mailprompt" in
|
---|
406 | "")
|
---|
407 | ;;
|
---|
408 | *)
|
---|
409 | echo "$mailprompt"
|
---|
410 | ;;
|
---|
411 | esac
|
---|
412 | case "$getcmd" in
|
---|
413 | yes)
|
---|
414 | : guess if the prompt should be evaluated or not
|
---|
415 | case "$PS1" in
|
---|
416 | \$|\$\ )
|
---|
417 | echo $n "$PS1$c"
|
---|
418 | ;;
|
---|
419 | *\`*|*\$*)
|
---|
420 | tmp="`(eval $PS1) 2>&1`"
|
---|
421 | case "$tmp" in
|
---|
422 | *not\ found)
|
---|
423 | echo $n "$PS1$c"
|
---|
424 | ;;
|
---|
425 | *)
|
---|
426 | echo $n "$tmp$c"
|
---|
427 | ;;
|
---|
428 | esac
|
---|
429 | ;;
|
---|
430 | *)
|
---|
431 | echo $n "$PS1$c"
|
---|
432 | ;;
|
---|
433 | esac
|
---|
434 |
|
---|
435 | read cmd || cmd="exit"
|
---|
436 | ;;
|
---|
437 | *) ;;
|
---|
438 | esac
|
---|
439 |
|
---|
440 | case "$MAIL" in
|
---|
441 | "")
|
---|
442 | ;;
|
---|
443 | *)
|
---|
444 | : check for mail every 10 commands
|
---|
445 | case "$mailcheck" in
|
---|
446 | 1111111111)
|
---|
447 | mailcheck=
|
---|
448 | if [ -f $MAIL ]; then
|
---|
449 | newsize="`set - \`wc -c $MAIL\`;echo $1`"
|
---|
450 | else
|
---|
451 | newsize=0
|
---|
452 | fi
|
---|
453 | if test "$newsize" -gt "$mailsize"; then
|
---|
454 | mailprompt="You have new mail"
|
---|
455 | else
|
---|
456 | mailprompt=
|
---|
457 | fi
|
---|
458 | mailsize=$newsize
|
---|
459 | ;;
|
---|
460 | *)
|
---|
461 | mailcheck=1$mailcheck
|
---|
462 | ;;
|
---|
463 | esac
|
---|
464 | ;;
|
---|
465 | esac
|
---|
466 | hist=no
|
---|
467 |
|
---|
468 | case "$cmd" in
|
---|
469 | "")
|
---|
470 | continue
|
---|
471 | ;;
|
---|
472 | sh)
|
---|
473 | sh
|
---|
474 | run=no
|
---|
475 | ;;
|
---|
476 | !!)
|
---|
477 | cmd=$lastcmd
|
---|
478 | echoit=yes
|
---|
479 | getcmd=no
|
---|
480 | continue
|
---|
481 | ;;
|
---|
482 | *:p)
|
---|
483 | cmd="`expr \"$cmd\" : '\(.*\):p'` +~+p"
|
---|
484 | getcmd=no
|
---|
485 | continue
|
---|
486 | ;;
|
---|
487 | foreach[\ \ ]*)
|
---|
488 | while test "$line" != "end"; do
|
---|
489 | echo $n "$PS2$c"
|
---|
490 | read line
|
---|
491 | cmd="${cmd};$line"
|
---|
492 | done
|
---|
493 | echo "$cmd" > /tmp/bcsh$$
|
---|
494 | ed - /tmp/bcsh$$ << ++++
|
---|
495 | s/end/done/
|
---|
496 | s/foreach[ ]\(.*\)(/for \1 in /
|
---|
497 | s/)//
|
---|
498 | s/;/;do /
|
---|
499 | w
|
---|
500 | ++++
|
---|
501 | ;;
|
---|
502 | for[\ \ ]*|while[\ \ ]*)
|
---|
503 | # try to catch the most common cshell-to-Bourne-shell
|
---|
504 | # mistakes
|
---|
505 |
|
---|
506 | echo $n "$PS2$c"
|
---|
507 | read line
|
---|
508 | case "$line" in
|
---|
509 | *do)
|
---|
510 | line="do :"
|
---|
511 | ;;
|
---|
512 | *do*)
|
---|
513 | ;;
|
---|
514 | *)
|
---|
515 | line="do $line"
|
---|
516 | ;;
|
---|
517 | esac
|
---|
518 |
|
---|
519 | cmd="${cmd};$line"
|
---|
520 | while test "$line" != "done" && test "$line" != "end"
|
---|
521 | do
|
---|
522 | echo $n "$PS2$c"
|
---|
523 | read line
|
---|
524 | case "$line" in
|
---|
525 | end)
|
---|
526 | line=done
|
---|
527 | ;;
|
---|
528 | esac
|
---|
529 | cmd="${cmd};$line"
|
---|
530 | done
|
---|
531 | echo "$cmd" > /tmp/bcsh$$
|
---|
532 | ;;
|
---|
533 | if[\ \ ]*)
|
---|
534 | while test "$line" != "fi" && test "$line" != "endif"
|
---|
535 | do
|
---|
536 | echo $n "$PS2$c"
|
---|
537 | read line
|
---|
538 | case "$line" in
|
---|
539 | *[a-z]*then)
|
---|
540 | line="`expr \"$line\" : '\(.*\)then'`;then"
|
---|
541 | ;;
|
---|
542 | endif)
|
---|
543 | line=fi
|
---|
544 | ;;
|
---|
545 | esac
|
---|
546 | cmd="${cmd};$line"
|
---|
547 | done
|
---|
548 | echo "$cmd" > /tmp/bcsh$$
|
---|
549 | case "`grep then /tmp/bcsh$$`" in
|
---|
550 | "")
|
---|
551 | # fix 'if foo bar' cases
|
---|
552 |
|
---|
553 | ed - /tmp/bcsh$$ << ++++
|
---|
554 | s/)/);then/
|
---|
555 | s/.*/;fi/
|
---|
556 | w
|
---|
557 | ++++
|
---|
558 | ;;
|
---|
559 | esac
|
---|
560 | ;;
|
---|
561 | case[\ \ ]*)
|
---|
562 | while test "$line" != "esac"
|
---|
563 | do
|
---|
564 | echo $n "$PS2$c"
|
---|
565 | read line
|
---|
566 | cmd="${cmd}@$line"
|
---|
567 | done
|
---|
568 | cmd="`echo \"$cmd\" | tr '@' ' '`"
|
---|
569 | echo "$cmd" > /tmp/bcsh$$
|
---|
570 | ;;
|
---|
571 | switch[\ \ ]*)
|
---|
572 | while test "$line" != "endsw"
|
---|
573 | do
|
---|
574 | echo $n "$PS2$c"
|
---|
575 | read line
|
---|
576 | cmd="${cmd}@$line"
|
---|
577 | done
|
---|
578 | echo "$cmd" > /tmp/bcsh$$
|
---|
579 | ed - /tmp/bcsh$$ << '++++'
|
---|
580 | 1,$s/@/\
|
---|
581 | /g
|
---|
582 | g/switch.*(/s//case "/
|
---|
583 | s/)/" in/
|
---|
584 | 1,$s/case[ ]\(.*\):$/;;\
|
---|
585 | \1)/
|
---|
586 | 2d
|
---|
587 | 1,$s/endsw/;;\
|
---|
588 | esac/
|
---|
589 | g/breaksw/s///
|
---|
590 | 1,$s/default.*/;;\
|
---|
591 | *)/
|
---|
592 | w
|
---|
593 | ++++
|
---|
594 | cmd="`cat /tmp/bcsh$$`"
|
---|
595 | ;;
|
---|
596 | *!*)
|
---|
597 | hist=yes
|
---|
598 | ;;
|
---|
599 | esac
|
---|
600 |
|
---|
601 | case "$hist" in
|
---|
602 | yes)
|
---|
603 | # deal with genuine exclamation marks, go back and parse again
|
---|
604 |
|
---|
605 | case "$cmd" in
|
---|
606 | *\>![\ \ ]*|*\\!*)
|
---|
607 | cmd="`echo \"$cmd\" | sed -e 's@\\!@REALEXCLAMATIONMARK@g'`"
|
---|
608 | exclaim=yes
|
---|
609 | getcmd=no
|
---|
610 | continue
|
---|
611 | ;;
|
---|
612 | esac
|
---|
613 |
|
---|
614 | # break command into elements, parse each one
|
---|
615 |
|
---|
616 | tmp=
|
---|
617 | for i in $cmd
|
---|
618 | do
|
---|
619 | # find element with !, peel off stuff up to !
|
---|
620 |
|
---|
621 | case "$i" in
|
---|
622 | !)
|
---|
623 | # most likely a typo for !!, so fix it
|
---|
624 | front=
|
---|
625 | $i=!!
|
---|
626 | ;;
|
---|
627 | !!*)
|
---|
628 | front=
|
---|
629 | i="`expr \"$i\" : '.*\(!!.*\)'`"
|
---|
630 | ;;
|
---|
631 | *!!*)
|
---|
632 | front="`expr \"$i\" : '\(.*\)!!.*'`"
|
---|
633 | i="`expr \"$i\" : '.*\(!!.*\)'`"
|
---|
634 | ;;
|
---|
635 | !*)
|
---|
636 | front=
|
---|
637 | i="`expr \"$i\" : '.*!\(.*\)'`"
|
---|
638 | ;;
|
---|
639 | *)
|
---|
640 | tmp="$tmp$i "
|
---|
641 | continue
|
---|
642 | ;;
|
---|
643 | esac
|
---|
644 | case "$i" in
|
---|
645 | !!*)
|
---|
646 | # want last command
|
---|
647 |
|
---|
648 | rest="`expr \"$i\" : '!!\(.*\)'`"
|
---|
649 | i=$lastcmd
|
---|
650 | ;;
|
---|
651 | -*)
|
---|
652 | # we want to search back through the history list
|
---|
653 |
|
---|
654 | case "$i" in
|
---|
655 | -)
|
---|
656 | rest="`expr \"$i\" : '-\(.*\)'`"
|
---|
657 | i=$lastcmd
|
---|
658 | ;;
|
---|
659 | -[0-9]*)
|
---|
660 | wanted="`expr \"$i\" : '-\([0-9][0-9]*\).*'`"
|
---|
661 | rest="`expr \"$i\" : '-[0-9][0-9]*\(.*\)'`"
|
---|
662 | i="`tail -n $wanted $histfile | sed -e "1q"`"
|
---|
663 | ;;
|
---|
664 | esac
|
---|
665 | ;;
|
---|
666 | [0-9]*)
|
---|
667 | # find which number command is wanted
|
---|
668 |
|
---|
669 | wanted="`expr \"$i\" : '\([0-9][0-9]*\).*'`"
|
---|
670 | rest="`expr \"$i\" : '[0-9][0-9]*\(.*\)'`"
|
---|
671 | i="`grep -n . $histfile | grep \"^$wanted\"`"
|
---|
672 | i="`expr \"$i\" : \"${wanted}.\(.*\)\"`"
|
---|
673 | ;;
|
---|
674 | \?*)
|
---|
675 |
|
---|
676 | # find which 'command-contains' match is wanted
|
---|
677 |
|
---|
678 | case "$i" in
|
---|
679 | \?{*}*)
|
---|
680 | wanted="`expr \"$i\" : '?{\(.*\)}.*'`"
|
---|
681 | rest="`expr \"$i\" : '?.*}\(.*\)'`"
|
---|
682 | ;;
|
---|
683 | \?*:*)
|
---|
684 | wanted="`expr \"$i\" : '?\(.*\):.*'`"
|
---|
685 | rest="`expr \"$i\" : '?.*\(:.*\)'`"
|
---|
686 | ;;
|
---|
687 | \?*)
|
---|
688 | wanted="`expr \"$i\" : '?\(.*\)'`"
|
---|
689 | rest=
|
---|
690 | ;;
|
---|
691 | esac
|
---|
692 | i="`grep \"$wanted\" $histfile | sed -n '$p'`"
|
---|
693 | ;;
|
---|
694 | *)
|
---|
695 | # find which 'start-of-command' match is wanted
|
---|
696 |
|
---|
697 | case "$i" in
|
---|
698 | {*}*)
|
---|
699 | wanted="`expr \"$i\" : '{\(.*\)}.*'`"
|
---|
700 | rest="`expr \"$i\" : '.*}\(.*\)'`"
|
---|
701 | ;;
|
---|
702 | *:*)
|
---|
703 | wanted="`expr \"$i\" : '\(.*\):.*'`"
|
---|
704 | rest="`expr \"$i\" : '.*\(:.*\)'`"
|
---|
705 | ;;
|
---|
706 | *)
|
---|
707 | wanted="$i"
|
---|
708 | rest=
|
---|
709 | ;;
|
---|
710 | esac
|
---|
711 | i="`grep \"^$wanted\" $histfile | sed -n '$p'`"
|
---|
712 | ;;
|
---|
713 | esac
|
---|
714 |
|
---|
715 | # see if we actually found anything to substitute
|
---|
716 |
|
---|
717 | case "$i" in
|
---|
718 | "")
|
---|
719 | badsub="Event not found"
|
---|
720 | break
|
---|
721 | ;;
|
---|
722 | *)
|
---|
723 | badsub=no
|
---|
724 | ;;
|
---|
725 | esac
|
---|
726 |
|
---|
727 | case "$rest" in
|
---|
728 | "")
|
---|
729 | tmp="$front$tmp$i "
|
---|
730 | continue
|
---|
731 | ;;
|
---|
732 | :[0-9]*)
|
---|
733 | # find which element of $i is wanted
|
---|
734 |
|
---|
735 | number="`expr \"$rest\" : ':\([0-9][0-9]*\).*'`"
|
---|
736 | rest="`expr \"$rest\" : ':[0-9][0-9]*\(.*\)'`"
|
---|
737 |
|
---|
738 | # count through $i till we get to the
|
---|
739 | # right element
|
---|
740 |
|
---|
741 | counter=0
|
---|
742 | for element in $i
|
---|
743 | do
|
---|
744 | case "$counter" in
|
---|
745 | $number)
|
---|
746 | break
|
---|
747 | ;;
|
---|
748 | *)
|
---|
749 | counter="`expr \"$counter\" + 1`"
|
---|
750 | # counter=$[ $counter + 1 ]
|
---|
751 | ;;
|
---|
752 | esac
|
---|
753 | done
|
---|
754 | case "$counter" in
|
---|
755 | $number)
|
---|
756 | badsub=no
|
---|
757 | ;;
|
---|
758 | *)
|
---|
759 | badsub="Bad command element"
|
---|
760 | break
|
---|
761 | ;;
|
---|
762 | esac
|
---|
763 | tmp="$tmp$front$element$rest "
|
---|
764 | continue
|
---|
765 | ;;
|
---|
766 | :\$*)
|
---|
767 | # spin through $i till we hit the last element
|
---|
768 |
|
---|
769 | rest="`expr \"$rest\" : ':\$\(.*\)'`"
|
---|
770 | for element in $i
|
---|
771 | do
|
---|
772 | :
|
---|
773 | done
|
---|
774 | tmp="$tmp$front$element$rest "
|
---|
775 | continue
|
---|
776 | ;;
|
---|
777 | :\**)
|
---|
778 | # we want all elements except the command itself
|
---|
779 |
|
---|
780 | rest="`expr \"$rest\" : ':\*\(.*\)'`"
|
---|
781 | save=$i
|
---|
782 | set - $i
|
---|
783 | shift
|
---|
784 | case "$*" in
|
---|
785 | "")
|
---|
786 | badsub="No arguments to command '$save'"
|
---|
787 | break
|
---|
788 | ;;
|
---|
789 | *)
|
---|
790 | badsub=no
|
---|
791 | ;;
|
---|
792 | esac
|
---|
793 | tmp="$tmp$front$*$rest "
|
---|
794 | continue
|
---|
795 | ;;
|
---|
796 | :s*|:gs*)
|
---|
797 | # we are doing a substitution
|
---|
798 | # put / on end if needed
|
---|
799 |
|
---|
800 | case "$rest" in
|
---|
801 | :s/*/*/*|:gs/*/*/*)
|
---|
802 | ;;
|
---|
803 | :s/*/*|:gs/*/*)
|
---|
804 | rest="${rest}/"
|
---|
805 | ;;
|
---|
806 | esac
|
---|
807 |
|
---|
808 | # find what substitution is wanted
|
---|
809 |
|
---|
810 | first="`expr \"$rest\" : ':*s\/\(.*\)\/.*\/.*'`"
|
---|
811 | second="`expr \"$i\" : ':*s/.*/\(.*\)/.*'`"
|
---|
812 |
|
---|
813 | # see if it is a global substitution
|
---|
814 |
|
---|
815 | case "$rest" in
|
---|
816 | :gs*)
|
---|
817 | global=g
|
---|
818 | ;;
|
---|
819 | :s*)
|
---|
820 | global=
|
---|
821 | ;;
|
---|
822 | esac
|
---|
823 | rest="`expr \"$rest\" : '.*/.*/.*/\(.*\)'`"
|
---|
824 | i="`echo \"$i\" | sed -e \"s@$first@$second@$global\"`"
|
---|
825 |
|
---|
826 | # see if subsitution worked
|
---|
827 |
|
---|
828 | case "$i" in
|
---|
829 | "")
|
---|
830 | badsub="Substiution failed"
|
---|
831 | break
|
---|
832 | ;;
|
---|
833 | *)
|
---|
834 | badsub=no
|
---|
835 | ;;
|
---|
836 | esac
|
---|
837 | tmp="$tmp$front$i$rest "
|
---|
838 | continue
|
---|
839 | ;;
|
---|
840 | *)
|
---|
841 | tmp="$tmp$front$i$rest "
|
---|
842 | ;;
|
---|
843 | esac
|
---|
844 | done
|
---|
845 | case "$badsub" in
|
---|
846 | no)
|
---|
847 | ;;
|
---|
848 | *)
|
---|
849 | echo "$badsub"
|
---|
850 | badsub=no
|
---|
851 | continue
|
---|
852 | ;;
|
---|
853 | esac
|
---|
854 | cmd="$tmp"
|
---|
855 | echoit=yes
|
---|
856 | getcmd=no
|
---|
857 | continue
|
---|
858 | ;;
|
---|
859 | *)
|
---|
860 | run=yes
|
---|
861 | ;;
|
---|
862 | esac
|
---|
863 |
|
---|
864 | case "$cmd" in
|
---|
865 | *\^*\^*\^*)
|
---|
866 | # see if the substitution is global
|
---|
867 | case "$cmd" in
|
---|
868 | g*)
|
---|
869 | global=g
|
---|
870 | ;;
|
---|
871 | *)
|
---|
872 | global=
|
---|
873 | ;;
|
---|
874 | esac
|
---|
875 |
|
---|
876 | # put a '^' on the end if necessary
|
---|
877 | case "$cmd" in
|
---|
878 | *\^)
|
---|
879 | ;;
|
---|
880 | *)
|
---|
881 | cmd="${cmd}^"
|
---|
882 | ;;
|
---|
883 | esac
|
---|
884 |
|
---|
885 | # find what substitution is wanted
|
---|
886 |
|
---|
887 | first="`expr \"$cmd\" : '*\^\(.*\)\^.*\^.*'`"
|
---|
888 | second="`expr \"$cmd\" : '*\^.*\^\(.*\)\^.*'`"
|
---|
889 | rest="`expr \"$cmd\" : '*\^.*\^.*\^\(.*\)'`"
|
---|
890 | cmd="`echo \"$lastcmd\" | sed -e \"s@$first@$second@$global\"`$rest"
|
---|
891 |
|
---|
892 | # see if the substitution worked
|
---|
893 |
|
---|
894 | case "$cmd" in
|
---|
895 | "")
|
---|
896 | echo "Substitution failed"
|
---|
897 | continue
|
---|
898 | ;;
|
---|
899 | esac
|
---|
900 | echoit=yes
|
---|
901 | getcmd=no
|
---|
902 | continue
|
---|
903 | ;;
|
---|
904 | *~e)
|
---|
905 | echo "$cmd" | sed -e "s@~e@@" > /tmp/bcsh$$
|
---|
906 | $EDITOR /tmp/bcsh$$
|
---|
907 | cmd="`cat /tmp/bcsh$$`"
|
---|
908 | getcmd=no
|
---|
909 | continue
|
---|
910 | ;;
|
---|
911 | *~v)
|
---|
912 | echo "$cmd" | sed -e "s@~v@@" > /tmp/bcsh$$
|
---|
913 | echo "$lastcmd" > /tmp/bcsh$$
|
---|
914 | $VISUAL /tmp/bcsh$$
|
---|
915 | cmd="`cat /tmp/bcsh$$`"
|
---|
916 | getcmd=no
|
---|
917 | continue
|
---|
918 | ;;
|
---|
919 | exec[\ \ ]*)
|
---|
920 | tail -n $savehist $histfile>/tmp/hist$$
|
---|
921 | uniq /tmp/hist$$ > $histfile
|
---|
922 | rm -f /tmp/*$$
|
---|
923 | echo $cmd > /tmp/cmd$$
|
---|
924 | . /tmp/cmd$$
|
---|
925 | ;;
|
---|
926 | login[\ \ ]*|newgrp[\ \ ]*)
|
---|
927 | tail -n $savehist $histfile>/tmp/hist$$
|
---|
928 | uniq /tmp/hist$$ > $histfile
|
---|
929 | rm -f /tmp/*$$
|
---|
930 | echo $cmd > /tmp/cmd$$
|
---|
931 | . /tmp/cmd$$
|
---|
932 | ;;
|
---|
933 | logout|exit|bye)
|
---|
934 | if test -s "$logoutfile"
|
---|
935 | then
|
---|
936 | # sh $logoutfile
|
---|
937 | $SHELL $logoutfile
|
---|
938 | fi
|
---|
939 | tail -n $savehist $histfile > /tmp/hist$$
|
---|
940 | uniq /tmp/hist$$ > $histfile
|
---|
941 | rm -f /tmp/*$$
|
---|
942 | exit 0
|
---|
943 | ;;
|
---|
944 | h|history)
|
---|
945 | grep -n . $histfile | tail -n $history | sed -e 's@:@ @' | $PAGER
|
---|
946 | continue
|
---|
947 | ;;
|
---|
948 | h[\ \ ]\|*|h[\ \ ]\>*|h\|*|h\>*)
|
---|
949 | cmd="`echo \"$cmd\" | sed -e \"s@h@grep -n . $histfile | tail -n $history | sed -e 's@:@ @'@\"`"
|
---|
950 | getcmd=no
|
---|
951 | continue
|
---|
952 | ;;
|
---|
953 | history[\ \ ]*\|*|history[\ \ ]*\>*)
|
---|
954 | cmd="`echo \"$cmd\" | sed -e \"s@history@grep -n . $histfile | tail -n $history | sed -e 's@:@ @'@\"`"
|
---|
955 | getcmd=no
|
---|
956 | continue
|
---|
957 | ;;
|
---|
958 | source[\ \ ]*)
|
---|
959 | set - $cmd
|
---|
960 | shift
|
---|
961 | echo . $* > /tmp/cmd$$
|
---|
962 | . /tmp/cmd$$
|
---|
963 | run=no
|
---|
964 | ;;
|
---|
965 | wait)
|
---|
966 | wait
|
---|
967 | run=no
|
---|
968 | ;;
|
---|
969 | .[\ \ ]*)
|
---|
970 | echo $cmd > /tmp/cmd$$
|
---|
971 | . /tmp/cmd$$
|
---|
972 | run=no
|
---|
973 | ;;
|
---|
974 | cd|cd[\ \ ]*)
|
---|
975 | # check if it will work first, or else this shell will terminate
|
---|
976 | # if the cd dies. If you have a built-in test, you might want
|
---|
977 | # to replace the try-it-and-see below with a couple of tests,
|
---|
978 | # but it is probably just as fast like this.
|
---|
979 |
|
---|
980 | echo $cmd > /tmp/cmd$$
|
---|
981 | if ($SHELL /tmp/cmd$$) ; then
|
---|
982 | . /tmp/cmd$$
|
---|
983 | fi
|
---|
984 | run=no
|
---|
985 | ;;
|
---|
986 | awk[\ \ ]*|dd[\ \ ]*|cc[\ \ ]*|make[\ \ ]*)
|
---|
987 | # these are the only commands I can think of whose syntax
|
---|
988 | # includes an equals sign. Add others as you find them.
|
---|
989 |
|
---|
990 | echo "$cmd" > /tmp/bcsh$$
|
---|
991 | ;;
|
---|
992 | setenv*|*=*)
|
---|
993 | # handle setting shell variables, turning cshell syntax to Bourne
|
---|
994 | # syntax -- note all variables must be exported or they will not
|
---|
995 | # be usable in other commands
|
---|
996 |
|
---|
997 | echo "$cmd" > /tmp/cmd$$
|
---|
998 | ed - /tmp/cmd$$ << ++++
|
---|
999 | g/^setenv[ ]/s/[ ]/@/
|
---|
1000 | g/^setenv@/s/[ ]/=/
|
---|
1001 | g/^setenv@/s///
|
---|
1002 | g/^set/s///
|
---|
1003 | .t.
|
---|
1004 | \$s/=.*//
|
---|
1005 | s/^/export /
|
---|
1006 | w
|
---|
1007 | ++++
|
---|
1008 | . /tmp/cmd$$
|
---|
1009 | rm -f /tmp/cmd$$
|
---|
1010 | run=no
|
---|
1011 | ;;
|
---|
1012 | unset[\ \ ]*|umask[\ \ ]*|export[\ \ ]*|set[\ \ ]*)
|
---|
1013 | # handle commands which twiddle current environment
|
---|
1014 |
|
---|
1015 | $cmd
|
---|
1016 | run=no
|
---|
1017 | ;;
|
---|
1018 | alias|alias[\ \ ])
|
---|
1019 | if [ -f $aliasfile ]; then
|
---|
1020 | $PAGER $aliasfile
|
---|
1021 | fi
|
---|
1022 | lastcmd=$cmd
|
---|
1023 | run=no
|
---|
1024 | continue
|
---|
1025 | ;;
|
---|
1026 | alias[\ \ ]*)
|
---|
1027 | case "$cmd" in
|
---|
1028 | alias[\ \ ]\|*|alias[\ \ ]\>*)
|
---|
1029 | cmd="`echo \"$cmd\" | sed -e \"s@alias@cat $aliasfile@\"`"
|
---|
1030 | getcmd=no
|
---|
1031 | continue
|
---|
1032 | ;;
|
---|
1033 | alias[\ \ ]*[\ \ ]*)
|
---|
1034 | ;;
|
---|
1035 | *)
|
---|
1036 | echo "Syntax: alias name command"
|
---|
1037 | cmd=
|
---|
1038 | continue
|
---|
1039 | ;;
|
---|
1040 | esac
|
---|
1041 | set - $cmd
|
---|
1042 | shift
|
---|
1043 | cmd="$*"
|
---|
1044 |
|
---|
1045 | # make sure there is always 1 blank line in file so
|
---|
1046 | # unaliasing will always work -- ed normally refuses
|
---|
1047 | # to write an empty file
|
---|
1048 | echo "" >> $aliasfile
|
---|
1049 | cat << ++++ >> $aliasfile
|
---|
1050 | $cmd
|
---|
1051 | ++++
|
---|
1052 |
|
---|
1053 | # ed - $aliasfile << '++++'
|
---|
1054 | # g/alias[ ]/s///
|
---|
1055 | # g/^['"]\(.*\)['"]$/s//\1/
|
---|
1056 | # g/^/s//alias /
|
---|
1057 | # w
|
---|
1058 | #++++
|
---|
1059 |
|
---|
1060 | sort -u -o $aliasfile $aliasfile
|
---|
1061 | doalias=yes
|
---|
1062 | cmd="alias $cmd"
|
---|
1063 | run=no
|
---|
1064 | ;;
|
---|
1065 | unalias[\ \ ]*)
|
---|
1066 | set - $cmd
|
---|
1067 | case "$#" in
|
---|
1068 | 2)
|
---|
1069 | cmd=$2
|
---|
1070 | ;;
|
---|
1071 | *)
|
---|
1072 | echo "Syntax: unalias alias_name"
|
---|
1073 | continue
|
---|
1074 | ;;
|
---|
1075 | esac
|
---|
1076 | ed - $aliasfile << ++++
|
---|
1077 | /^$cmd[ ]/d
|
---|
1078 | w
|
---|
1079 | ++++
|
---|
1080 | case "`set - \`wc -l $aliasfile\`;echo $1`" in
|
---|
1081 | 1)
|
---|
1082 | # just removed last alias
|
---|
1083 | doalias=no
|
---|
1084 | ;;
|
---|
1085 | esac
|
---|
1086 | run=no
|
---|
1087 | ;;
|
---|
1088 | *)
|
---|
1089 | case "$doalias" in
|
---|
1090 | yes)
|
---|
1091 | set - $cmd
|
---|
1092 | tmp="`grep \"^$1 \" $aliasfile`"
|
---|
1093 | case "$tmp" in
|
---|
1094 | $1[\ \ ]*)
|
---|
1095 | shift
|
---|
1096 | cmd=$*
|
---|
1097 | set - $tmp
|
---|
1098 | shift
|
---|
1099 | tmp=$*
|
---|
1100 | case "$tmp" in
|
---|
1101 | *\$*)
|
---|
1102 | # uses positional variables
|
---|
1103 |
|
---|
1104 | cmd="set - $cmd ; $tmp"
|
---|
1105 | getcmd=no
|
---|
1106 | continue
|
---|
1107 | ;;
|
---|
1108 | *)
|
---|
1109 | cmd="$tmp $cmd"
|
---|
1110 | getcmd=no
|
---|
1111 | continue
|
---|
1112 | ;;
|
---|
1113 | esac
|
---|
1114 | ;;
|
---|
1115 | *)
|
---|
1116 | echo "$cmd" > /tmp/bcsh$$
|
---|
1117 | ;;
|
---|
1118 | esac
|
---|
1119 | ;;
|
---|
1120 | no)
|
---|
1121 | echo "$cmd" > /tmp/bcsh$$
|
---|
1122 | ;;
|
---|
1123 | esac
|
---|
1124 | ;;
|
---|
1125 | esac
|
---|
1126 |
|
---|
1127 | case "$cmd" in
|
---|
1128 | *+~+p)
|
---|
1129 | cmd="`expr \"$cmd\" : '\(.*\)+~+p'`"
|
---|
1130 | echoit=yes
|
---|
1131 | run=no
|
---|
1132 | ;;
|
---|
1133 | esac
|
---|
1134 |
|
---|
1135 | case "$cmd" in
|
---|
1136 | "")
|
---|
1137 | continue
|
---|
1138 | ;;
|
---|
1139 | *)
|
---|
1140 | case "$exclaim" in
|
---|
1141 | yes)
|
---|
1142 | cmd="`echo \"$cmd\" | sed -e 's@REALEXCLAMATIONMARK@!@g'`"
|
---|
1143 | echo "$cmd" > /tmp/bcsh$$
|
---|
1144 | ;;
|
---|
1145 | esac
|
---|
1146 | case "$echoit" in
|
---|
1147 | yes)
|
---|
1148 | echo $cmd
|
---|
1149 | ;;
|
---|
1150 | esac
|
---|
1151 | case "$run" in
|
---|
1152 | yes)
|
---|
1153 | case "${noclobber+yes}" in
|
---|
1154 | yes)
|
---|
1155 | case "$cmd" in
|
---|
1156 | *\>![\ \ ]*)
|
---|
1157 | ed - /tmp/bcsh$$ << ++++
|
---|
1158 | g/>!/s//>/
|
---|
1159 | w
|
---|
1160 | ++++
|
---|
1161 | ;;
|
---|
1162 | *\>\>*)
|
---|
1163 | ;;
|
---|
1164 | *\>*)
|
---|
1165 | outfile="`expr \"$cmd\" : '.*>\(.*\)'`"
|
---|
1166 | case "$outfile" in
|
---|
1167 | \&*)
|
---|
1168 | ;;
|
---|
1169 | *)
|
---|
1170 | set - $outfile
|
---|
1171 | outfile="$1"
|
---|
1172 | if test -s "$outfile"
|
---|
1173 | then
|
---|
1174 | case "${iclobber+yes}" in
|
---|
1175 | yes)
|
---|
1176 | echo $n "Overwrite ${outfile}? $c"
|
---|
1177 | read answer
|
---|
1178 | case "$answer" in
|
---|
1179 | y*)
|
---|
1180 | ;;
|
---|
1181 | *)
|
---|
1182 | echo ':' > /tmp/bcsh$$
|
---|
1183 | ;;
|
---|
1184 | esac
|
---|
1185 | ;;
|
---|
1186 | *)
|
---|
1187 | echo "${outfile}: file exists"
|
---|
1188 | echo ':' > /tmp/bcsh$$
|
---|
1189 | ;;
|
---|
1190 | esac
|
---|
1191 | fi
|
---|
1192 | ;;
|
---|
1193 | esac
|
---|
1194 | ;;
|
---|
1195 | esac
|
---|
1196 | ;;
|
---|
1197 | *)
|
---|
1198 | case "$cmd" in
|
---|
1199 | *\>![\ \ ]*)
|
---|
1200 | ed - /tmp/bcsh$$ << ++++
|
---|
1201 | g/>!/s//>/g
|
---|
1202 | w
|
---|
1203 | ++++
|
---|
1204 | ;;
|
---|
1205 | esac
|
---|
1206 | ;;
|
---|
1207 | esac
|
---|
1208 | (trap 'exit 1' 2 3; $BASH /tmp/bcsh$$)
|
---|
1209 | ;;
|
---|
1210 | esac
|
---|
1211 | case "$cmd" in
|
---|
1212 | $lastcmd)
|
---|
1213 | ;;
|
---|
1214 | *)
|
---|
1215 | case "$exclaim" in
|
---|
1216 | yes)
|
---|
1217 | cmd="`echo \"$cmd\" | sed -e 's@!@\\\\!@g'`"
|
---|
1218 | ;;
|
---|
1219 | esac
|
---|
1220 |
|
---|
1221 | cat << ++++ >> $histfile
|
---|
1222 | $cmd
|
---|
1223 | ++++
|
---|
1224 | lastcmd=$cmd
|
---|
1225 |
|
---|
1226 | case "$inc_cmdno" in
|
---|
1227 | yes)
|
---|
1228 | cmdno="`expr \"$cmdno\" + 1`"
|
---|
1229 | # cmdno=$[$cmdno + 1]
|
---|
1230 | ;;
|
---|
1231 | esac
|
---|
1232 | ;;
|
---|
1233 | esac
|
---|
1234 | ;;
|
---|
1235 | esac
|
---|
1236 |
|
---|
1237 | # The next commented-out line sets the prompt to include the command
|
---|
1238 | # number -- you should only un-comment this if it is the ONLY thing
|
---|
1239 | # you ever want as your prompt, because it will override attempts
|
---|
1240 | # to set PS1 from the command level. If you want the command number
|
---|
1241 | # in your prompt without sacrificing the ability to change the prompt
|
---|
1242 | # later, replace the default setting for PS1 before the beginning of
|
---|
1243 | # the main loop with the following: PS1='echo -n "${cmdno}% "'
|
---|
1244 | # Doing it this way is, however, slower than the simple version below.
|
---|
1245 |
|
---|
1246 | PS1="${cmdno}% "
|
---|
1247 |
|
---|
1248 | getcmd=yes
|
---|
1249 | echoit=no
|
---|
1250 | exclaim=no
|
---|
1251 | done
|
---|
1252 | exit 0
|
---|
1253 |
|
---|
1254 | # Christine Robertson {linus, ihnp4, decvax}!utzoo!globetek!chris
|
---|