2017-07-16 23:16:01 +03:00
|
|
|
|
---
|
|
|
|
|
language: tcsh
|
|
|
|
|
filename: LearnTCSH.csh
|
|
|
|
|
contributors:
|
2017-08-25 11:30:10 +03:00
|
|
|
|
- ["Nicholas Christopoulos", "https://github.com/nereusx"]
|
|
|
|
|
|
2017-07-16 23:16:01 +03:00
|
|
|
|
---
|
|
|
|
|
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
|
|
|
|
|
# First line of the script is shebang which tells the system how to execute the
|
|
|
|
|
# script: http://en.wikipedia.org/wiki/Shebang_(Unix)
|
|
|
|
|
# TCSH emulates the shebang on systems which 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 prevents expanding special characters too, but some
|
|
|
|
|
# characters like `!' and backslash have higher priority
|
|
|
|
|
# `$' (variable value) will not expands
|
|
|
|
|
echo '$1 tip'
|
|
|
|
|
# `!' (history) will expands
|
|
|
|
|
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 first command fails"
|
|
|
|
|
echo "Always executed" && echo "Only executed if first command does NOT fail"
|
|
|
|
|
|
|
|
|
|
# Parenthesised commands are always executed in a subshell,
|
|
|
|
|
|
|
|
|
|
# example: create 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 leaving 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 variable from the rest when its 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 indexed element; 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 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 this is useful to 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 filenane 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
|
|
|
|
|
# so 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 first command fails"
|
|
|
|
|
echo "Always executed" && echo "Only executed if 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 parenthesised
|
|
|
|
|
# !, ~, |, &, ^, ~, <<, >>,
|
|
|
|
|
# Compare and logical operators
|
|
|
|
|
#
|
|
|
|
|
# All operators are 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 work well when the
|
|
|
|
|
# expression is parenthesised otherwise the primary parser seems it is active.
|
|
|
|
|
# Parenthesis 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 ++
|
|
|
|
|
|
|
|
|
|
# None shell 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 second option
|
|
|
|
|
# (https://www.gnu.org/software/bc/manual/html_mono/bc.html)
|
|
|
|
|
#
|
|
|
|
|
# The standard Unix's AWK as third option
|
|
|
|
|
# (https://www.gnu.org/software/gawk/manual/gawk.html)
|
|
|
|
|
|
|
|
|
|
# You can also use `perl', `php' 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 builtin `filetest' command do 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, displays a message
|
|
|
|
|
if ( -e README ) echo "I have already README file"
|
|
|
|
|
|
|
|
|
|
# if the `less' program is installed, use this 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 lass access time (atime) -A: returns atime string
|
|
|
|
|
# -U returns the owners user ID -U: returns the owners user-name
|
|
|
|
|
# -G returns the group ID -G: returns the group-name
|
|
|
|
|
# -P returns the permissions as octal number -Pmode returns perm. AND mode
|
|
|
|
|
|
|
|
|
|
# this will display the date as 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 though file system with `chdir' (cd)
|
|
|
|
|
cd path # change working directory
|
|
|
|
|
cd # change to home directory
|
|
|
|
|
cd - # change to 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. This `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 programs of Unix and they have their
|
|
|
|
|
# own man-page. The `pipe' mechanism is part of the kernel but the syntax
|
|
|
|
|
# and the control is job of the shell, the tcsh in our case.
|
|
|
|
|
|
|
|
|
|
# NOTE: `pipe' mechanism has Windows too, but it is buggy and I sign it for all
|
|
|
|
|
# versions until Windows XP SP3 API32 which was the last one that I worked on.
|
|
|
|
|
# Microsoft still denied it but is 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 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 Unices. `ps2pdf' program
|
|
|
|
|
# is part of `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 true, then command is executed.
|
|
|
|
|
# `command' must be a simple command, not an alias, a pipeline, a command list
|
|
|
|
|
# or a parenthesized command list. With few words, avoid to use it.
|
|
|
|
|
#
|
|
|
|
|
# BUG: Input/output redirection occurs even if expr is false and command is
|
|
|
|
|
# thus not executed.
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
# check if we are in 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 its 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 jump 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
|
2017-08-23 11:14:39 +03:00
|
|
|
|
echo 'parameters =' $params
|
2017-07-16 23:16:01 +03:00
|
|
|
|
|
|
|
|
|
#### 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 set 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 about its bugs;
|
|
|
|
|
# * It was also famous about its advanced interactive mode.
|
|
|
|
|
# * TCSH is famous that have the most advanced completition subsystem.
|
|
|
|
|
# * TCSH is famous that have the most advanced aliases subsystem; aliases
|
|
|
|
|
# can take parameters and often used as functions!
|
|
|
|
|
# * TCSH is well known that preferred by people (me too) because of better
|
|
|
|
|
# syntax. All shells are using Thomson's syntax with exception of [t]csh,
|
|
|
|
|
# fish and plan9's shells (rc, ex).
|
|
|
|
|
# * It is smaller and consume far less memory than bash, zsh even mksh!
|
|
|
|
|
# (memusage reports)
|
|
|
|
|
# * TCSH still has bugs; less but have; if you write readable clean code you'll
|
|
|
|
|
# find none; well almost none... This has to do with the implementation of
|
|
|
|
|
# csh; that no means the other shells has good implementation.
|
|
|
|
|
# * no one well known shell is capable for regular programming; if your script
|
|
|
|
|
# getting big, use a programming language, or at least PHP or Perl (good
|
|
|
|
|
# script languages).
|
|
|
|
|
#
|
|
|
|
|
# Advises:
|
|
|
|
|
# 1. Do not use redirection in single-line if (it is well documented bug)
|
|
|
|
|
# In most cases avoid to use 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' worked, `set x = 1' worked, `set x =1' did not!
|
|
|
|
|
# 4. It is well documented that numeric expressions require spaces in-between;
|
|
|
|
|
# also parenthesise 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 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 which was written without it.
|
|
|
|
|
#
|
|
|
|
|
# NOTE: The same for `parseoctal', but it is better to fix the problematic
|
|
|
|
|
# scripts.
|
|
|
|
|
#
|
|
|
|
|
# NOTE: **for beginners only**
|
|
|
|
|
# This enable automatically rescan `path' directories if need to. (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 %# "
|
|
|
|
|
```
|