shell基本语法

本文深入解析Linux命令行的基础知识与高级技巧,包括变量、命令替换、算术替换、交互登录与非登录shell、非交互启动shell、条件测试、if语句、case语句、for循环、while循环、位置参数、函数、调试方法以及常用shell命令的使用。旨在帮助开发者高效掌握Linux命令行操作,提升生产力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不同的命令可接受的命令行格式或有不同,一般情况下,一个标准的命令行格式为如下所列:
command-name options argument

若从技术细节来看,shell 会依据 IFS(Internal Field Seperator) 将 command line 所输入的文字给拆解为"字段"(word)。
然后再针对特殊字符(meta)先作处理,最后再重组整行 command line 。
(注意:请务必理解上两句话的意思,我们日后的学习中会常回到这里思考。)

其中的 IFS 是 shell 预设使用的字段分隔符,可以由一个及多个如下按键组成:
* 空格键(White Space)
* 表格键(Tab)
* 回车键(Enter)

 

首先己说说语法里的配对现象:

if --fi

case--esac

do--done

1、变量

定义一个变量:varname=value,等号两边不能有空格,否则会被解释成命令。

变量分为本地变量和环境变量。本地变量只存在于当前的shell进程,而环境变量

可以从当前进程传递给fork出来的子进程。printenv可以打印出当前进程的环境变量。

用export可以将本地变量导出成环境变量。用unset可以删除变量。

 

2、命令代换

可以用`和$()进行命令代换。如:

birth=`date`或birth=$(date)

 

3、算术代换$(())

var=45

echo $(($var+3))

 

4、转义字符/

这个/没什么好说的,各种语言都有,不过在shell里有个特殊的地方。
其中“-”加上转义字符也不行,如果要创建一个-hell的文件,你需要这么做
touch ./-hello

 

5、交互登录的shell

就是输入用户名和密码后得到的shell。

进入登录shell后会执行一系列文件:

/etc/profile、~/.bash_profile、~/.bash_login、~/.profile

在退出时候要执行~/.bash_logout

 

6、交互非登录的shell

在图形界面打开一个终端或者在登陆shell中执行bash命令,就得到一个交互非登录的shell。
这种shell在启动时自动执行~/.bashrc。
一般在bashrc里面设置本地变量、函数、alias。

 

7、非交互启动的shell
为执行脚本而fork出来的是非交互shell。

它会执行BASH_ENV这个环境变量指定的文件。
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

 

8、条件测试

可以用test或[]进行条件测试,如果测试结果为真就返回0,如果为假就返回1。

测试两个数的大小:

  1. $ VAR=2  
  2. $ test $VAR -gt 1  
  3. echo $?  
  4. 0  
  5. $ test $VAR -gt 3  
  6. echo $?  
  7. 1  
  8. $ [ $VAR -gt 3 ]  
  9. echo $?  
  10. 1  

[是一个命令,传递给它的参数都用空格分开。

bash 的 test 目前支援的測試對像只有三種:
* string:字串,也就是純文字。
* integer:整數( 0 或正整數,不含負數或小數點)。
* file:文件。
請初學者一定要搞清楚這三者的差異,因為 test 所用的 expression 是不一樣的。
以 A=123 這個變量為例:
* [ "$A" = 123 ]:是字串的測試,以測試 $A 是否為 1、2、3 這三個連續的"文字"。
* [ "$A" -eq 123 ]:是整數的測試,以測試 $A 是否等於"一百二十三"。
* [ -e "$A" ]:是關於文件的測試,以測試 123 這份"文件"是否存在。 

常见的测试命令如下:

[ -d dir ] :如果dir存在,返回真

[ -f filename ] :如果filename这个文件存在,就返回真

[ -z string ] :如果string为空返回真

[ -n string ] :如果string不为空返回真

[ string1 = string2 ] :如果相等返回真

[ string1 != string2 ] :如果不相等返回真

[ arg1 OP arg2 ] :OP可以是-gt/-lt/-ge/-le/-eq/-ne中的任意一个。对整数的测试

比较字符写法

-eq   等于
-ne    不等于
-gt    大于
-lt    小于
-le    小于等于
-ge   大于等于

以上是对整数的测试字符,

下面是对字符串的:
-z    空串
=     两个字符相等
!=    两个字符不等
-n    非空串  (測試 string 長度大於 0)

is one of -eq, -ne, -lt, -le, -gt or -ge. These arithmetic binary operators return true if “ARG1” is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to “ARG2”, respectively. “ARG1” and “ARG2” are integers.

 

其他语言常用的!、and、or在shell里面这么表示:

同時,test 也允許多重的覆合測試:
* expression1 -a expression2 :當兩個 exrepssion 都為 true ,才送出 0 ,否則送出非 0 。
* expression1 -o expression2 :只需其中一個 exrepssion 為 true ,就送出 0 ,只有兩者都為 false 才送

[ ! exp ]

[ exp1 -a exp2 ]

[ exp1 -o exp2 ]

举个例子:

[ -d test -a “$var”="abc" ]

其中$var一般要用引号引起来,否则容易引起错误。原因是,如果var为空的话,这句会被

解释成这样:[ -d test -a ="abc" ],这显然有语法错误,但是加上引号就会被解释成这样:

[ -d test -a ""="abc" ]这样无论如何都不会有语法错误了。

 

9、if语句

if语句常常包含以下关键词:if、then、else、elif、fi。

  1. if [ -f ~/.bashrc ]; then  
  2.     . ~/.bashrc  
  3. fi  
  4. if :; then echo "always true"; fi  

if [ -f ~/.bashrc ]是一条,then . ~/.bashrc、fi各是一条。如果两条写在一块,就要用“;”分割。

:是一个空命令,表示什么也不执行。

shell的if与c语言if的功能上的区别

 shell if   c语言if
0为真,走then 正好相反,非0走then
 不支持整数变量直接if
必须:if [ i –ne 0 ]

但支持字符串变量直接if
if [ str ] 如果字符串非0
 支持变量直接if
if (i )
 

比较两个字符串是否相等的办法是:

    if [ "$test"x = "test"x ]; then

    这里的关键有几点:

    1 使用单个等号

    2 注意到等号两边各有一个空格:这是unix shell的要求

    3 注意到"$test"x最后的x,这是特意安排的,因为当$test为空的时候,上面的表达式就变成了x = testx,显然是不相等的。而如果没有这个x,表达式就会报错:[: =: unary operator expected

注意: if [ "$test"x = "test"x ]  "$test"x = "test"x  前后都要有空格



10、case语句

case语句 :它能够把变量的内容与多个模板进行匹配,再根据成功匹配的模板去决定应该执行哪部分代码。
使用格式:
case 匹配母板 in
模板1 [ | 模板2 ] … ) 语句组 ;;
模板3 [ | 模板4 ] … ) 语句组 ;;
esac
case语句的匹配是从上往下地匹配顺序。因此,case语句编写的原则是从上往下,模板从特殊到普通。在C语言里,case语句中有default模板,而
在shell程序设计中,可能将模板写成*,就可以完成相同的功能。

  1. #! /bin/sh  
  2. echo "Is it morning? Please answer yes or no."  
  3. read YES_OR_NO  
  4. case "$YES_OR_NO" in  
  5. yes|y|Yes|YES)  
  6.   echo "Good Morning!";;  
  7. [nN]*)  
  8.   echo "Good Afternoon!";;  
  9. *)  
  10.   echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."  
  11.   exit 1;;  
  12. esac  
  13. exit 0  

 

11、for/do/done

for 无$变量 in字符串
do
  $变量

done

(字符串是以 “空格”区分的)

  1. #! /bin/sh  
  2. for FRUIT in apple banana pear; do  
  3.   echo "I like $FRUIT"  
  4. done  

 

12、while/do/done

  1. #! /bin/sh  
  2. echo "Enter password:"  
  3. read TRY  
  4. while [ "$TRY" != "secret" ]; do  
  5.   echo "Sorry, try again"  
  6.   read TRY  
  7. done  

 

13、位置参数和特殊变量

$0:文件名 相当于C语言main函数的argv[0]

$#:参数个数 

$1,$2 这些称为位置参数(Positional Parameter),相当于C语言main函数的argv[1]、argv[2]...

$@:参数列表,不包括$0 表示参数列表"$1" "$2" ...,例如可以用在for循环中的in后面。

$?:上一次命令执行是否成功的标志 上一条命令的Exit Status

$$:进程id

 

14、函数

调用函数时可以传递任意个参数,在函数内提取参数用$0/$1....

下面这个脚本可以一次创建多个目录,各目录名通过命令行参数传入,脚本逐个测试各目录是否存在,如果目录不存在,首先打印信息然后试着创建该目录。

  1. #! /bin/sh  
  2. is_directory()  
  3. {  
  4.   DIR_NAME=$1  
  5.   if [ ! -d $DIR_NAME ]; then  
  6.     return 1  
  7.   else  
  8.     return 0  
  9.   fi  
  10. }  
  11. for DIR in "$@"do  
  12.   if is_directory "$DIR"  
  13.   then :  
  14.   else  
  15.     echo "$DIR doesn't exist. Creating it now..."  
  16.     mkdir $DIR > /dev/null 2>&1  
  17.     if [ $? -ne 0 ]; then  
  18.       echo "Cannot create directory $DIR"  
  19.       exit 1  
  20.     fi  
  21.   fi  
  22. done  

15 select 表达式是一种bash的扩展应用,尤其擅长于交互式使用。用户可以从一组不同的值中进行选择。
select var in ... ; do
 break
done

例如 :
#!/bin/sh
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
 break
done
echo "You have selected $var"
结论 :
linux-bvhu:/home # ./select.sh
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1   //选择数字
You have selected Linux

16.

&& 與 || 都是用來"組建"多個 command line 用的:
* command1 && command2 :其意思是 command2 只有在 RV 為 0 (true) 的條件下執行。
* command1 || command2 :其意思是 command2 只有在 RV 為非 0 (false) 的條件下執行。

17、脚本的调试

sh -x ./test.sh:这样可以将执行的每一条命令和结果打印出来。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值