一、shell 编程概述
在 Linux 下有一门脚本语言叫做:Shell 脚本,这个脚本语言可以帮助我们简化很多工作,例如编写自定义命令等,所以还是很有必要学习它的基本用法的。
本质上讲,shell 是 linux 命令集的概称,是属于命令行的人机界面。shell 里语句可以直接是 linux 命令的执行。
shell分为几个版本,Bourne Shell, C Shell,Bash (Bourne Again Shell),Korn Shell,Z Shell 等版本。
常用的 shell 主要有两种:Bash 和 C Shell,特点如下:
- Bash 是 GNU 项目的一部分,是最广泛使用的 Shell 之一。
- 完全兼容 Bourne Shell,并扩展了大量功能,如命令行编辑、命令补全、历史记录等。
- 支持函数定义、数组操作、关联数组(从版本 4 开始)等高级特性。
- 非常适合脚本编写和日常使用,是 Linux 系统默认的 Shell。
- 在 linux 中,默认的环境配置文件路径在~/.bashrc,用户在登录后,默认执行该配置。
- C Shell 提供一种更接近于 C 语言语法的脚本环境。
- 支持命令历史记录、别名、文件名补全等功能,提高了交互效率。
- 提供了一些类似于 C 语言的控制结构(如
if、switch),便于熟悉 C 的开发者使用。 - 不适合复杂的脚本编程,因为它的变量处理不如 Bash 灵活。
- 在 linux 中,默认的环境配置文件路径在~/.cshrc,用户在登录后,默认执行该配置。
二、开始 Bshell
shell 语言是 linux 命令集的概称,shell 可以通过其条件语句和循环语句等,把一系列 Linux 命令结合在一起,形成一个相当于面向过程的程序。
同时,在语法上,shell 语言格式与其他编程需要有相当大的不同。这个做一个简单的总结:
- 用 # 进行单行注释,也可多行注释,多行注释请百度,一般用的少
- 用空格分割命令,空格不能随便用
- 用换行分割语句,分号也可用来分割语句。语句可以是一个命令,也可以是一个关键词。
- 对缩进没有要求,但是尽可能好看点,便于阅读
一个简单的 hello.sh 脚本像下面这样:
#!/bin/bash # 标识该 Shell 脚本由哪个 Shell 解释
echo "Hello World!" # 打印输出字符 Hello World!
运行 shell 脚本:在 CMD 命令行下,sh hello.sh 即可,也可 ./hello.sh 运行
后台运行:sh hello.sh & ,若退出终端的运行就会挂掉。
后台挂起运行:nohup sh hello.sh &,hohup 的作用是:用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。
Shell 的编写流程:
- 编写 Shell 脚本
- 赋予可执行权限(一般可以忽略)
- 执行,调试
2.1 shell 关键字
所有的 linux 命令都可以在 shell 脚本里直接使用,比如:
#!/bin/bash
input=`ls ./teat/*` #`` 是反引号,通常位于 esc 键下面,用于执行 linux 的 ls 命令并返回结果
除此之外,bshell 还有以下关键字用于脚本编写。
2.1.1 基本关键字
基本常用的关键字如下:
- echo:打印文字到屏幕
- exec:执行另一个 Shell 脚本
- read:读标准输入
- expr:对整数型变量进行算术运算
- test:用于测试变量是否相等、 是否为空、文件类型等
- exit:退出
看个例子,新建文件 test.sh,写入:
#!/bin/bash
echo "Hello Shell" # 打印输出字符串 Hello Shell
# 读入变量(从屏幕输入)
read VAR
echo "VAR is $VAR"
# 计算变量
expr $VAR - 5 #算术运算,并返回值
# 测试字符串
test "Hello"="HelloWorld"
# 测试整数
test $VAR -eq 10
# 测试目录
test -d ./Android
# 执行其他 Shell 脚本
exec ./othershell.sh
# 退出
exit
$ 符号是对变量取值
2.1.1 各种重要符号
$ 变量名:对变量取值${ 变量名 }:对变量取值,花括号的作用仅仅是精确界定变量名称的范围。$(命令或函数名):执行命令或函数,并返回执行结果。与反引号 ` 命令或函数名 ` 作用一致引号:见 2.2.1 章节
$[1+2]与$((2+1)):进行整数运算,注意这里可以没有空格[]:条件判断符号,用于条件测试,见 2.5 章节(()):仅仅用于整型数字的计算与比较[[]]:双方括号为字符串比较提供高级功能,模式匹配。常见用法见 2.4.2。[[是 bash 程序语言的关键字。;分号或换行,一个 / 一句命令的结束
()与 {} 的区别
相同点:
- ()和 {} 都是把一串的命令放在括号里面,如果命令在一行,则命令之间用 ; 隔开
不同点:
()只是把一串命令重新开一个子 shell 进行执行,不影响当前 shell 环境;{}对一串命令在当前 shell 执行, 影响当前 shell 环境
()最后一个命令不用分号,{}最后一个命令要用分号
()里的第一个命令和左边括号不必有空格,{}的第一个命令和左括号之间必要要有一个空格
()和 {} 中括号里面的某个命令的重定向只影响改名了,但括号外的重定向则影响到括号里的所有命令
== 与 = 的区别
- == 可用于判断变量是否相等,= 除了可用于判断变量是否相等外,还可以表示赋值。
- = 与 == 在 [] 中表示判断 (字符串比较) 时是等价的
- 在 (()) 中 = 表示赋值, == 表示判断(整数比较),它们不等价
${}的补充用法
- ${var:-word}:若 var 为空或未设置,返回默认值但是并不把默认值赋值给该变量,若 var 不为空,则不替换,var 的值不变
- ${var:=word}:若 var 为空或未设置,把默认值赋值给该变量。若 var 设置了,则不替换,var 的值不变
- ${var:+word}:若 var 不为空时,返回默认值,并且也不重新赋值
2.2 字符串
shell 就两种数据类型,字符型和数组。数字(整型)也可以看作是一种字符串。
在 Shell 中所有的变量默认都是字符串型。字符串可以用单引号,也可以用双引号,也可以不用引号。
字符串赋值时,变量名和等号之间 不能有空格
取值时,只要在变量名前面加美元符号 $ 即可,也可使用 ${变量名}
2.2.1 引号
单引号
str='this is a string'单引号字符串的限制:
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
双引号
name="Jack" str="my name is $name"双引号的优点:
- 双引号里可以有变量
- 双引号里可以出现转义字符
不加引号
path=/home/qiang/ file=$path/xor.txt不加引号特点:
- 只能是连续字符串,不能有空格
- 可以有变量
- 可以出现转义字符
这里补充一个符号:反引号 `
这个符号通常位于键盘 Esc 键的下方。当用尖角号括起来一个 shell 命令时,代表执行这个命令,并将执行的结果返回给赋给的变量。
2.2.2 字符串方法
获取子串长度:
${#str},获取 str 变量的字符串长度提取子串(切片):
${str:1:4},从第 2 个字符开始,截取 4 个字符${str:2},从第 3 个字符开始,截取后面所有字符${str:2:-1},从左往右第 3 位开始截取,从右往左截取到第一位
查找子串:
expr index "$str" xy #查找字符 x 或 y 的位置(哪个字母先出现就计算哪个)拼接字符串:
"hello, ""$name",直接写在一块就行。字符串替换:
${var/pattern/replacement}匹配删除:
直接匹配:
语法 说明 ${str#hello}如果 str 以 hello 为开头就删掉 hello ${str%hello}如果 str 以 hello 为结尾就删掉 hello 通配符匹配:
语法 含义 示例(var=”a_b_c.txt”) 结果 ${var# 模式 }从开头删,最短匹配 ${var#*_}b_c.txt${var## 模式 }**从开头删,最长匹配 ${var##*_}c.txt${var% 模式 }从结尾删 , 最短匹配 ${var%.txt}a_b_c${var%% 模式 }从结尾删 , 最长匹配 ${var%%.*}a_b_c通配符:
通配符 含义 *匹配任意字符(包括空) ?匹配任意单个字符 [abc]匹配 a、b 或 c [0-9]匹配数字
2.3 shell 变量类型
Shell 变量分为 3 种:
- 用户自定义变量
- 等号前后不要有空格:
NUM=10 - 一般变量名用大写:
M=1
- 等号前后不要有空格:
- 预定义变量
- 环境变量
2.3.1 自定义变量
这种变量 只支持字符串类型,不支持其他字符,浮点等类型,常见有这 3 个前缀:
unset:删除变量readonly:标记只读变量export:指定全局变量
一个例子:
#!/bin/bash
# 定义普通变量
CITY=SHENZHEN #将字符串 SHENZHEN 赋给变量 CITY
# 定义全局变量
export NAME=cdeveloper
# 定义只读变量
readonly AGE=21
# 打印变量的值
echo $CITY
echo $NAME
echo $AGE
# 删除 CITY 变量
unset CITY
2.3.2 预定义变量
预定义变量常用来获取命令行的输入,有下面这些:
$0:脚本文件名$1-9:第 1-9 个命令行参数名$#:命令行参数个数$@:所有命令行参数$*:所有命令行参数$?:前一个命令的退出状态,可用于获取函数返回值$$:执行的进程 ID
在运行 shell 脚本的时候,可以外部传参,供脚本内部使用:
sh test.sh param1 parma2 parma3 #运行 test.sh 脚本并传入三个参数 param1 parma2 parma3这时候这 7 个预定义变量的作用就容易出来了。
一个例子执行sh.test.sh x y z:
#!/bin/bash
echo $0 #输出 test.sh
echo $1 #输出 x
echo $2 #输出 y
echo $3 #输出 z
echo $# #输出 3
echo $@ #输出 x y z
echo $* #输出 x y z
echo $? #输出 0
echo $$ #输出 184715
2.3.3 环境变量
环境变量默认就存在,常用的有下面这几个:
HOME:代表用户主目录PATH:代表系统环境变量 PATHTERM:代表当前终端UID:代表当前用户 IDPWD:代表当前工作目录,绝对路径
看一个例子:
#!/bin/bash
echo "print env"
echo $HOME #输出 /home/origin
echo $PATH #输出 /home/orange/anaconda2/bin: 后面还有很多
echo $TERM #输出 xterm
echo $PWD #输出 /home/origin/test
echo $UID #输出 1674
2.4 shell 运算符
由于 Shell 中所有的变量默认都是字符串型,故在运算时,不同于常规运算方法。
2.4.1 算术运算
shell 的算术运算只支持整型数字运算(包括正负整型),不支持浮点数。
在算术运算时,非数字的单字符或字符串都被 shell 当作 0。
常用的四种运算格式(都是计算 m+10):
m=$[m+10]m=$((m+10))let m=m+10#除了let后面有空格,计算中必定不能存在空格,只能赋值,不能直接输出- 利用
expr命令
举例说明:
#!/bin/sh
aa=10
bb=$((aa+10))
bb=$[aa+10]
let bb=aa+10
bb=`expr $aa + 10`
if ["$aa" == 10]; then # “10” 加引号也可
((aa++))
fi
echo $aa #输出 11
支持的运算符如下:
- 加号(+)、减号(-)、乘法(*)、除法(/)、取余(%)、赋值(=)、自增(++)、自减(–)
小数(浮点数)运算
- 利用 bc 模块
bc是Linux下的计算机工具模块,bc支持交互式和非交互式两种计算,在进行计算的时候,可以使用scale=n来指定小数点的位数,还支持比较操操作符>、>=、<、<=、==、!=。交互式:打开bc计算机,进行使用。非交互式:通过脚本命令执行,不需要打开计算机。- 在使用
bc命令时如果报错bc: command not found,说明没有安装此工具模块,需要进行安装:
- 利用 awk 模块
- awk 是一种编程语言,用于在 linux/unix 下对文本和数据进行处理。在本博客另一文章有介绍[linux 常见命令学习 | jqiange](https://jqiange.github.io/linux 常见命令学习 /#3-2-awk 命令)
举例:
#!/bin/bash
echo "scale=2;10/3" | bc #scale=2 是保留两位有效小数,计算 10/3 的值
result=`echo "scale=2;10/3" | bc`
#------ 传参, 2 种方式
result=$(bc -l <<< "scale=2;$a * $b")
result=`echo "$a + $b" | bc`
#----- awk, awk 传参麻烦,不建议用
awk 'BEGIN { print 3.14 + 2.86 }'
awk 'BEGIN { printf "%.2f\n", 10 / 3 }' # 保留两位小数
2.4.2 逻辑运算符
| 运算符 | 说明 | 举例 |
|---|---|---|
| && | 逻辑 AND | [[$a > 0 && $b < 10]] |
| || | 逻辑 OR | [[$a >= 0 || $b < 10]] |
特点:
- 短路求值:如果
command1失败,command2不会执行 - 用于命令流程控制,不是专门用于条件测试。
举例:
#!/bin/sh
index=0
file="test.txt"
#---- 写法 1
if [[$index == 0 && -f $file]]; then
echo "hello" > $file
fi
#---- 写法 2
if [$index == 0] && [-f $file]; then
echo "hello" > $file
fi
#---- 写法 3
if ((index > 0)) && [-f "$file"]; then
echo "hello" > $file
fi
2.4.3 布尔运算符
| 运算符 | 说明 | 举例 |
|---|---|---|
| ! | 取反运算 | [! -f $file] |
这里只需要记住这个即可,其他的布尔运算符不建议用。
2.5 条件测试
shell 条件测试一共就三种: 文件测试 , 数值比较 , 字符串比较
条件测试分为三种用法,但作用是一样的:
test 条件表达式[条件表达式][[条件表达式]]
推荐使用第二种。
2.5.1 文件测试

用法示例:
[! -d /home/test] && makdir /home/test #目录不存在就创建
[-d /home/test] || makdir /home/test #目录存在就不创建
test -d /home/test
echo $?
0 #在 shell 中,为真的退出状态码为 0,为假时状态码为 1
2.5.2 数值比较
关系运算符只支持 整数运算,不支持字符串,除非字符串的值是数字。
- 在
[]或test中同时支持自 字母 和符号 运算符
- 在
(())仅仅使用 符号 运算符
| 字母运算符 | 符号运算符 | 示例 | 说明 |
|---|---|---|---|
-eq |
== |
["$a" -eq "$b"] 或 ((a == b)) |
等于 |
-ne |
!= |
["$a" -ne 5] 或 ((a != 5)) |
不等于 |
-lt |
< |
["$a" -lt 10] 或 ((a < 10)) |
小于 |
-le |
<= |
["$a" -le 10] 或 ((a <= 10)) |
小于等于 |
-gt |
> |
["$a" -gt 0] 或 ((a >= 0)) |
大于 |
-ge |
>= |
["$a" -ge 100] 或 ((a >= 100)) |
大于等于 |
必须用双引号包裹变量(防止空值导致语法错误)
["$count" >= 5] # ✅ 安全
[$count >= 5] # ❌ 若 count 为空,会报错
浮点数比较
a=3.14
b=2.71
#---- 比较 a > b ?
if ["$(echo "$a > $b" | bc)" = "1" ]; then
echo "a 大于 b"
fi
2.5.3 字符串比较
字符串变量要使用双引号引起来

用法示例:
cha="aa"
if ["$cha" == "aa"]; then
echo "is aa"
fi
2.6 shell 语句
2.6.1 if 语句
格式:
if 条件测试 1 ; then
执行语句 1
elif 条件测试 2; then
执行语句 2
else
执行语句 2
fi
用法示例:
#!/bin/bash
VAR=10
if [$VAR == 10]; then
echo "true"
else
echo "false"
fi
2.6.2 case 语句
格式:
case $ 变量 in
值 1)
执行语句 1
;;
值 2)
执行语句 2
;;
*)
执行语句 3
;;
esac
2.6.3 for 语句
格式:
#--- 格式 1
for ((i = 1; i <= 3; i++))
do
echo $i
done
#--- 格式 2
for j in 1 2 3
do
echo $j
done
#--- 格式 3
for j in {0..100} #输出 0-100
do
echo $j
done
workspace="/home/user1/project"
input=`ls ./teat/*.gg`
for ff in $input
do
out="$workspace/$input"
echo $out
done
2.6.4 while 语句
格式:
while 条件测试 #条件为真,执行
do
执行语句
done
2.6.5 until 语句
格式:
until 条件测试 #条件为假,执行
do
echo $i
i=$[$i + 1]
done
2.6.6 break
Shell 中的 break 用法与高级语言相同,都是 跳出循环,来看个例子:
for VAR in 1 2 3
do
if [$VAR == 2]
then
break
fi
echo $VAR
done
2.6.7 continue
continue 用来 跳过本次循环,进入下一次循环
for VAR in 1 2 3
do
if [$VAR == 2]
then
continue
fi
echo $VAR
done
2.7 shell 数组
shell 就两种数据类型,字符型和数组。字符串之前已经介绍了,这里介绍数组。
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小。
2.7.1 数组定义
# ---- 第一种
arr=(v1 v2 v3 v4 v5) #v 可以是字符串或者数字,不必类型相同
#---- 第二种
arr1=(
xxx
yyy
zzz
)
#---- 数组的遍历
for case in ${arr1[*]}
do
echo $case
done
#----- 单独赋值
arr[1]=10
#---- 第三种: 用字符串实现同样的功能
arr2="
xxx
yyy
zzz
"
#----- 字符串的遍历
for item in $arr2
do
echo $item
done
一对括号 (…) 表示的是数组,数组元素用空格符号分隔开
数组和字符串循环取值的方式不同,注意区分
2.7.2 读取与赋值
- 读取数组:
- 读取整个数组:
${arr[@]}或者${arr[*]} - 按索引读取:
${arr[index]},索引从 0 开始
- 读取整个数组:
- 读取长度:
${#arr[@]}或者${#arr[*]} - 赋值:
arr[1]=100 - 删除:
unset arr[1]或unset arr - 替换:
${a[@或 *] / 查找字符 / 替换字符 },该操作不会改变原来的数组内容
一个常用的例子:
caselist=($(ls /home/template_dir | grep -v 'xor'))
for case in ${caselist[*]}
do
echo $case
done
2.8 shell 函数
shell 函数中,默认均为全局变量,如想用局部变量加local 关键字
2.8.1 函数定义与调用
格式 1:
function fun1(){ #如果写了 function 关键字,()可以省略
echo $1 #返回方式 1
echo $2
return 0 #返回方式 2
}
#1 直接函数名调用, 并传参
fun1 10 20
#2 间接调用
F=`fun1 100 200`
echo $F
格式 2:
fun2()
{
echo "fun2 call"
}
#3 直接函数名调用,不带参数方式
fun2
Shell 函数返回值,常用的两种方式:return、echo。二者是有差别的
- return:只能用来返回整数值(0-255),一般是用来表示函数执行成功与否的,0 表示成功,其他值表示失败。
- echo:标准输出返回,可以返回任何类型的数据。
2.8.2 获取函数返回值
函数用 echo 输出返回:直接函数名调用
函数用 return 输出返回:
$?接收,$?要紧跟在函数调用处的后面
先举个例子:
fun2()
{
echo "fun2 call"
return 100
}
fun2 # 输出 echo 的内容: fun2 call
echo $? #输出 return 的内容:100
echo $? #输出函数退出码:0
还有 2 种:
- 函数名当命令执行:`fun2` (尖角号) 或者 $(fun2)
- 传参输出返回:$(fun2 “/temp”)
再举个例子:
fun3()
{
echo "fun3 call"
}
echo `fun3` #输出打印 fun3 call
echo $(fun3) #输出打印 fun3 call
re=$(fun3)
echo ${re} #输出打印 fun3 call
2.8.3 高级收参
$@ 可以接收所有参数,以数组的方式。
function getsum(){
local sum=0
for n in $@
do
((sum+=n))
done
echo $sum
return 0
}
total=$(getsum 10 20 55 15)
echo $total
2.9 shell 重定向
2.9.1 输出重定向
命令的结果不再输出到显示器上,而是输出到指定的文件里。
- 命令输出重定向
格式:
command > file #覆盖写入到文件
command >> file #追加写入到文件 用法示例:
echo "hello world!" > data.txt
ls -l >> data.txt
- cat 输出重定向 : 用于多行文本写入
用法示例:
cat > file << EOF
export ORACLE_SID=yqpt
export PATH=\$PATH:\$ORACLE_HOME/bin
EOF
作用:将两个 EOF 之间的内容输出写到 data.txt 文件里。
- EOF 只是一个标识符,也可使用其他字符代替
- 多行文本如有 $ 等特殊字符时,须利用转义字符 \
2.9.2 输入重定向
使用文件作为命令的输入。
command < file #将 file 文件中的内容作为 command 的输入
command << END #从标准输入(键盘)中读取数据,直到遇见分界符 END 才停止 高级用法(代码输入重定向)示例:
#!/bin/bash
sum=0
while read n; do
((sum += n))
done < nums.txt #输入重定向
echo "sum=$sum"
2.10 shell 调试
检查是否有语法错误:
sh -n script_name.sh执行并逐步调试 shell 脚本:
sh -x script_name.sh带有 + 表示的是 Shell 调试器的输出 , 不带 + 表示我们程序的输出。
csh 同样支持逐步调试!使用csh -x test.sh
三、开始 Cshell
csh 缺乏函数,局部变量等一些高级特性,但是在芯片及其相关软件应用上(Linux 环境),仍然非常广泛,时常需要用其写一些自动化脚本来执行任务,所以本章也对其做一个较为详细的介绍。
1. 变量声明
#!/bin/csh
#====== 使用 set 声明变量
set enc = "this is a test!"
set ax = 10 # csh 变量赋值只支持整数,不支持小数,需要额外的手段
echo $enc
echo $ax
2. 数组与循环
在 csh(C Shell) 中,没有真正意义上的“数组”类型 (不像 bash 有索引数组或关联数组),但 csh 和其增强版 tcsh 支持一种称为“单词列表”(word list)的变量形式,可以 模拟简单的一维字符串数组。
#!/bin/csh
set myarr = ("aa" "bb" "cc")
echo $myarr[1] #index 从 1 开始
echo $#myarr #输出元素个数
foreach el (${myarr})
set out = $el
end
多行的写法:
set aa = (\
test1.txt \
test2.txt \
test3.txt \
)
多行的写法只能是这样,没有更加优雅的方法。
3. 环境配置与别名声明
一般 csh 的默认配置文件为:~/.cshrc,可以在里面配置一些环境。
setenv PATH /home/user1/install/ #配置环境变量
alias .. "cd .." #别名(快捷命令)
alias python "/home/user1/install/python3.10"
4. 逻辑判断与循环语句
4.1 if 判断
#!/bin/csh
set num = 5
if ($num == 1) then
echo "Number is 1"
else if ($num == 2) then
echo "Number is 2"
else if ($num == 3) then
echo "Number is 3"
else
echo "Number is not 1, 2, or 3"
endif
4.2 循环语句
#!/bin/csh
#======== foreach
set myarr = ("aa" "bb" "cc")
foreach el (${myarr})
set out = $el
end
foreach folder (test1 test2 test3)
if (! -d $folder) then
mkdir -p $folder
endif
end
#======= while
set sum = 0
set i = 1
while ($i <= 5)
set sum = `expr $sum + $i`
set i = `expr $i + 1`
end
echo "Sum is $sum"
#=========switch
switch ($sum)
case 1:
# commands
breaksw
case 2:
#commands
default:
breaksw
endsw
想其他语言一样,csh 的循环体同样支持 break 和continue:
- break:跳出终止当前循环
- continue:跳过本次循环剩余部分,开始下一次循环迭代
5. 写文件
写文件也叫数据重定向,使用尖括号> filePath
#!/bin/csh
#====== 单行重定向
echo "this is a test" > tt.log
#====== 多行重定向
set words = ("test1" "test2" "test3")
cat > tt.log << END
this is a $words[1]
this is a $words[2]
this is a $words[3]
END
6 数据运算与条件判断
6.1 数据运算
数据分为:数字,字符串。下面分别介绍数字运算和字符串处理方法
6.1.1 原生算数表达式:
@ c = $a + $b
@ d = $c * 2
@ e = $d / 3
@ f = $d % 4
- 支持的运算符:
+,-,*,/,%,+=,-=,++,-- - 不支持括号嵌套复杂表达式(如
@ x = ($a + $b) * 2会报错) - 所有操作必须在
@行内完成,不能直接在set中做算术
举例:
#!/bin/csh
set x = 7
set y = 3
@ sum = $x + $y
echo "Sum is $sum"
6.1.2 扩展算数
借助外部工具,还可以采用其他的方式:
#==== expr 命令,整数运算
set sum = `expr $a + $b`
set product = `expr $a \* $b`
#==== bc 命令,小数计算
set result = `echo "scale=2;10/3" | bc` #scale=2 保留两位小数
echo $result
# ==== awk 命令,实数运算
set pi = `awk 'BEGIN {print 22/7}'`
echo "Approx pi = $pi" #输出:3.14286
6.1.3 字符串运算
字符串拼接:写一行写一块就行
set first = "John" set last = "Doe" #===== 形式 1 set full = "$first $last" #===== 形式 2 set aa = "hhhha"`basename "test.txt" .txt`字符串长度:无内置命令,需要借助外部命令
set str = "hello" set len = `echo -n "$str" | wc -c` echo "Length: $len"子串提取:无内置命令,可借助 awk/cut/sed
set s = "abcdef" set sub = `echo "$s" | cut -c2-4` # 提取第 2 到第 4 字符 echo $sub # 输出:bcd
6.2 条件判断
6.2.1 数值与字符串判断
#===== 数值判断
set x = 10
if ($x > 5) then
echo "x is greater than 5"
endif
#===== 字符串判断
set name = "Alice"
if ("$name" == "Alice") then
echo "Hello, Alice!"
else
echo "Who are you?"
endif
数值支持:==、!=、<、<=、>、>=
字符串支持:==、!=
6.2.2 文件判断
使用 csh 可以直接对文件或者路径进行判断:
#!/bin/csh
# 定义文件名
set filename = "test.txt"
#===== 判断文件是否存在
if (-e $filename) then
echo "$filename 存在 "
else
echo "$filename 不存在 "
endif
文件 / 文件夹判断方法总结如下:
| 表达式 | 含义 |
|---|---|
-r file |
文件存在且可读 |
-w file |
文件存在且可写 |
-x file |
文件存在且可执行 |
-e file |
文件存在(任何类型) |
-f file |
文件存在且是普通文件 |
-d file |
文件存在且是目录 |
-c file |
字符设备文件 |
-b file |
块设备文件 |
-p file |
命名管道(FIFO) |
-l file |
符号链接(部分实现支持) |
-u file |
设置了 setuid 位 |
-g file |
设置了 setgid 位 |
-s file |
文件存在且非空(size > 0) |
6.3 逻辑运算
| 运算符 | 含义 | 示例 |
|---|---|---|
&& |
逻辑与(AND) | if ($a > 0 && -f "$file") then |
| ` | ` | |
! |
逻辑非(NOT) | if (! -e "$tmp") then |
必要时用括号明确顺序(但注意 csh 对复杂嵌套括号支持有限):
if (( $a == 1 || $a == 2) && -f "data$a.txt" ) then
...
endif
欢迎各位看官及技术大佬前来交流指导呀,可以邮件至 jqiange@yeah.net