Translate between bash and tcsh commands

Table of Contents

  1. Bash/Tcsh Comparison Table
  2. How It Was Generated
  3. Makefile
  4. Generate HTML (genhtml.py)
  5. Bash Commands Script (compare.sh)
  6. Tcsh Commands Script (compare.csh)

Bash/Tcsh Comparison Table

The table below shows bash commands and their equivalents in tcsh along with the tools that I wrote to create it.

I put it together because I sometimes have to switch between shells and needed a handy reference. It was built up over time by as I came across tidbits that I wanted to remember.

In some cases there are different ways of doing the same thing so I simply chose my preferred approach (such as [[]] expressions rather than [] in the if statements).

I hope that you find it useful.

ID Operation bash tcsh
1 alias alias foo=bar alias foo bar
2 array: declaration ARRAY=("a" "b" "c") set ARRAY = ("a" "b" "c")
3 array: first item echo first item [0] = ${ARRAY[0]} echo "first item [1] = $ARRAY[1]"
4 array: iterate by index for i in ${!ARRAY[@]}; do
    printf "%d %s\n" $i ${ARRAY[i]}
done
foreach i ( `seq $#ARRAY` )
    echo $i $ARRAY[$i] |\
        awk '{printf("%d %s\n",$1,$2);}'
end
5 array: iterate by item for item in ${ARRAY[@]} ; do
    echo item = $item
done
foreach item ( $ARRAY )
    echo item = $item
end
6 array: iterate by item, single line A=("a" "b" "c")
for x in ${A[@]} ; do echo $x; done
N/A
7 array: size echo ${#ARRAY[@]} items echo $#ARRAY items
8 command substitution # style 1 – can't be nested
x=`ls –1`
# style 2 – can be nested
me=$(dirname –– $(readlink –f .))
echo $me
# style 1 – can't be nested
set x = `ls –1`
# style 2 – not supported
set r = `readlink –f .`
set me = `dirname $r`
echo $me
9 exit the shell exit
exit 1
exit
exit 1
10 formatted printing # Native support.
printf "%05d %s\n" 42 "Deep Thought"
# No native support,
# emulate with awk.
# Embedded spaces are a pain.
echo 42 "Deep Thought" |\
  awk '{printf("%05d %s %s\n",$1,$2,$3);'}
11 function function echo–cmds {
    echo "CMD : "$*
    # Echo the commands.
    local args="$@" # local var
    $args | sed –e 's/^/      /'
}
echo–cmds pwd
echo–cmds ls –l
N/A
Can be emulated using
external scripts
12 get shell name echo $SHELL echo $shell
13 get shell version bash ––version
echo $BASH_VERSION
tcsh ––version
echo $version
14 if/then/else: numeric i=2
if (( i>2 )) ; then
    echo i greater than 2
elif (( i<2 )) ; then
    echo i less than 2
else
    echo i is two
fi
set i=2
if ($i>2) then
    echo i greater than 2
else if ($i<2) then
    echo i less than 2
else
    echo i is two
endif
15 if/then/else: string s="foo bar"
if [[ "$s" == "foo bar" ]] ; then
    echo "foo"
else
    echo "spam"
fi
set s="foo bar"
if ("$s" == "foo bar") then
    echo "foo"
else
    echo "spam"
endif
16 include a file source include–file
.  include–file
source include–file
17 IO: redirect stderr ls 2> /tmp/$$ ( ls > /dev/tty ) >& /tmp/$$
18 IO: redirect stdout ls > /tmp/$$ ls > /tmp/$$
19 IO: redirect stdout and stderr ls > /tmp/$$ 2>&1 # older
ls &> /tmp/$$     # newer
ls >& /tmp/$$
20 job: move into the background job
<Ctrl–Z>
bg
job
<Ctrl–Z>
bg
21 job: move into the foreground fg
fg %1
fg
fg %1
22 job: start in the background job & job &
23 job: status job
echo status = $?
job
echo status = $?
24 local variable function fct {
    local var='local'
}
# functions not supported
25 prompt set PS1='\u >'  # user name
set PS1='\h >'  # host
set PS1='\! >'  # command num
#set PS1=N/A >' # last 3 dir parts
set PS1='\W >'  # last dir part
set PS1='\w >'  # curr dir full
set PS1='\v >'  # shell version
set PS1='\u@\h \W (\!) >'
set prompt='%n >'  # user name
set prompt='%j >'  # host
set prompt='! >'   # command num
set prompt='%c3 >' # last 3 dir parts
set prompt='%c >'  # last dir part
set prompt='%~ >'  # curr dir full
#set prompt=N/A    # shell version
set prompt='%n@%j %c (!) >'
26 range iteration for i in `seq 1000` ; do
    echo $i
done

for i in $( seq 1000 ) ; do
    echo $i
done

# fastest
for i in {1..1000} ; do
    echo $i
done

foreach i ( `seq 1000` )
  echo $i
end
27 read values from the console read –p "login? " login
read –p "passwd? " –s passwd
echo
echo "login: $login"
echo "passwd: $passwd"
echo –n "login? "
set login = $<

echo –n "passwd? "
stty –echo
set passwd = $<
stty echo

echo
echo "login: $login"
echo "passwd: $passwd"

28 regex extension check FILES=('f1.tar.bz2' 'f2.tar.gz' 'f3.zip')
for FILE in ${FILES[@]} ; do
    if [[ "$FILE" =~ .tar.bz2$ ]] ; then
        echo "tar.bz2: $FILE"
    elif [[ "$FILE" =~ .tar.gz$ ]] ; then
        echo "tar.gz: $FILE"
    elif [[ "$FILE" =~ .zip$ ]] ; then
        echo "zip: $FILE"
    else
        echo "unk: $FILE"
    fi
done
set FILES=('f1.tar.bz2' 'f2.tar.gz' 'f3.zip')
foreach FILE ( $FILES )
    echo $FILE | grep '.tar.bz2$' >&/dev/null
    if ( $? == 0 ) then
        echo "tar.bz2: $FILE"
        continue
    endif

    echo $FILE | grep '.tar.gz$' >&/dev/null
    if ( $? == 0 ) then
        echo "tar.gz: $FILE"
        continue
    endif

    echo $FILE | grep '.zip$' >&/dev/null
    if ( $? == 0 ) then
        echo "zip: $FILE"
        continue
    endif

    echo "unk: $FILE"
end

29 set path variable export PATH="$PATH:/tmp" set path = ( $path /tmp )
30 set resource limits ulimit limit
31 setenv/export export FOOBAR="spam" setenv FOOBAR "spam"
32 switch statement arg="foo"
case "$arg" in
    "foo")
        echo "do foo"
        ;;
    "bar")
        echo "do bar"
        ;;
    "spam")
        echo "do spam"
        ;;
    *)
        echo "do be do be do"
        ;;
esac
set arg="foo"
switch ("$arg")
    case "foo":
        echo "do foo"
        breaksw
    case "bar":
        echo "do bar"
        breaksw
    case "spam":
        echo "do spam"
        breaksw
    default:
        echo "do be do be do"
        breaksw
endsw
33 variable: auto decrement i=0
(( i–– ))
echo auto deccrement = $i
set i=0
@ i––
echo auto decrement = $i
34 variable: auto increment i=0
(( i++ ))
echo auto increment = $i
set i=0
@ i++
echo auto increment = $i
35 variable: automatically exit on error /bin/bash –e # invocation
set –e # inside the shell
/bin/tcsh –e # invocation only
36 variable: create array ARRAY=("item1" "item2" "item2") set ARRAY=("item1" "item2" "item2")
37 variable: create scalar i=0
s="foo bar spam"
set i=0
set="foo bar spam"
38 variable: debug tracing set –x # on
pwd
set +x # off
pwd
set verbose # on
pwd
unset verbose # off
pwd
39 variable: destroy or unset ARRAY=("item1" "item2" "item2")
unset ARRAY
set ARRAY=("item1" "item2" "item2")
unset ARRAY
40 variable: dump state set set
41 variable: dynamic # Native support, can also use eval.
a="some value"
b=a
echo $b = ${!b}
bv="${!b}"
echo bv = $bv
# Not native, need to use eval.
set a="some value"
set b="a"
eval "echo $b = "'$'${b}
set bv=`eval echo '$'$b`
echo bv = $bv
42 variable: print environment variables env
printenv
env
printenv
43 variable: substitution foo='bar'
echo ${foo/bar/baz/}
set foo = 'bar'
echo $foo:s/bar/baz/
44 variable: turn on unset variable checking set –u N/A

How It Was Generated

The table was generated automatically from two test scripts: a bash script (compare.sh) and a tcsh script (compare.csh). Each one ran all of the commands in the previous table.

I used another script (genhtml.py) to parse them and generate this table automatically under the control of a Makefile. See the comments in the python script for more
details about the record format. Here is how I ran it.

I then manually entered the HTML table data onto this page.

Makefile

This is the make file that I used.

Generate HTML (genhtml.py)

This is the python script file that generated the HTML table data.

Bash Commands Script (compare.sh)

This is the script that tested the bash commands.

Tcsh Commands Script (compare.csh)

This is the script that tested the tcsh commands.

18 thoughts on “Translate between bash and tcsh commands”

  1. Nice table – useful for when I have to VNC to check out a problem and they’re using csh/tcsh. Only thing I can see missing is export(bash) / setenv(csh) as a ‘set’ in csh will not export a new variable. (So your path example is OK as it’s a pre-existing environment/exported variable).

  2. Best blog…..I spend time many times searching google when working b/w these two terminals….this is all at one place..sorted down very well.
    Thanks bro….

    1. Bash does have access the command line arguments but it doesn’t name them argv.

      Are you suggesting that an entry is added that shows this in bash:

      and something like this in tcsh:

  3. What about adding bash “parameter expansion” / tcsh “variable substitution”? Eg in bash you write “${foo/bar/baz/}” where in tcsh you would write “$foo:s/bar/baz/”

    Thanks for a great resource.

  4. Could you please upload your tcsh and bash script as well as the python script you used to generate the tables so that everyone can easily create their own version of this table with their frequently used commands?

  5. There are a few tcsh things I don’t know how to do in bash that have kept me from switching, e.g.:

    Any of these you could add?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.