IC设计中Linux shell的选择和使用(tcsh语法、bash语法 、zsh语法)

提示:用户画像为linux用户ICer、需要使用tcshbash进行编程来完成日常的工作的各个读者,旨在帮助用户学以致用。


一、前言:IC设计中的Linux shell

提示:下文是ic设计、或使用到linux多种shell下的工作者的一些知识。

IC design (integrated circuit design): 集成电路设计,可以抽象化理解成将预设的功能设计进行物理实现的过程。IC design百度词条

在ic设计的工作中,我们会用到很多的EDA (Electronic design automation)工具,帮助完成设计和实现过程,还有文本编辑的工具等,这些工具都是在linux系统环境下工作的。起初那些EDA工具是在Unix上运行的,但是后期Linux开源的优势占据了上风,有着大量的开源的工具可供EDA厂商使用,当然Linux系统本身有着很强的稳定性等,逐渐的EDA工具也就转移到了Linux系统上了。
Linux系统是依靠shell进行交互的,不同shell往往有着不同的语法规则、不同的bulit-in命令和其用法等。现如今最常见的Linux shell包括tcsh(从csh发展来的)、bash(从shell发展来的)、ksh(兼容csh和sh的优势)、dash(从shell发展而来,和bash很接近)、zsh(集成tcsh和bash的各自的优势)等。
ICer工作者留心的话,可能就会注意到用前辈们大都使用的是tcsh(或者csh)和bash(年代久远的大厂可能还有一部分sh脚本)。使用过tcsh和bash的shell的用户都知道,bash脚本是可以定义函数的,相对于tcsh这是一个很大的优势,还有bash是可以支持复杂的数据结构的,这一点也是tcsh shell不具备的(你可能看到多处、或者百度AI等告知,bash不支持hash,但实际上bash是支持的)。

例子:使用bash shell定义复杂的数据结构
## shell is bash
[weifexie@atletx7-neu004 ~/shell_tra]$ echo $0
bash

## define hash 
[weifexie@atletx7-neu004 ~/shell_tra]$ xie[wei]='feng'
[weifexie@atletx7-neu004 ~/shell_tra]$ echo ${xie[wei]}
feng

## define list
[weifexie@atletx7-neu004 ~/shell_tra]$ xiexie=(1 2 3 4)
[weifexie@atletx7-neu004 ~/shell_tra]$ echo ${xiexie[0]}
1

可能是tcsh脚本中不能定义函数,ICer工作者可能会看到大量的.csh脚本在不断的source,一个工作需要调用大量的.csh脚本。如果换成bash脚本就不需要这样子做了,直接在bash脚本内部直接定义函数,将脚本集成到一起。
如此看来,bash比tcsh在运用上更具有优势才对,但为什么tcsh却是ICer使用最多的shell呢?为什么不将bash换成默认的shell呢?

四下询问、查看资料、同行答疑、文本记载、野史等,可能的原因有:

  1. tcsh在bash前定版发行,在bash没有发行前,ICer在csh上工作,累计了大量的代码,csh和bash不兼容,代码的重新编写的工作量很大,同时IC行业是一个需要迭代升级的行业,代码往往会在原有的基础上进行升级,先入为主了。有经历的人说到:有段时间ICer在solaris 7和solaris8上做IC designs,csh是默认的shell,同时还不支持bash,如果想支持bash需要另外安装GNUBash。
  2. 从linux的发展史可以了解到,ICer起初是在unix上完成工作的,很长的一段时间,sh是用来编程,csh用来做交互式设计,在那时,csh相对于sh来说有着很多的优势,有着更多的功能,对用户更友好,可能从那时开始ICer想要完成工作,学习csh要比sh更为有用。再后来bash定版发行,取代了sh成为了现在诸多Linux的默认shell,但留心你会发现,ICer的工作shell可能依然还是tcsh。

Tcl、Perl、Python等脚本语言相比于tcsh、bash等,可以帮助ICer完成更为复杂的流程和过程,是ICer工作者继掌握tcsh和bash后必须要知晓的语言了,Tcl、Perl、Python后续会介绍各自的用法和案例,旨在帮助读者可以使用该知识实现设计工作的自动化。

提示:以下是本篇文章正文内容,下面案例可供参考

二、tcsh语法、bash语法 、zsh语法

tcsh语法和bash语法不兼容,这里提醒一下,二者作为shell时,built-in命令很多都是相同的,用法也可能是相同的,因为这两者再最初的阶段都是从sh处继承了很多底层的内容,但是作为编程语言时,二者就有着很大的差别了。zsh语言可以看作是tcsh和 bash的集成。以下介绍tcsh、bash、zsh在作为编程语言时的用法。
在此处笔者给出两个相同的脚本,只是一个是tcsh语言书写的,另一个是bash语言书写的。读者可以对照就可以知道二者之间的区别了。在脚本之后,该文总结tcsh的bash的语言特点。

案例

tcsh语言编写的脚本 

读者可以不用在意脚本具体实现了什么功能,只需掌握语法规则即可。

# !/usr/bin/tcsh
# this used to atgp part and it would be better if used ~/shell_tra/atpgsim_auto.csh
# usage: $0 regr_fl which_mode(s)
#
if ($#argv < 2 || $1 =~ *"help"*) then
  echo "pls chk usage and follow the format below\
        $0 regr_fl which_mode\
            eg: ~/shell_tra/run_atpg.csh usb4_sc0_t_nldrel/ stac \
                results: regr_fl is: usb4_sc0_t_nldrel/; mode(s) you chosen: (wc: 3) scm_STAC0 scm_STAC1 scm_STAC2"
  exit 1
else
  # get now_path where script is running
  set now_path = `pwd`    
  echo -n "\nregr_fl is: $1; mode(s) you chosen: "
  if (! -d $1) then
    echo "pls chk $1, and its validity"
    exit 1
  else
    set path_regr_fl = $now_path/$1
    shift
    set session_lists = ()
    foreach arg($argv)
      if(-d $path_regr_fl/atpg/session/) then
        set findfd = `find $path_regr_fl/atpg/session/ -iname "*$arg*" -type d`
        # get findfd name
        foreach findfd_name($findfd)
          set findfd_name = `basename $findfd_name`
          set session_lists = ($session_lists $findfd_name)
        end
      else 
        echo  "$path_regr_fl/atpg/session/ is non-exist, "
      endif
    end # foreach arg
    echo -n "(wc: $#session_lists) $session_lists" # cont. mode(s) you chosen: (wc: $#session_lists) $session_lists
  endif
endif
echo
# main function start
# foreach session_lists
foreach sess($session_lists)
  echo "//performing sess ($sess) mode//"
  # cd $1/atpg/session/$sess
  cd $path_regr_fl/atpg/session
  # ls -d *$sess*
  set sess_modes = `ls -d *$sess* | awk '{print $NF}'`
  foreach mode($sess_modes)
    cd $mode
    # run atpg csh
    gnome-terminal --tab --title "$mode" -- csh -c "echo `pwd`;./run" &
    wait
    cd -
  end
cd $path_regr_fl/atpg/session
end # foreach sess
exit 0 # end successfully
改用bash语言编写上述code
#!/usr/bin/bash
# this bash script is transformed from ~/shell_tra/run_atpg.csh
#
if [ $# -lt 2 ];then
  # cat EOF inf
  echo "psl chk usage and follow the format below
        $0 regr_fl which_mode
            eg: ~/shell_tra/atpg_run.bash usb4_sc0_t_nldrel stac
                results: regr_fl is: usb4_sc0_t_nldrel; mode(s) you chosen: (wc: 3) scm_STAC0 scm_STAC1 scm_STAC2"
  exit 1
else
  # get now_path where script is running
  now_path=`pwd`
  echo -n "rer_fl is: $1; mode(s) you chosen: "
  if [ ! -d $1 ]; then
    echo "pls chk $1, and its vailidity"
    exit 1
  else
    path_regr_fl="$now_path/$1"
    #echo path_regr_fl="$now_path/$1"
    shift
    session_lists=()
    for arg in $@; do
    #echo "\$@ = $@, arg = $arg"
      if [ -d $path_regr_fl/atpg/session/ ]; then
        findfd=`find $path_regr_fl/atpg/session/ -iname "*$arg*" -type d`
        # echo "findfd=$findfd"
        # get findfd name
        for findfd_name in ${findfd[@]}; do
          #echo "findfd_name=$findfd_name"
          findfd_name=$(basename $findfd_name)
          session_lists=("${session_lists[@]}" "$findfd_name")
          #echo "session_lists=${session_lists[@]}"
        done
      else
        echo "$path_regr_fl/atpg/session is non-exist"
      fi
    done
    echo -n "(wc: ${#session_lists[@]}) ${session_lists[@]}" #
  fi
fi
echo
# main function start
# for in session_lists
for sess in ${session_lists[@]}; do
  echo "//performing sess ($sess) mode//"
  # cddir $1/atpg/$sess
  cd $path_regr_fl/atpg/session
  # ls -d *$sess*
  sess_modes=`ls -d *$sess* | awk '{print $NF}'`
  for mode in ${sess_modes[@]}; do
    cd $mode
    # run atpg csh
    gnome-terminal --tab --title "$mode" -- csh -c "./run; exec tcsh" &
    sleep 5s
    cd -
  done
cd $path_regr_fl/atpg/session/
done
exit 0

1、注释和shebang

# tcsh
# 注释使用#号
# shebang -- #!/usr/bin/tcsh
# (注意:第一行shebang可以省略不写,那么,脚本使用默认shebang,即当前命令行$SHELL)


# bash
# 注释符使用 #
# shebang -- #!/usr/bin/bash
# 省略不写的情况同上

2、变量定义和引用

# tcsh
# 定义字符变量
set now_path = `pwd` 
# 定义列表
set session_lists = (1 2 3 4)
# 注意:tcsh定义变量时,变量名、等号、等号右边的内容之间都是有空格的
# 列表元素的引用
# session_lists 第二个元素:$session_lists[2]


# bash
# 定义字符变量
now_path = `pwd` 
# 定义列表
session_lists=(1 2 3 4)
# 注意:bash定义变量时,变量名、等号、等号右边的内容之间都是没有空格的

# 列表元素的引用
# session_lists 第二个元素:${session_lists[1]}
# 注意:bash中列表的索引从0开始,tcsh是从1开始的

3、条件判断

# tcsh
# if 条件判断
if ($#argv < 2 || $1 =~ *"help"*) then
  echo
else
  echo
endif
# if 后是小括号,小括号和括号内的内容之间可以有、也可以没有空格


# bash
if [ $# -lt 2 ];then
  echo
else
  echo
fi
# if 和之后的中阔号需要有空格,中括号和括号内的内容之间也需要有空格
# if的条件不满足时的分支else语言,当else存在时,else分支就不能没有语句,否则会出错,如
if [ ]; then
echo
else
fi
# 上else分支不能是空语言,这样会出错

4、结构控制

# tcsh
foreach sess($session_lists)
  echo
end


# bash
for sess in ${session_lists[@]}; do
  echo
done

5、函数

# tcsh
# 不支持函数功能


# bash,
function sum(){
  return $(($1+$2))
}
sum 3 4
echo "sum = $?"

6、参数变量

# tcsh
# $#argv -- 表示参数个数
# $argv -- 表示参数列表
# $argv[1] --表示第一个参数,从1开始,同$1
# $0 -- 脚本名称


# bash
# $# -- 表示参数个数
# $@ -- 表示参数列表
# $1 -- 表示第一个参数
# $0 -- 脚本名称

7、引用dirname、basename

# tcsh
# set findfd_name = `basename $findfd_name`
# 使用``反引号来引用basename、dirname得到的结果


# bash
# findfd_name=$(basename $findfd_name)
# 使用$符号引用

8、附加文本tcsh语法word文档

以上是tcsh和bash基于上脚本所表现出来的在语法上的不同,上述基础语法也许就可以帮读者完成一些基本的进程了,当然,掌握tcsh、bash、和zsh语法于胸,笔者该文是远远不够的,故附上tcsh的语法文档,旨在帮助大家全面掌握tcsh,同时在该本第三部分附上了多个shell的文档,供读者自研。

zsh用法结合了tcsh和bash的二者的优势,该文不再赘述,第三部分可以找到zsh的语法。


三、相关资料

本文参考文献和同行笔墨
IC设计中Linux shell的选择和使用(bash、tcsh、zsh)

附上tcsh语言word文档

四、总结

该文介绍了在ICer设计中常用的tcsh,另一种linux默认的bash shell。给出了一个案例,使用tcsh和bash书写,由此案例总结了tcsh和bash的语法区别,附上tcsh、bash、和zsh的多份学习材料,旨在帮助读者全面的学习。


念念不忘,必有回响

END

  • 23
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weifexie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值