summaryrefslogtreecommitdiffhomepage
path: root/tcsh.html.markdown
blob: 8f8429bc10fbffc2c76dbcdce9c40295ea257169 (plain)
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
---
category: tool
tool: tcsh
filename: LearnTCSH.csh
contributors:
       - ["Nicholas Christopoulos", "https://github.com/nereusx"]

---
tcsh ("tee-see-shell") is a Unix shell based on and compatible with the C shell (csh).
It is essentially the C shell with programmable command-line completion, command-line editing,
and a few other features.
It is the native root shell for BSD-based systems such as FreeBSD.

Almost all Linux distros and BSD today use tcsh instead of the original csh. In
most cases csh is a symbolic link that points to tcsh.
This is because tcsh is backward compatible with csh, and the last
is not maintained anymore.

- [TCSH Home](http://www.tcsh.org/)
- [TCSH Wikipedia](https://en.wikipedia.org/wiki/Tcsh)
- [TCSH manual page](http://www.tcsh.org/tcsh.html/top.html)
- [“An Introduction to the C shell”, William Joy](https://docs.freebsd.org/44doc/usd/04.csh/paper.html)
- [TCSH Bug reports and/or features requests](https://bugs.gw.com/)

Some more files:
[tcsh help command (for 132x35 terminal size)](https://github.com/nereusx/dotfiles/blob/master/csh-help),
[my ~/.tcshrc](https://github.com/nereusx/dotfiles/blob/master/.tcshrc)

```tcsh
#!/bin/tcsh
# The first line of the script is a shebang which tells the system how to execute
# the script: http://en.wikipedia.org/wiki/Shebang_(Unix)
# TCSH emulates the shebang on systems that don't understand it.

# In most cases you'll use `#!/bin/tcsh -f`, because `-f` option does not load
# any resource or start-up files, or perform any command hashing, and thus
# starts faster.

# --- the echo command --------------------------------------------------------
# The `echo` writes each word to the shell's standard output, separated by
# spaces and terminated with a newline. The echo_style shell variable may be
# set to emulate (or not) the flags and escape sequences.

# Display the value of echo_style
echo $echo_style

# Enable `echo` to support backslashed characters and `-n` option (no new line)
# This is the default for tcsh, but your distro may change it. Slackware has
# done so.
set echo_style = both

# Prints "Hello world"
echo Hello world
echo "Hello world"
echo 'Hello world'
echo `echo Hello world`

# This prints "twonlines" in one line
echo two\nlines

# Prints the two lines
echo "two\nlines"
echo 'two\nlines'

# --- Basic Syntax ------------------------------------------------------------

# A special character (including a blank or tab) may be prevented from having
# its special meaning by preceding it with a backslash `\`.
# This will display the last history commands
echo !!
# This will not
echo \!\!

# Single quotes prevent expanding special characters too, but some
# characters like `!` and backslash have higher priority
# `$` (variable value) will not expand
echo '$1 tip'
# `!` (history) will expand
echo '!!'

# Strings enclosed by back-quotes will be executed and replaced by the result.
echo `ls`

# Semi-colon separate commands
echo 'first line'; echo 'second line'

# There is also conditional execution
echo "Always executed" || echo "Only executed if the first command fails"
echo "Always executed" && echo "Only executed if the first command does NOT fail"

# Parenthesised commands are always executed in a subshell,

# example: creates a project and then informs you that it finished while
# it does the installation.
make && ( espeak "BOSS, compilation finished"; make install )

# prints the home directory but leaves you where you were
(cd; pwd); pwd

# Read tcsh man-page documentation
man tcsh

# --- Variables ---------------------------------------------------------------
# The shell maintains a list of variables, each of which has as value a list of
# zero or more words. The values of shell variables can be displayed and
# changed with the `set` and `unset` commands.
# The system maintains its own list of "environment" variables.
# These can be displayed and changed with `printenv`, `setenv`, and `unsetenv`.
# The syntax of `setenv` is similar to POSIX sh.

# Assign a value or nothing will create a variable
# Assign nothing
set var
# Assign a numeric value
# the '@' denotes the expression is arithmetic; it works similar to 'set' but
# the right value can be a numeric expression.
@ var = 1 + 2
# Assign a string value
set var = "Hello, I am the contents of 'var' variable"
# Assign the output of a program
set var = `ls`

# Remove a variable
unset var
# Prints 1 (true) if the variable `var` exists otherwise prints 0 (false)
echo $?var
# Print all variables and their values
set

# Prints the contents of 'var'
echo $var;
echo "$var";
# Prints the string `$var`
echo \$var
echo '$var'
# Braces can be used to separate variables from the rest when it is needed
set num = 12; echo "There ${num}th element"

# Prints the number of characters of the value: 6
set var = '123456'; echo $%var

### LISTs
# Assign a list of values
set var = ( one two three four five )
# Print all the elements: one two three four five
echo $var
echo $var[*]
# Print the count of elements: 5
echo $#var
# Print the indexed element; This prints the second element: two
echo $var[2]
# Print range of elements; prints 2nd up to 3rd: two, three
echo $var[2-3]
# Prints all elements starting from the 3rd: three four five
echo $var[3-]
# Prints print all up to 3rd element: one two three
echo $var[-3]

### Special Variables
# $argv         list of command-line arguments
# $argv[0]      this file-name (the file of the script file)
# $# $0, $n, $* are the same as $#argv, $argv[0], $argv[n], $argv[*]
# $status, $?   the exit code of the last command that executed
# $_            the previous command line
# $!            the PID of the last background process started by this shell
# $$            script's PID

# $path, $PATH  the list of directories that will search for an executable to run
# $home, $HOME  user's home directory, also the `~` can be used instead
# $uid          user's login ID
# $user         user's login name
# $gid          the user's group ID
# $group        the user's group-name
# $cwd, $PWD    the Current/Print Working Directory
# $owd          the previous working directory
# $tcsh         tcsh version
# $tty          the current tty; ttyN for Linux console, pts/N for terminal
#               emulators under X
# $term         the terminal type
# $verbose      if set, causes the words of each command to be printed.
#               can be set by the `-v` command line option too.
# $loginsh      if set, it is a login shell

# TIP: $?0 is always false in interactive shells
# TIP: $?prompt is always false in non-interactive shells
# TIP: if `$?tcsh` is unset; you run the original `csh` or something else;
#      try `echo $shell`
# TIP: `$verbose` is useful for debugging scripts
# NOTE: `$PWD` and `$PATH` are synchronised with `$cwd` and `$pwd` automatically.

# --- Variable modifiers ------------------------------------------------------
# Syntax: ${var}:m[:mN]
# Where <m> is:
# h : the directory  t : the filename  r : remove extension   e : the extension
# u : uppercase the first lowercase letter
# l : lowercase the first uppercase letter
# p : print but do not execute it (hist)
# q : quote the substituted words, preventing further substitutions
# x : like q, but break into words at white spaces
# g : apply the following modifier once to each word
# a  : apply the following modifier as many times as possible to single word
# s/l/r/ : search for `l` and replace with `r`, not regex; the `&` in the `r` is
# replaced by `l`
# & : Repeat the previous substitution

# start with this file
set f = ~/Documents/Alpha/beta.txt
# prints ~/Documents/Alpha/beta
echo $f:r
# prints ~/Documents/Alpha
echo $f:h
# prints beta.txt
echo $f:t
# prints txt
echo $f:e
# prints beta
echo $f:t:r
# prints Beta
echo $f:t:r:u
# prints Biota
echo $f:t:r:u:s/eta/iota/

# --- Redirection -------------------------------------------------------------

# Create file.txt and write the standard output to it
echo 'this string' > file.txt
# Create file.txt and write the standard output and standard error to it
echo 'this string' >& file.txt
# Append the standard output to file.txt
echo 'this string' >> file.txt
# Append the standard output and standard error to file.txt
echo 'this string' >>& file.txt
# Redirect the standard input from file.txt
cat < file.txt
# Input from keyboard; this stores the input line to variable `x`
set x = $<
# Document here;
cat << LABEL
...text here...
LABEL

# TIP: this is how to get standard error separated:
(grep 'AGP' /usr/src/linux/Documentation/* > output-file.txt) >& error-file.txt

# example: read a name from standard input and display a greetings message
echo -n "Enter your name: "
set name = $<
echo "Greetings $name"

# --- Expressions ------------------------------------------------------------

# Operators:
# ==  equal         !=  not equal    !  not
#  >  greater than   <  less than   >=  greater or equal  <= less or equal
# &&  logical AND   ||  logical OR

if ( $name != $user ) then
    echo "Your name isn't your username"
else
    echo "Your name is your username"
endif

# single-line form
if ( $name != $user ) echo "Your name isn't your username"

# NOTE: if $name is empty, tcsh sees the above condition as:
# if ( != $user ) ...
# which is invalid syntax
# The "safe" way to use potentially empty variables in tcsh is:
# if ( "$name" != $user ) ...
# which, when $name is empty, is seen by tcsh as:
# if ( "" != $user ) ...
# which works as expected

# There is also conditional execution
echo "Always executed" || echo "Only executed if the first command fails"
echo "Always executed" && echo "Only executed if the first command does NOT fail"

# To use && and || with if statements, you don't need multiple pairs of
# square brackets:
if ( "$name" == "Steve" && "$age" == 15 ) then
    echo "This will run if $name is Steve AND $age is 15."
endif

if ( "$name" == "Daniya" || "$name" == "Zach" ) then
    echo "This will run if $name is Daniya OR Zach."
endif

# String matching operators ( `=~` and `!~` )
# The ‘==’ ‘!=’ ‘=~’ and ‘!~’ operators compare their arguments as strings;
# all others operate on numbers. The operators ‘=~’ and ‘!~’ are like ‘!=’
# and ‘==’ except that the right hand side is a glob-pattern against which
# the left-hand operand is matched.

if ( $user =~ ni[ck]* ) echo "Greetings Mr. Nicholas."
if ( $user !~ ni[ck]* ) echo "Hey, get out of Nicholas' PC."

# Arithmetic expressions are denoted with the following format:
@ result = 10 + 5
echo $result

# Arithmetic Operators
# +, -, *, /, %
#
# Arithmetic Operators which must be parenthesized
# !, ~, |, &, ^, ~, <<, >>,
# Compare and logical operators
#
# All operators are the same as in C.

# It is non so well documented that numeric expressions require spaces
# in-between; Also, `@` has its own parser, it seems that it works well when
# the expression is parenthesized, otherwise the primary parser seems to be
# active. Parentheses require spaces around, this is documented.

# wrong
@ x = $y+1
@ x = 0644 & 022;      echo $x
@ x = (0644 & 022) +1; echo $x
@ x = (0644 & 022)+ 1; echo $x
@ x = ( ~077 );        echo $x

# correct
@ x = $y + 1
@ x = ( 0644 & 022 ) + 1; echo $x
@ x = ( ~ 077 );          echo $x
@ x = ( ~ 077 | 022 );    echo $x
@ x = ( ! 0 );            echo $x

# C's operators ++ and -- are supported if there is not assignment
@ result ++

# No shell was created to do mathematics;
# Except for the basic operations, use an external command with backslashes.
#
# I suggest the calc as the best option.
# (http://www.isthe.com/chongo/tech/comp/calc/)
#
# The standard Unix's bc as the second option
# (https://www.gnu.org/software/bc/manual/html_mono/bc.html)
#
# The standard Unix's AWK as the third option
# (https://www.gnu.org/software/gawk/manual/gawk.html)

# You can also use `Perl`, `PHP`, `python`, or even several BASICs, but prefer
# the above utilities for faster load-and-run results.

# real example: (that I answer in StackExchange)
# REQ: x := 1001b OR 0110b

# in `tcsh` expression (by using octal)
@ x = ( 011 | 06 ); echo $x

# the same by using `calc` (and using binary as the original req)
set x = `calc '0b1001 | 0b110'`; echo $x

# --- File Inquiry Operators --------------------------------------------------
# NOTE: The built-in `filetest` command does the same thing.

#### Boolean operators
# -r  read access    -w  write access    -x  execute access    -e  existence
# -f  plain file     -d  directory       -l  symbolic link     -p  named pipe
# -S  socket file
# -o  ownership      -z  zero size       -s  non-zero size
# -u  SUID is set    -g  SGID is set     -k  sticky is set
# -b  block device   -c  char device
# -t  file (digit) is an open file descriptor for a terminal device

# If the file `README` exists, display a message
if ( -e README ) echo "I have already README file"

# If the `less` program is installed, use it instead of `more`
if ( -e `where less` ) then
    alias more 'less'
endif

#### Non-boolean operators
# -Z  returns the file size in bytes
# -M  returns the modification time (mtime)    -M: returns mtime string
# -A  returns the last access time (atime)     -A: returns atime string
# -U  returns the owner's user ID              -U: returns the owner's user name
# -G  returns the owner's group ID             -G: returns the owner's group name
# -P  returns the permissions as octal number  -Pmode returns perm. AND mode

# this will display the date as a Unix-time integer: 1498511486
filetest -M README.md

# This will display "Tue Jun 27 00:11:26 2017"
filetest -M: README.md

# --- Basic Commands ----------------------------------------------------------

# Navigate through the filesystem with `chdir` (cd)
cd path # change working directory
cd      # change to the home directory
cd -    # change to the previous directory
cd ..   # go up one directory

# Examples:
cd ~/Downloads # go to my `Downloads` directory

# Use `mkdir` to create new directories.
mkdir newdir
# The `-p` flag causes new intermediate directories to be created as necessary.
mkdir -p ~/.backup/saves

# which & where
# find if csh points to tcsh
ls -lha `which csh`
# find if csh is installed on more than one directory
where csh

# --- Pipe-lines --------------------------------------------------------------
# A pipeline is a sequence of processes chained together by their standard
# streams, so that the output of each process (stdout) feeds directly as input
# (stdin) to the next one. These `pipes` are created with the `|` special
# character and it is one of the most powerful characteristics of Unix.

# example:
ls -l | grep key | less
# "ls -l" produces a process, the output (stdout) of which is piped to the
# input (stdin) of the process for "grep key"; and likewise for the process
# for "less".

# the `ls`, the `grep`, and the `less` are Unix programs and they have their
# own man-page. The `pipe` mechanism is part of the kernel but the syntax
# and the control is the shell's job, the tcsh in our case.

# NOTE: Windows has the `pipe` mechanism too, but it is buggy and I signed it
# for all versions until Windows XP SP3 API32 which was the last one that I
# worked on. Microsoft denied it, but it is a well-known bug since it is a
# common method for inter-process communication. For small I/O it will work well.
# tcsh, along with grep, GCC, and Perl is one of the first Unix programs that
# ported to DOS (with EMX DOS extender) and later to Windows (1998).

# example: this will convert tcsh to PostScript and will show it with Okular
zcat /usr/man/man1/tcsh.1.gz | groff -Tps -man | okular -

# a better version
zcat `locate -b -n 1 '\tcsh.1.gz'` | groff -Tps -man | okular -

# even better
set page = tcsh; set loc = (locate -b -n 1 "\\\\"${page}".1.gz");
 zcat `eval $loc` | groff -Tps -man | okular -

# the same, modified to create man page pdf
set page = tcsh; set loc = (locate -b -n 1 "\\\\"${page}".1.gz");
 zcat `eval $loc` | groff -Tps -man | ps2pdf - ${page}.pdf

# the same, but now shows the ${page}.pdf too
set page = tcsh; set loc = (locate -b -n 1 "\\\\"${page}".1.gz");
 zcat `eval $loc` | groff -Tps -man | ps2pdf - ${page}.pdf && okular tcsh.pdf

# NOTE: `okular` is the default application of the KDE environment and it shows
# postcript and pdf files. You can replace it with your lovely PDF viewer.
# `zcat`, `locate`, `groff`, are common programs in all Unixes. The `ps2pdf`
# program is part of the `ghostscript` package that is widely used.

# --- Control Flow ------------------------------------------------------------

#### IF-THEN-ELSE-ENDIF
# Syntax:
# if ( expr ) then
#    ...
# [else if ( expr2 ) then
#    ...]
# [else
#    ...]
# endif
#
# If the specified `expr` is true then the commands to the first else are
# executed; otherwise if `expr2` is true then the commands to the second else
# are executed, etc.
# Any number of else-if pairs are possible; only one endif is needed.
#
# Single-line form:
#
# if ( expr ) command
#
# If `expr` evaluates to true, then the command is executed.
# `command` must be a simple command, not an alias, a pipeline, a command list
#, or a parenthesized command list. With a few words, avoid using it.
#
# BUG: Input/output redirection occurs even if expr is false and the command
# is thus not executed.
#

# check if we are in a non-interactive shell and quit if true
if ( $?USER == 0 || $?prompt == 0 ) exit

# check if we are a login shell
if ( $?loginsh ) then
    # check if you are on linux console (not X's terminal)
    if ( $tty =~ tty* ) then
        # enable keypad application keys (man console_codes)
        echo '\033='
    endif
endif

#### SWITCH-ENDSW
# Syntax:
# switch ( expr )
# case pattern:
#     ...
#     [breaksw]
# [default:
#     ...]
# endsw
#
# tcsh uses a case statement that works similarly to switch in C.
# Each case label is successively matched, against the specified string which
# is first command and filename expanded. The file metacharacters `*`, `?`
# and `[...]` may be used in the case labels. If none of the labels match the
# execution begins after the default label if it's defined.
# The command `breaksw` causes execution to continue after the endsw. Otherwise,
# control may fall through case labels and default labels as in C.

switch ( $var )
case *.[1-9]:
case *.[1-9].gz:
    echo "$var is a man-page."
    breaksw
case *gz:
    echo "$var is gzipped"
    breaksw
default:
    file $var
endsw

#### FOREACH-END
# Syntax:
# foreach name ( wordlist )
#    ...
#   [break | continue]
# end
#
# Successively sets the variable `name` to each member of `wordlist` and
# executes the sequence of commands between this command and the matching
# `end` keyword. The `continue` keyword jumps to the next element back to
# top, and the `break` keyword terminates the loop.
#
# BUG: `foreach` doesn't ignore here documents when looking for its end.

# example: counting 1 to 10
foreach i ( `seq 1 10` )
    echo $i
end

# example: type all files in the list
foreach f ( a.txt b.txt c.txt )
    cat $f
end

# example: convert wma to ogg
foreach f ( *.wma )
    ffmpeg -i "$f" "$f:r".ogg
end

#### WHILE-END
# while ( expr )
#     ...
#     [break | continue]
# end
#
# Executes the commands between the `while` and the matching `end` while `expr`
# evaluates non-zero. `break` and `continue` may be used to terminate or
# continue the loop prematurely.

# count from 1 to 10
set num = 1
while ( $num <= 10 )
    echo $num
    @ num ++
end

# print all directories of CWD
set lst = ( * )
while ( $#lst )
    if ( -d $lst[1] ) echo $lst[1] is directory
    shift lst
end

# separate command-line arguments to options or parameters
set options
set params
set lst = ( $* )
while ( $#lst )
    if ( "$lst[1]" =~ '-*' ) then
        set options = ( $options $lst[1] )
    else
        set params = ( $params $lst[1] )
    endif
    shift lst
end
echo 'options =' $options
echo 'parameters =' $params

#### REPEAT
# Syntax: repeat count command
#
# The specified command, which is subject to the same restrictions as the
# command in the one line `if` statement above, is executed count times.
# I/O redirections occur exactly once, even if `count` is 0.
#
# TIP: in most cases prefer `while`

repeat 3 echo "ding dong"

# --- Functions ---------------------------------------------------------------
# tcsh has no functions but its expression syntax is advanced enough to use
# `alias` as functions. Another method is recursion

# Alias argument selectors; the ability to define an alias to take arguments
# supplied to it and apply them to the commands that it refers to.
# Tcsh is the only shell that provides this feature.
#
# \!#   argument selector for all arguments, including the alias/command
#       itself; arguments need not be supplied.
# \!*   argument selector for all arguments, excluding the alias/command;
#       arguments need not be supplied.
# \!$   argument selector for the last argument; argument need not be supplied,
#       but if none is supplied, the alias name is considered to be the
#       last argument.
# \!^   argument selector for first argument; argument MUST be supplied.
# \!:n  argument selector for the nth argument; argument MUST be supplied;
#       n=0 refers to the alias/command name.
# \!:m-n   argument selector for the arguments from the mth to the nth;
#       arguments MUST be supplied.
# \!:n-$   argument selector for the arguments from the nth to the last;
#       at least argument n MUST be supplied.

# Alias the cd command so that when you change directories, the contents
# are immediately displayed.
alias cd 'cd \!* && ls'

# --- Recursion method --- begin ---
#!/bin/tcsh -f
set todo = option1
if ( $#argv > 0 ) then
    set todo = $argv[1]
endif

switch ( $todo )
case option1:
#    ...
    $0 results
    breaksw
case option2:
#    ...
    $0 results
    breaksw
case results:
    echo "print the results here"
#    ...
    breaksw
default:
    echo "Unknown option: $todo"
#    exit 0
endsw
# --- Recursion method --- end ---

# --- examples ----------------------------------------------------------------

# this script prints available power-states if no argument is set;
# otherwise it sets the state of the $argv[1]
# --- power-state script --- begin --------------------------------------------
#!/bin/tcsh -f
# get parameter ("help" for none)
set todo = help
if ( $#argv > 0 ) then
    set todo = $argv[1]
endif
# available options
set opts = `cat /sys/power/state`
# is known?
foreach o ( $opts )
    if ( $todo == $o ) then
        # found; execute it
        echo -n $todo > /sys/power/state
        break
    endif
end
# print help and exit
echo "usage: $0 [option]"
echo "available options on kernel: $opts"
# --- power-state script --- end ----------------------------------------------

# Guess the secret number game
# --- secretnum.csh --- begin -------------------------------------------------
#!/bin/tcsh -f
set secret=`shuf -i1-100 -n1`
echo "I have a secret number from 1 up to 100"
while ( 1 )
    echo -n "Guess: "
    set guess = $<
    if ( $secret == $guess ) then
        echo "You found it"
        exit 1
    else
        if ( $secret > $guess ) then
            echo "its greater"
        else if ( $secret < $guess ) then
                echo "its lesser"
            endif
        endif
    endif
end
# --- secretnum.csh --- end ---------------------------------------------------

# -----------------------------------------------------------------------------
# Appendices

#### About [T]CSH:
# * CSH is notorious for its bugs;
# * It is also famous for its advanced interactive mode.
# * TCSH is famous for having the most advanced completion subsystem.
# * TCSH is famous for having the most advanced aliases subsystem; aliases
#   can take parameters and often be used as functions!
# * TCSH is well known and preferred by people (me too) because of better
#   syntax. All shells are using Thomson's syntax with the exception of
#   [t]csh, fish, and plan9's shells (rc, ex).
# * It is smaller and consumes far less memory than bash, zsh, and even mksh!
#   (memusage reports)
# * TCSH still has bugs; fewer, but it does; if you write readable clean code
#   you'll find none; well almost none... This has to do with the implementation
#   of csh; that doesn't mean the other shells have a good implementation.
# * no well-known shell is capable of regular programming; if your script
#   is getting big, use a programming language, like Python, PHP, or Perl (good
#   scripting languages).
#
# Advice:
# 1. Do not use redirection in single-line IFs (it is well documented bug)
#    In most cases avoid using single-line IFs.
# 2. Do not mess up with other shells' code, c-shell is not compatible with
#    other shells and has different abilities and priorities.
# 3. Use spaces as you'll use them to write readable code in any language.
#    A bug of csh was `set x=1` and `set x = 1` worked, but `set x =1` did not!
# 4. It is well documented that numeric expressions require spaces in between;
#    also parenthesize all bit-wise and unary operators.
# 5. Do not write a huge weird expression with several quotes, backslashes, etc
#    It is bad practice for generic programming, it is dangerous in any shell.
# 6. Help tcsh, report the bug here <https://bugs.gw.com/>
# 7. Read the man page, `tcsh` has a huge number of options and variables.
#
#    I suggest the following options enabled by default
#    --------------------------------------------------
# Even in non-interactive shells
#    set echo_style=both
#    set backslash_quote
#    set parseoctal
#    unset noclobber
#
# Whatever...
#    set inputmode=insert
#    set autolist
#    set listjobs
#    set padhour
#    set color
#    set colorcat
#    set nobeep
#    set cdtohome
#
#    set histdup
#    set histlit
#    set nohistclop
#
#    unset compat_expr
#    unset noglob
#    unset autologout
#    unset time
#    unset tperiod
#
# NOTE: If the `backslash_quote` is set, it may create compatibility issues
# with other tcsh scripts that were written without it.
#
# NOTE: The same for `parseoctal`, but it is better to fix the problematic
# scripts.
#
# NOTE: **for beginners only**
# This enables automatic rescanning of `path` directories if needed. (like bash)
#    set autorehash

#### common aliases
#    alias hist  'history 20'
#    alias ll    'ls --color -lha'
#    alias today "date '+%d%h%y'
#    alias ff    'find . -name '

#### a nice prompt
#    set prompt = "%B%{\033[35m%}%t %{\033[32m%}%n@%m%b %C4 %# "
```