mirrored from git://git.code.sf.net/p/zsh/code
/
FAQ.yo
2428 lines (2086 loc) · 108 KB
/
FAQ.yo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
mailto(pws@pwstephenson.fsnet.co.uk)\
whentxt(notableofcontents())\
COMMENT(-- mytt is like tt but adds quotes `like this' for plain text --)\
def(mytt)(1)(\
whentxt(`ARG1')\
whenhtml(tt(ARG1))\
whenlatex(tt(ARG1))\
whenms(tt(ARG1))\
whensgml(tt(ARG1)))\
COMMENT(-- mybf/em are like bf/em but add *emphasis* for text too --)\
def(mybf)(1)(\
whentxt(*ARG1*)\
whenhtml(bf(ARG1))\
whenlatex(bf(ARG1))\
whenms(bf(ARG1))\
whensgml(bf(ARG1)))\
def(myem)(1)(\
whentxt(_ARG1_)\
whenhtml(em(ARG1))\
whenlatex(em(ARG1))\
whenms(em(ARG1))\
whensgml(em(ARG1)))\
COMMENT(-- mydit is like dit but no `o' for text mode --)\
def(mydit)(1)(\
whenlatex(dit(ARG1))\
whenhtml(dit(ARG1))\
whentxt(ARG1)\
whenman(dit(ARG1))\
whenms(dit(ARG1))\
whensgml(dit(ARG1)))\
COMMENT(-- myeit is like eit but fancier text formatting --)\
def(myeit)(0)(\
whenlatex(eit())whenhtml(eit())whenman(eit())whenms(eit())whensgml(eit())\
whentxt(eit()CHAR(41)))\
def(myeitd)(0)(\
whenlatex(eit())whenhtml(eit())whenman(eit())whenms(eit())whensgml(eit())\
whentxt(.))\
COMMENT(-- don't want headers for text, USENET headers must come first --)\
def(myreport)(3)(\
whentxt(report()()())\
whenhtml(report(ARG1)(ARG2)(ARG3))\
whenlatex(report(ARG1)(ARG2)(ARG3))\
whenman(report(ARG1)(ARG2)(ARG3))\
whenms(report(ARG1)(ARG2)(ARG3))\
whensgml(report(ARG1)(ARG2)(ARG3)))\
def(startitem)(0)() \
def(enditem)(0)()\
def(item)(2)(
ARG1: ARG2)\
def(nofill)(1)(ARG1)
myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(2010/02/15)
COMMENT(-- the following are for Usenet and must appear first)\
description(\
mydit(Archive-Name:) unix-faq/shell/zsh
mydit(Last-Modified:) 2012/06/15
mydit(Submitted-By:) email(coordinator@zsh.org (Peter Stephenson))
mydit(Posting-Frequency:) Monthly
mydit(Copyright:) (C) P.W. Stephenson, 1995--2010 (see end of document)
)
This document contains a list of frequently-asked (or otherwise
significant) questions concerning the Z-shell, a command interpreter
for many UNIX systems which is freely available to anyone with FTP
access. Zsh is among the most powerful freely available Bourne-like
shell for interactive use.
If you have never heard of mytt(sh), mytt(csh) or mytt(ksh), then you are
probably better off to start by reading a general introduction to UNIX
rather than this document.
If you just want to know how to get your hands on the latest version,
skip to question link(1.6)(16); if you want to know what to do with
insoluble problems, go to link(5.2)(52).
whentxt(Notation: Quotes `like this' are ordinary textual quotation
marks. Other uses of quotation marks are input to the shell.)
COMMENT(-- need to do this specially in text since it should go here --)
whentxt(Contents:
Chapter 1: Introducing zsh and how to install it
1.1. Sources of information
1.2. What is it?
1.3. What is it good at?
1.4. On what machines will it run? (Plus important compilation notes)
1.5. What's the latest version?
1.6. Where do I get it?
1.7. I don't have root access: how do I make zsh my login shell?
Chapter 2: How does zsh differ from...?
2.1. sh and ksh?
2.2. csh?
2.3. Why do my csh aliases not work? (Plus other alias pitfalls.)
2.4. tcsh?
2.5. bash?
2.6. Shouldn't zsh be more/less like ksh/(t)csh?
2.7. What is zsh's support for Unicode/UTF-8?
Chapter 3: How to get various things to work
3.1. Why does `$var' where `var="foo bar"' not do what I expect?
3.2. In which startup file do I put...?
3.3. What is the difference between `export' and the ALL_EXPORT option?
3.4. How do I turn off spelling correction/globbing for a single command?
3.5. How do I get the Meta key to work on my xterm?
3.6. How do I automatically display the directory in my xterm title bar?
3.7. How do I make the completion list use eight bit characters?
3.8. Why do the cursor (arrow) keys not work? (And other terminal oddities.)
3.9. Why does my terminal act funny in some way?
3.10. Why does zsh not work in an Emacs shell mode any more?
3.11. Why do my autoloaded functions not autoload [the first time]?
3.12. How does base arithmetic work?
3.13. How do I get a newline in my prompt?
3.14. Why does `bindkey ^a command-name' or 'stty intr ^-' do something funny?
3.15. Why can't I bind \C-s and \C-q any more?
3.16. How do I execute command `foo' within function `foo'?
3.17. Why do history substitutions with single bangs do something funny?
3.18. Why does zsh kill off all my background jobs when I logout?
3.19. How do I list all my history entries?
3.20. How does the alternative loop syntax, e.g. mytt(while {...} {...}) work?
3.21. Why is my history not being saved?
3.22. How do I get a variable's value to be evaluated as another variable?
3.23. How do I prevent the prompt overwriting output when there is no newline?
3.24. What's wrong with cut and paste on my xterm?
3.25. How do I get coloured prompts on my colour xterm?
3.26. Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?
3.27. What are these `^' and `~' pattern characters, anyway?
Chapter 4: The mysteries of completion
4.1. What is completion?
4.2. What sorts of things can be completed?
4.3. How does zsh deal with ambiguous completions?
4.4. How do I complete in the middle of words / just what's before the cursor?
4.5. How do I get started with programmable completion?
4.6. Suppose I want to complete all files during a special completion?
Chapter 5: Multibyte input and output
5.1. What is multibyte input?
5.2. How does zsh handle multibyte input and output?
5.3. How do I ensure multibyte input and output work on my system?
5.4. How can I input characters that aren't on my keyboard?
Chapter 6: The future of zsh
6.1. What bugs are currently known and unfixed? (Plus recent important changes)
6.2. Where do I report bugs, get more info / who's working on zsh?
6.3. What's on the wish-list?
6.4. Did zsh have problems in the year 2000?
Acknowledgments
Copyright
--- End of Contents ---
)
chapter(Introducing zsh and how to install it)
sect(Sources of information)
label(11)
Information on zsh is available via the World Wide Web. The URL
is url(http://zsh.sourceforge.net/)(http://zsh.sourceforge.net/) .
The server provides this FAQ and much else and is
now maintained by the zsh workers (email email(zsh-workers@zsh.org)).
The FAQ is at \
url(http://zsh.sourceforge.net/FAQ/)(http://zsh.sourceforge.net/FAQ/) .
The site also contains some contributed zsh scripts and functions;
we are delighted to add more, or simply links to your own collection.
This document was originally written in YODL, allowing it to be converted
easily into various other formats. The master source file lives at
url(http://zsh.sourceforge.net/FAQ/zshfaq.yo)
(http://zsh.sourceforge.net/FAQ/zshfaq.yo) and the plain text version
can be found at url(http://zsh.sourceforge.net/FAQ/zshfaq.txt)
(http://zsh.sourceforge.net/FAQ/zshfaq.txt) .
Another useful source of information is the collection of FAQ articles
posted frequently to the Usenet news groups comp.unix.questions,
comp.unix.shells and comp.answers with answers to general questions
about UNIX. The fifth of the seven articles deals with shells,
including zsh, with a brief description of differences. There is
also a separate FAQ on shell differences and how to change your
shell. Usenet FAQs are available via FTP from rtfm.mit.edu and
mirrors and also on the World Wide Web; see
description(
mydit(USA) url(http://www.cis.ohio-state.edu/hypertext/faq/usenet/top.html)
(http://www.cis.ohio-state.edu/hypertext/faq/usenet/top.html)
mydit(UK) url(http://www.lib.ox.ac.uk/internet/news/faq/comp.unix.shell.html)
(http://www.lib.ox.ac.uk/internet/news/faq/comp.unix.shell.html)
mydit(Netherlands) url(http://www.cs.uu.nl/wais/html/na-dir/unix-faq/shell/.html)
(http://www.cs.uu.nl/wais/html/na-dir/unix-faq/shell/.html)
)
You can also get it via email by emailing \
email(mail-server@rtfm.mit.edu)
with, in the body of the message, mytt(send faqs/unix-faq/shell/zsh).
The latest version of this FAQ is also available directly from any
of the zsh archive sites listed in question link(1.6)(16).
I have put together a user guide to complement the manual by
explaining the most useful features of zsh in a more easy to read way.
This can be found at the zsh web site:
url(http://zsh.sourceforge.net/Guide/)(http://zsh.sourceforge.net/Guide/)
(As a method of reading the following in Emacs, you can type tt(\M-2
\C-x $) to make all the indented text vanish, then tt(\M-0 \C-x $)
when you are on the title you want.)
For any more eclectic information, you should contact the mailing
list: see question link(5.2)(52).
sect(What is it?)
Zsh is a UNIX command interpreter (shell) which of the standard
shells most resembles the Korn shell (ksh); its compatibility with
the 1988 Korn shell has been gradually increasing. It includes
enhancements of many types, notably in the command-line editor,
options for customising its behaviour, filename globbing, features
to make C-shell (csh) users feel more at home and extra features
drawn from tcsh (another `custom' shell).
It was written by Paul Falstad when a student at Princeton; however,
Paul doesn't maintain it any more and enquiries should be sent to
the mailing list (see question link(5.2)(52)). Zsh is distributed under a
standard Berkeley style copyright.
For more information, the files Doc/intro.txt or Doc/intro.troff
included with the source distribution are highly recommended. A list
of features is given in FEATURES, also with the source.
sect(What is it good at?)
Here are some things that zsh is particularly good at. No claim of
exclusivity is made, especially as shells copy one another, though
in the areas of command line editing and globbing zsh is well ahead
of the competition. I am not aware of a major interactive feature
in any other freely-available shell which zsh does not also have
(except smallness).
itemize(
it() Command line editing:
itemize(
it() programmable completion: incorporates the ability to use the
full power of zsh's globbing and shell programming features,
it() multi-line commands editable as a single buffer (even files!),
it() variable editing (vared),
it() command buffer stack,
it() print text straight into the buffer for immediate editing (print -z),
it() execution of unbound commands,
it() menu completion in two flavours,
it() variable, editing function and option name completion,
it() inline expansion of variables and history commands.
)
it() Globbing --- extremely powerful, including:
itemize(
it() recursive globbing (cf. find),
it() file attribute qualifiers (size, type, etc. also cf. find),
it() full alternation and negation of patterns.
)
it() Handling of multiple redirections (simpler than tee).
it() Large number of options for tailoring.
it() Path expansion (=foo -> /usr/bin/foo).
it() Adaptable messages for spelling, watch, time as well as prompt
(including conditional expressions).
it() Named directories.
it() Comprehensive integer and floating point arithmetic.
it() Manipulation of arrays (including reverse subscripting).
it() Associative arrays (key-to-value hashes)
it() Spelling correction.
)
sect(On what machines will it run?)
From version 3.0, zsh uses GNU autoconf as the installation
mechanism. This considerably increases flexibility over the old
`buildzsh' mechanism. Consequently, zsh should compile and run on
any modern version of UNIX, and a great many not-so-modern versions
too. The file MACHINES in the distribution has more details.
There used to be separate ports for Windows and OS/2, but these
are rather out of date and hard to get; however, zsh exists for
the Cygwin environment. See further notes below.
If you need to change something to support a new machine, it would be
appreciated if you could add any necessary preprocessor code and
alter configure.in and acconfig.h to configure zsh automatically,
then send the required context diffs to the list (see question
link(5.2)(52)). Please make sure you have the latest version first.
To get it to work, retrieve the source distribution (see question
link(1.6)(16)), un-gzip it, un-tar it and read the INSTALL file in the top
directory. Also read the MACHINES file for up-to-date
information on compilation on certain architectures.
mybf(Note for users of nawk) (The following information comes from Zoltan
Hidvegi): On some systems nawk is broken and produces an incorrect
signames.h file. This makes the signals code unusable. This often happens
on Ultrix, HP-UX, IRIX (?). Install gawk if you experience such problems.
sect(What's the latest version?)
Zsh 5.0.5 is the latest production version. For details of all the
changes, see the NEWS file in the source distribution.
A beta of the next version is sometimes available. Development of zsh is
patch by patch, with each intermediate version publicly available. Note
that this `open' development system does mean bugs are sometimes
introduced into the most recent archived version. These are usually
fixed quickly. If you are really interested in getting the latest
improvements, and less worried about providing a stable environment,
development versions are uploaded quite frequently to the archive in the
tt(development) subdirectory.
Note also that as the shell changes, it may become incompatible with
older versions; see the end of question link(5.1)(51) for a partial list.
Changes of this kind are almost always forced by an awkward or
unnecessary feature in the original design (as perceived by current
users), or to enhance compatibility with other Bourne shell
derivatives, or (mostly in the 3.0 series) to provide POSIX compliancy.
sect(Where do I get it?)
label(16)
The coordinator of development is currently me; the alias
email(coordinator@zsh.org) can be used to contact whoever is in the hot
seat. The following are known mirrors (kept frequently up to date); the
first is the official archive site, currently in Australia. All are
available by anonymous FTP. The major sites keep test versions in the
`testing' subdirectory: such up-to-the-minute development versions should
only be retrieved if you actually plan to help test the latest version of
the shell. The following list also appears on the WWW at
url(http://www.zsh.org/)(http://www.zsh.org/) .
includefile(../Doc/Zsh/ftp_sites.yo)
A Windows port was created by Amol Deshpandem based on 3.0.5 (which
is now rather old). This has now been restored and can be found at
url(http://zsh-nt.sourceforge.net/)(http://zsh-nt.sourceforge.net/).
All recent releases of zsh compile under Cygwin, a freely available
UNIX-style environment for the Win32 API, and a pre-compiled version of
zsh can be downloaded by the Cygwin installer. You can find information
about this at url(http://www.cygwin.com/)(http://www.cygwin.com/).
Please email email(zsh-workers@zsh.org) if you have information about
other ports.
Starting from mid-October 1997, there is an archive of patches sent
to the maintainers' mailing list. Note that these may not all be
added to the shell, and some may already have been; you simply have
to search for something you might want which is not in the version
you have. Also, there may be some prerequisites earlier in the
archive. It can be found on the zsh WWW pages (as described in
link(1.1)(11)) at:
description(
mydit() url(http://zsh.sourceforge.net/Patches/)
(http://zsh.sourceforge.net/Patches/)
)
sect(I don't have root access: how do I make zsh my login shell?)
Unfortunately, on many machines you can't use mytt(chsh) to change your
shell unless the name of the shell is contained in /etc/shells, so if
you have your own copy of zsh you need some sleight-of-hand to use it
when you log on. (Simply typing mytt(zsh) is not really a solution since
you still have your original login shell waiting for when you exit.)
The basic idea is to use mytt(exec <zsh-path>) to replace the current
shell with zsh. Often you can do this in a login file such as .profile
(if your shell is sh or ksh) or .login (if it's csh). Make sure you
have some way of altering the file (e.g. via FTP) before you try this as
mytt(exec) is often rather unforgiving.
If you have zsh in a subdirectory mytt(bin) of your home directory,
put this in .profile:
verb(
[ -f $HOME/bin/zsh ] && exec $HOME/bin/zsh -l
)
or if your login shell is csh or tcsh, put this in .login:
verb(
if ( -f ~/bin/zsh ) exec ~/bin/zsh -l
)
(in each case the mytt(-l) tells zsh it is a login shell).
If you want to check this works before committing yourself to it,
you can make the login shell ask whether to exec zsh. The following
work for Bourne-like shells:
verb(
[ -f $HOME/bin/zsh ] && {
echo "Type Y to run zsh: \c"
read line
[ "$line" = Y ] && exec $HOME/bin/zsh -l
}
)
and for C-shell-like shells:
verb(
if ( -f ~/bin/zsh ) then
echo -n "Type Y to run zsh: "
if ( "$<" == Y ) exec ~/bin/zsh -l
endif
)
It's not a good idea to put this (even without the -l) into .cshrc,
at least without some tests on what the csh is supposed to be doing,
as that will cause _every_ instance of csh to turn into a zsh and
will cause csh scripts (yes, unfortunately some people write these)
which do not call `csh -f' to fail. If you want to tell xterm to
run zsh, change the SHELL environment variable to the full path of
zsh at the same time as you exec zsh (in fact, this is sensible for
consistency even if you aren't using xterm). If you have to exec
zsh from your .cshrc, a minimum safety check is mytt(if ($?prompt) exec
zsh).
If you like your login shell to appear in the process list as mytt(-zsh),
you can link mytt(zsh) to mytt(-zsh) (e.g. by mytt(ln -s ~/bin/zsh
~/bin/-zsh)) and change the exec to mytt(exec -zsh). (Make sure
mytt(-zsh) is in your path.) This has the same effect as the mytt(-l)
option.
Footnote: if you DO have root access, make sure zsh goes in
/etc/shells on all appropriate machines, including NIS clients, or you
may have problems with FTP to that machine.
chapter(How does zsh differ from...?)
As has already been mentioned, zsh is most similar to ksh, while many
of the additions are to please csh users. Here are some more detailed
notes. See also the article `UNIX shell differences and how to change
your shell' posted frequently to the USENET group comp.unix.shell.
sect(Differences from sh and ksh)
label(21)
Most features of ksh (and hence also of sh) are implemented in zsh;
problems can arise because the implementation is slightly different.
Note also that not all ksh's are the same either. I have based this
on the 11/16/88f version of ksh; differences from ksh93 will be more
substantial.
As a summary of the status:
enumerate(
myeit() because of all the options it is not safe to assume a general
zsh run by a user will behave as if sh or ksh compatible;
myeit() invoking zsh as sh or ksh (or if either is a symbolic link to
zsh) sets appropriate options and improves compatibility (from
within zsh itself, calling mytt(ARGV0=sh zsh) will also work);
myeit() from version 3.0 onward the degree of compatibility with sh
under these circumstances is very high: zsh can now be used
with GNU configure or perl's Configure, for example;
myeit() the degree of compatibility with ksh is also high, but a few
things are missing: for example the more sophisticated
pattern-matching expressions are different for versions before
3.1.3 --- see the detailed list below;
myeit() also from 3.0, the command `emulate' is available: `emulate
ksh' and `emulate sh' set various options as well as changing the
effect of single-letter option flags as if the shell had been
invoked with the appropriate name. Including the command
`emulate sh; setopt localoptions' in a shell function will
turn on sh emulation for that function only. In version 4 (and in
3.0.6 through 8), this can be abbreviated as `emulate -L sh'.
)
The classic difference is word splitting, discussed in question \
link(3.1)(31);
this catches out very many beginning zsh users. As explained there,
this is actually a bug in every other shell. The answer is to set
tt(SH_WORD_SPLIT) for backward compatibility. The next most classic
difference is that unmatched glob patterns cause the command to abort;
set tt(NO_NOMATCH) for those.
Here is a list of various options which will increase ksh
compatibility, though maybe decrease zsh's abilities: see the manual
entries for tt(GLOB_SUBST), tt(IGNORE_BRACES) (though brace expansion occurs
in some versions of ksh), tt(KSH_ARRAYS), tt(KSH_GLOB), tt(KSH_OPTION_PRINT),
tt(LOCAL_OPTIONS), tt(NO_BAD_PATTERN), tt(NO_BANG_HIST), tt(NO_EQUALS), \
tt(NO_HUP),
tt(NO_NOMATCH), tt(NO_RCS), tt(NO_SHORT_LOOPS), tt(PROMPT_SUBST), \
tt(RM_STAR_SILENT),
tt(POSIX_ALIASES), tt(POSIX_BUILTINS), tt(POSIX_IDENTIFIERS),
tt(SH_FILE_EXPANSION), tt(SH_GLOB), tt(SH_OPTION_LETTERS),
tt(SH_WORD_SPLIT) (see question link(3.1)(31)) and tt(SINGLE_LINE_ZLE).
Note that you can also disable any built-in commands which get in
your way. If invoked as `ksh', the shell will try to set suitable
options.
Here are some differences from ksh which might prove significant for
ksh programmers, some of which may be interpreted as bugs; there
must be more. Note that this list is deliberately rather full and
that most of the items are fairly minor. Those marked `*' perform
in a ksh-like manner if the shell is invoked with the name `ksh', or
if `emulate ksh' is in effect. Capitalised words with underlines
refer to shell options.
itemize(
it() Syntax:
itemize(
it()* Shell word splitting: see question link(3.1)(31).
it()* Arrays are (by default) more csh-like than ksh-like:
subscripts start at 1, not 0; tt(array[0]) refers to tt(array[1]);
mytt($array) refers to the whole array, not tt($array[0]);
braces are unnecessary: tt($a[1] == ${a[1]}), etc.
Set the tt(KSH_ARRAYS) option for compatibility.
it() Furthermore, individual elements of arrays in zsh are always
strings, not separate parameters. This means, for example, you
can't `unset' an array element in zsh as you can in ksh; you
can only set it to the empty string, or shorten the array.
(You can unset elements of associative arrays in zsh because
those are a completely different type of object.)
it() Coprocesses are established by mytt(coproc); mytt(|&) behaves like
csh. Handling of coprocess file descriptors is also different.
it() In mytt(cmd1 && cmd2 &), only mytt(cmd2) instead of the whole
expression is run in the background in zsh. The manual implies
this is a bug. Use mytt({ cmd1 && cmd2 } &) as a workaround.
)
it() Command line substitutions, globbing etc.:
itemize(
it()* Failure to match a globbing pattern causes an error (use
tt(NO_NOMATCH)).
it()* The results of parameter substitutions are treated as plain text:
mytt(foo="*"; print $foo) prints all files in ksh but mytt(*) in zsh
(use tt(GLOB_SUBST)).
it()* tt($PSn) do not do parameter substitution by default (use \
PROMPT_SUBST).
it()* Standard globbing does not allow ksh-style `pattern-lists'.
Equivalents:
verb(
----------------------------------------------------------------------
ksh zsh Meaning
------ ------ ---------
!(foo) ^foo Anything but foo.
or foo1~foo2 Anything matching foo1 but foo2[1].
@(foo1|foo2|...) (foo1|foo2|...) One of foo1 or foo2 or ...
?(foo) (foo|) Zero or one occurrences of foo.
*(foo) (foo)# Zero or more occurrences of foo.
+(foo) (foo)## One or more occurrences of foo.
----------------------------------------------------------------------
)
The mytt(^), mytt(~) and mytt(#) (but not mytt(|))forms require \
tt(EXTENDED_GLOB).
From version 3.1.3, the ksh forms are fully supported when the
option tt(KSH_GLOB) is in effect; for previous versions you
must use the table above.
[1] See question link(3.27)(327) for more on the mysteries of
mytt(~) and mytt(^).
it() Unquoted assignments do file expansion after mytt(:)s (intended for
PATHs).
it()* mytt(typeset) and mytt(integer) have special behaviour for
assignments in ksh, but not in zsh. For example, this doesn't
work in zsh:
verb(
integer k=$(wc -l ~/.zshrc)
)
because the return value from tt(wc) includes leading
whitespace which causes wordsplitting. Ksh handles the
assignment specially as a single word.
)
it() Command execution:
itemize(
it()* There is no tt($ENV) variable (use tt(/etc/zshrc), tt(~/.zshrc);
note also tt($ZDOTDIR)).
it()* tt($PATH) is not searched for commands specified
at invocation without -c.
)
it() Aliases and functions:
itemize(
it() The order in which aliases and functions are defined is significant:
function definitions with () expand aliases -- see question \
link(2.3)(23).
it() Aliases and functions cannot be exported.
it() There are no tracked aliases: command hashing replaces these.
it() The use of aliases for key bindings is replaced by `bindkey'.
it()* Options are not local to functions (use LOCAL_OPTIONS; note this
may always be unset locally to propagate options settings from a
function to the calling level).
it() Functions defined with `function funcname { body }' behave the
same way as those defined with `funcname () { body }'. In ksh,
the former behave as if the body were read from a file with `.',
and only the latter behave as true functions.
)
it() Traps and signals:
itemize(
it()* Traps are not local to functions. The option LOCAL_TRAPS is
available from 3.1.6.
it() TRAPERR has become TRAPZERR (this was forced by UNICOS which
has SIGERR).
)
it() Editing:
itemize(
it() The options tt(gmacs), tt(viraw) are not supported.
Use bindkey to change the editing behaviour: mytt(set -o {emacs,vi})
becomes `bindkey -{e,v}', although `set -o emacs' and `set -o vi'
are supported for compatibility; for gmacs, go to emacs mode and
use `bindkey \^t gosmacs-transpose-characters'.
it() The mytt(keyword) option does not exist and mytt(-k) is instead
interactivecomments. (mytt(keyword) is not in recent versions
of ksh either.)
it()* Management of histories in multiple shells is different:
the history list is not saved and restored after each command.
The option tt(SHARE_HISTORY) appeared in 3.1.6 and is set in ksh
compatibility mode to remedy this.
it() mytt(\) does not escape editing chars (use mytt(^V)).
it() Not all ksh bindings are set (e.g. mytt(<ESC>#); try mytt(<ESC>q)).
it()* mytt(#) in an interactive shell is not treated as a comment by
default.
it() In vi command mode the keys "k" and "j" move the cursor to the
end of the line. To move the cursor to the start instead, use
verb(
bindkey -M vicmd 'k' vi-up-line-or-history
bindkey -M vicmd 'j' vi-down-line-or-history
)
)
it() Built-in commands:
itemize(
it() Some built-ins (tt(r), tt(autoload), tt(history), tt(integer) ...)
were aliases in ksh.
it() There is no built-in command newgrp: use e.g. mytt(alias
newgrp="exec newgrp")
it() mytt(jobs) has no mytt(-n) flag.
)
it() Other idiosyncrasies:
itemize(
it() mytt(select) always redisplays the list of selections on each loop.
)
)
sect(Similarities with csh)
Although certain features aim to ease the withdrawal symptoms of csh
(ab)users, the syntax is in general rather different and you should
certainly not try to run scripts without modification. The c2z script
is provided with the source (in Misc/c2z) to help convert .cshrc
and .login files; see also the next question concerning aliases,
particularly those with arguments.
Csh-compatibility additions include:
itemize(
it() tt(logout), tt(rehash), tt(source), tt((un)limit) built-in commands.
it() tt(*rc) file for interactive shells.
it() Directory stacks.
it() tt(cshjunkie*), tt(ignoreeof) options.
it() The tt(CSH_NULL_GLOB) option.
it() tt(>&), tt(|&) etc. redirection.
(Note that mytt(>file 2>&1) is the standard Bourne shell command for
csh's mytt(>&file).)
it() tt(foreach ...) loops; alternative syntax for other loops.
it() Alternative syntax mytt(if ( ... ) ...), though this still doesn't
work like csh: it expects a command in the parentheses. Also
mytt(for), mytt(which).
it() tt($PROMPT) as well as tt($PS1), tt($status) as well as tt($?),
tt($#argv) as well as tt($#), ....
it() Escape sequences via tt(%) for prompts.
it() Special array variables tt($PATH) etc. are colon-separated, tt($path)
are arrays.
it() tt(!)-type history (which may be turned off via mytt(setopt
nobanghist)).
it() Arrays have csh-like features (see under link(2.1)(21)).
)
sect(Why do my csh aliases not work? (Plus other alias pitfalls.))
label(23)
First of all, check you are using the syntax
verb(
alias newcmd='list of commands'
)
and not
verb(
alias newcmd 'list of commands'
)
which won't work. (It tells you if `newcmd' and `list of commands' are
already defined as aliases.)
Otherwise, your aliases probably contain references to the command
line of the form mytt(\!*), etc. Zsh does not handle this behaviour as it
has shell functions which provide a way of solving this problem more
consistent with other forms of argument handling. For example, the
csh alias
verb(
alias cd 'cd \!*; echo $cwd'
)
can be replaced by the zsh function,
verb(
cd() { builtin cd "$@"; echo $PWD; }
)
(the `builtin' tells zsh to use its own `cd', avoiding an infinite loop)
or, perhaps better,
verb(
cd() { builtin cd "$@"; print -D $PWD; }
)
(which converts your home directory to a tt(~)). In fact, this problem is
better solved by defining the special function chpwd() (see the manual).
Note also that the mytt(;) at the end of the function is optional in zsh,
but not in ksh or sh (for sh's where it exists).
Here is Bart Schaefer's guide to converting csh aliases for zsh.
enumerate(
myeit() If the csh alias references "parameters" (tt(\!:1), tt(\!*) etc.),
then in zsh you need a function (referencing tt($1), tt($*) etc.).
Otherwise, you can use a zsh alias.
myeit() If you use a zsh function, you need to refer _at_least_ to
tt($*) in the body (inside the tt({ })). Parameters don't magically
appear inside the tt({ }) the way they get appended to an alias.
myeit() If the csh alias references its own name (tt(alias rm "rm -i")),
then in a zsh function you need the "command" or "builtin" keyword
(function tt(rm() { command rm -i "$@" })), but in a zsh alias
you don't (tt(alias rm="rm -i")).
myeit() If you have aliases that refer to each other (tt(alias ls "ls -C";
alias lf "ls -F" ==> lf == ls -C -F)) then you must either:
itemize(
it() convert all of them to zsh functions; or
it() after converting, be sure your .zshrc defines all of your
aliases before it defines any of your functions.
)
Those first four are all you really need, but here are four more for
heavy csh alias junkies:
myeit() Mapping from csh alias "parameter referencing" into zsh function
(assuming tt(SH_WORD_SPLIT) and tt(KSH_ARRAYS) are NOT set in zsh):
verb(
csh zsh
===== ==========
\!* $* (or $argv)
\!^ $1 (or $argv[1])
\!:1 $1
\!:2 $2 (or $argv[2], etc.)
\!$ $*[$#] (or $argv[$#], or $*[-1])
\!:1-4 $*[1,4]
\!:1- $*[1,$#-1] (or $*[1,-2])
\!^- $*[1,$#-1]
\!*:q "$@"
\!*:x $=* ($*:x doesn't work (yet))
)
myeit() Remember that it is NOT a syntax error in a zsh function to
refer to a position (tt($1), tt($2), etc.) greater than the number of
parameters. (E.g., in a csh alias, a reference to tt(\!:5) will
cause an error if 4 or fewer arguments are given; in a zsh
function, tt($5) is the empty string if there are 4 or fewer
parameters.)
myeit() To begin a zsh alias with a - (dash, hyphen) character, use
mytt(alias --):
verb(
csh zsh
=============== ==================
alias - "fg %-" alias -- -="fg %-"
)
myeit() Stay away from mytt(alias -g) in zsh until you REALLY know what
you're doing.
)
There is one other serious problem with aliases: consider
verb(
alias l='/bin/ls -F'
l() { /bin/ls -la "$@" | more }
)
mytt(l) in the function definition is in command position and is expanded
as an alias, defining mytt(/bin/ls) and mytt(-F) as functions which call
mytt(/bin/ls), which gets a bit recursive. This can be avoided if you use
mytt(function) to define a function, which doesn't expand aliases. It is
possible to argue for extra warnings somewhere in this mess.
Bart Schaefer's rule is: Define first those aliases you expect to
use in the body of a function, but define the function first if the
alias has the same name as the function.
If you aware of the problem, you can always escape part or all of the
name of the function:
verb(
'l'() { /bin/ls -la "$@" | more }
)
Adding the quotes has no effect on the function definition, but
suppresses alias expansion for the function name. Hence this is
guaranteed to be safe---unless you are in the habit of defining
aliases for expressions such as tt('l'), which is valid, but probably
confusing.
sect(Similarities with tcsh)
(The sections on csh apply too, of course.) Certain features have
been borrowed from tcsh, including tt($watch), tt(run-help), tt($savehist),
periodic commands etc., extended prompts, tt(sched) and tt(which) built-ins.
Programmable completion was inspired by, but is entirely different to,
tcsh's mytt(complete). (There is a perl script called tt(lete2ctl) in the
Misc directory of the source distribution to convert mytt(complete) to \
mytt(compctl)
statements.) This list is not definitive: some features have gone in
the other direction.
If you're missing the editor function tt(run-fg-editor), try something
with mytt(bindkey -s) (which binds a string to a keystroke), e.g.
verb(
bindkey -s '^z' '\eqfg %$EDITOR:t\n'
)
which pushes the current line onto the stack and tries to bring a job
with the basename of your editor into the foreground. mytt(bindkey -s)
allows limitless possibilities along these lines. You can execute
any command in the middle of editing a line in the same way,
corresponding to tcsh's mytt(-c) option:
verb(
bindkey -s '^p' '\eqpwd\n'
)
In both these examples, the mytt(\eq) saves the current input line to
be restored after the command runs; a better effect with multiline
buffers is achieved if you also have
verb(
bindkey '\eq' push-input
)
to save the entire buffer. In version 4 and recent versions of zsh 3.1,
you have the following more sophisticated option,
verb(
run-fg-editor() {
zle push-input
BUFFER="fg %$EDITOR:t"
zle accept-line
}
zle -N run-fg-editor
)
and can now bind tt(run-fg-editor) just like any other editor function.
sect(Similarities with bash)
The Bourne-Again Shell, bash, is another enhanced Bourne-like shell;
the most obvious difference from zsh is that it does not attempt to
emulate the Korn shell. Since both shells are under active
development it is probably not sensible to be too specific here.
Broadly, bash has paid more attention to standards compliancy
(i.e. POSIX) for longer, and has so far avoided the more abstruse
interactive features (programmable completion, etc.) that zsh has.
In recent years there has been a certain amount of crossover in the
extensions, however. Zsh (as of 3.1.6) has bash's `tt(${var/old/new})'
feature for replacing the text tt(old) with the text tt(new) in the
parameter tt($var). Note one difference here: while both shells
implement the syntax `tt(${var/#old/new})' and `tt(${var/%old/new})' for
anchoring the match of tt(old) to the start or end of the parameter text,
respectively, in zsh you can't put the `tt(#)' or `tt(%)' inside a
parameter: in other words `tt({var/$old/new})' where tt(old) begins with
a `tt(#)' treats that as an ordinary character in zsh, unlike bash. To
do this sort of thing in zsh you can use (from 3.1.7) the new syntax
for anchors in any pattern, `tt((#s))' to match the start of a string,
and `tt((#e))' to match the end. These require the option
tt(EXTENDED_GLOB) to be set.
sect(Shouldn't zsh be more/less like ksh/(t)csh?)
People often ask why zsh has all these `unnecessary' csh-like features,
or alternatively why zsh doesn't understand more csh syntax. This is
far from a definitive answer and the debate will no doubt continue.
Paul's object in writing zsh was to produce a ksh-like shell which
would have features familiar to csh users. For a long time, csh was
the preferred interactive shell and there is a strong resistance to
changing to something unfamiliar, hence the additional syntax and
tt(CSH_JUNKIE) options. This argument still holds. On the other hand,
the arguments for having what is close to a plug-in replacement for ksh
are, if anything, even more powerful: the deficiencies of csh as a
programming language are well known (look in any Usenet FAQ archive, e.g.
url(http://www.cis.ohio-state.edu/hypertext/faq/usenet/unix-faq/\
shell/csh-whynot/faq.html)
(http://www.cis.ohio-state.edu/hypertext/faq/usenet/unix-faq/shell/csh-whynot/faq.html)
if you are in any doubt) and zsh is able to run many standard
scripts such as /etc/rc.
Of course, this makes zsh rather large and feature-ridden so that it
seems to appeal mainly to hackers. The only answer, perhaps not
entirely satisfactory, is that you have to ignore the bits you don't
want. The introduction of loadable in modules in version 3.1 should
help.
sect(What is zsh's support for Unicode/UTF-8?)
`Unicode', or UCS for Universal Character Set, is the modern way
of specifying character sets. It replaces a large number of ad hoc
ways of supporting character sets beyond ASCII. `UTF-8' is an
encoding of Unicode that is particularly natural on Unix-like systems.
The production branch of zsh, 4.2, has very limited support:
the built-in printf command supports "\u" and "\U" escapes
to output arbitrary Unicode characters; ZLE (the Zsh Line Editor) has
no concept of character encodings, and is confused by multi-octet
encodings.
However, the 4.3 branch has much better support, and furthermore this
is now fairly stable. (Only a few minor areas need fixing before
this becomes a production release.) This is discussed more
fully below, see `Multibyte input and output'.
chapter(How to get various things to work)
sect(Why does mytt($var) where mytt(var="foo bar") not do what I expect?)
label(31)
In most Bourne-shell derivatives, multiple-word variables such as
verb(
var="foo bar"
)
are split into words when passed to a command or used in a mytt(for foo in
$var) loop. By default, zsh does not have that behaviour: the
variable remains intact. (This is not a bug! See below.) The option
tt(SH_WORD_SPLIT) exists to provide compatibility.
For example, defining the function args to show the number of its
arguments:
verb(
args() { echo $#; }
)
and with our definition of `var',
verb(
args $var
)
produces the output `1'. After
verb(
setopt shwordsplit
)
the same function produces the output `2', as with sh and ksh.
Unless you need strict sh/ksh compatibility, you should ask yourself
whether you really want this behaviour, as it can produce unexpected
effects for variables with entirely innocuous embedded spaces. This
can cause horrendous quoting problems when invoking scripts from
other shells. The natural way to produce word-splitting behaviour
in zsh is via arrays. For example,
verb(
set -A array one two three twenty
)
(or
verb(
array=(one two three twenty)
)
if you prefer), followed by
verb(
args $array
)
produces the output `4', regardless of the setting of tt(SH_WORD_SPLIT).
Arrays are also much more versatile than single strings. Probably
if this mechanism had always been available there would never have
been automatic word splitting in scalars, which is a sort of
uncontrollable poor man's array.
Note that this happens regardless of the value of the internal field
separator, tt($IFS); in other words, with mytt(IFS=:; foo=a:b; args $foo)
you get the answer 1.
Other ways of causing word splitting include a judicious use of
`eval':
verb(
sentence="Longtemps, je me suis couch\\'e de bonne heure."
eval "words=($sentence)"
)
after which $words is an array with the words of $sentence (note
characters special to the shell, such as the mytt(') in this example,
must already be quoted), or, less standard but more reliable,
turning on tt(SH_WORD_SPLIT) for one variable only:
verb(
args ${=sentence}
)
always returns 8 with the above definition of mytt(args). (In older
versions of zsh, tt(${=foo}) toggled tt(SH_WORD_SPLIT); now it forces it on.)
Note also the tt("$@") method of word splitting is always available in zsh
functions and scripts (though strictly this does array splitting, not
word splitting). This is more portable than the tt($*), since it
will work regardless of the tt(SH_WORD_SPLIT) setting; the other
difference is that tt($*) removes empty arguments from the array.
You can fix the first half of that objection by using tt(${==*}),
which turns off tt(SH_WORD_SPLIT) for the duration of the expansion.
tt(SH_WORD_SPLIT) is set when zsh is invoked with the names `ksh' or `sh',
or (entirely equivalent) when mytt(emulate ksh) or mytt(emulate sh) is in
effect.
There is one other effect of word splitting which differs between ksh
and zsh. In ksh, the builtin commands that declare parameters such
as tt(typeset) and tt(export) force word-splitting not to take place
after on an assignment argument:
verb(
typeset param=`echo foo bar`
)
in ksh will create a parameter with value mytt(foo bar), but in zsh will
create a parameter tt(param) with value tt(foo) and a parameter tt(bar)
whose value is empty. Contrast this with a normal assignment (no