shell编程

目录

一、开头

二、注释

三、变量

1>用户自定义变量

2>预定义变量

3>位置参数

4>环境变量

四、shell程序和语句

1>说明性语句

2>功能性语句

3>结构性语句

4>break与continue

五、shell函数

1>函数的定义格式

2>函数调用格式

六、案例

一、案例一

二、案例二​


什么是shell,他是一个命令解释器,介于linux系统和用户之间的绝缘层。它的作用就是把你需要执行的各种命令放在一个.sh文件中,然后一次性执行的一个程序文件。

一、开头

创建一个.sh文件就可以编写shell脚本了,但是文件的第一行必须是以下命令

#!/bin/bash

(这个bash是终端的版本,本案例使用bash版本)

文件编辑完成后并不能运行,因为没有运行权限,因此要给他加上可执行权限

chomd +x 文件名.sh

然后./文件名.sh就能运行了

二、注释

shell中注释与c有所不同,他只有一种注释,即以#开头便是注释,到这一行结束。

三、变量

shell所有的变量都有字符串组成,并且不需要提前声明。一共有四种变量分别是用户自定义变量,位置参数即命令行参数,预定义变量,环境变量。

1>用户自定义变量

shell中可以自定义变量,但是它没有数据类型,任何赋予自定义变量的值都会被shell解释为一串字符串。它的命名规则与c相同

~   由字母、数字以及下划线(_)组成,首字母不能为数字

~   不能为关键字和保留字

~   尽量见名知意

给变量赋值

变量名=值

这里等号两边不能有空格,而且shell中通常使用全大写来写变量;

若要取变量的值可以用$符号,例如我定义一个变量COUNT

COUNT=2

echo "this is the $COUNTnd"

是不是以为他会打印this is the 2nd

shell并不知道COUNDnd的值,因此需要给他加上{},即

COUNT=2

echo "this is the {$COUN}nd"

使用unset命令可删除变量的赋值

upset COUNT

他的值就会被撤销

2>预定义变量

当执行一个 Shell 脚本时,如果希望获取到命令行的参数信息,就需要使用到位置参数变量。基本语法有:

$# :代表命令行中所有参数的个数(命令不记在参数内)

$n :n 为数字,$0 代表命令本身,$1-9 代表第 1 到第 9 个参数,10 以上的参数需要用大括号包含如 ${10}
$*:代表命令行中的所有参数,$* 将所有参数看成一个整体
$@  :这个变量也可以代表命令行中的所有参数,不过 $@ 把每个参数区分对待

$?:包含前一个命令的退出状态,正常退出返回0,反之则为非0值

$$:包含正在执行进程的id号

#!/bin/bash
# 获取命令行参数的个数
echo "Number of arguments: $#"

# 输出命令本身
echo "Script name: $0"

# 输出前3个命令行参数
echo "First argument: $1"
echo "Second argument: $2"
echo "Third argument: $3"

# 输出所有命令行参数作为一个整体
echo "All arguments as a whole: $*"

# 使用$@遍历并输出每个命令行参数
echo "Iterating through arguments using \$@:"
for arg in "$@"; do
    echo "$arg"
done

# 执行一个命令并检查退出状态
ls /some/nonexistent/directory
exit_status=$?
if [ $exit_status -eq 0 ]; then
    echo "Command succeeded"
else
    echo "Command failed with exit status: $exit_status"
fi

# 输出前一个命令的退出状态
echo "Exit status of previous command: $?"

# 输出当前执行进程的进程ID
echo "Current process ID: $$"

$ bash script.sh arg1 arg2 arg3

Number of arguments: 3
Script name: script.sh
First argument: arg1
Second argument: arg2
Third argument: arg3
All arguments as a whole: arg1 arg2 arg3
Iterating through arguments using $@:
arg1
arg2
arg3
ls: cannot access '/some/nonexistent/directory': No such file or directory
Command failed with exit status: 2
Exit status of previous command: 2
Current process ID: <当前进程ID>

请注意,<当前进程ID> 是一个占位符,实际运行时将显示当前执行进程的进程ID。

3>位置参数

位置参数是指在Shell脚本中传递给脚本的命令行参数的值,它们按照其出现的顺序进行编号。在Shell脚本中,可以使用特殊变量 $1$2$3 等来引用这些位置参数。

假设我们有一个名为 script.sh 的Shell脚本,我们可以在命令行中传递参数给它:

$ bash script.sh arg1 arg2 arg3

在脚本中,可以通过 $1$2$3 来访问这些位置参数的值。

#!/bin/bash

echo "First argument: $1"
echo "Second argument: $2"
echo "Third argument: $3"

输出:

First argument: arg1
Second argument: arg2
Third argument: arg3

4>环境变量

环境变量是在操作系统环境中定义的一些全局变量,可以影响程序的行为和系统的操作。在Shell脚本中,可以使用这些环境变量来获取系统的信息、配置程序的行为和传递数据。

以下是一些常见的环境变量及其作用:

  1. PATH:用于指定可执行程序的搜索路径。当你在命令行中输入一个命令时,操作系统会在PATH指定的路径下查找可执行文件。

  2. HOME:表示当前用户的主目录路径。通常用于存储用户的个人文件和配置。

  3. USERUSERNAME:表示当前登录用户的用户名。

  4. SHELL:表示当前用户所使用的Shell程序的路径。

  5. PWD:表示当前工作目录的路径。

  6. LANGLC_*:用于设置区域设置(Locale)和语言环境。

  7. TMPTEMP:表示临时文件所存放的路径。

  8. PS1:用于定义命令提示符的格式。

我们可以通过$变量名的方式来引用环境变量的值。例如,$PATH引用了PATH环境变量的值。

同时,也可以在脚本中使用export命令来定义和设置自己的环境变量。例如,export MY_VAR="Hello"将定义一个名为MY_VAR的环境变量,其值为Hello

四、shell程序和语句

一个shell语句由多条shell语句构成,shell语句包括三个类型:说明语句、功能性语句、和结构性语句。

1>说明性语句

即注释行,他可以在任何位置,可单独一行,也可在语句末尾行。以#号开头,到所在行的末尾结束,就是这句话不被执行。

2>功能性语句

shell中变量赋值具有一定的局限性,我们经常需要从外部获取变量的值,可采取键盘输入变量值。

(1)键盘读入变量值

read [-options] [variable...]

 -options 是可选的参数,用于指定read命令的行为。常用的选项包括:

  • -p prompt:用于指定一个提示符,显示给用户,等待用户输入。
  • -s:使输入的内容在终端上不可见(用于输入密码等敏感信息)。
  • -r:将用户输入的内容原样存储,不进行转义。
  • -a array:将连续的多个输入赋值给一个数组变量。
  • variable 是要接收用户输入值的变量名称。用户的输入将赋值给相应的变量。

例如

#!/bin/bash

read -p "Please enter your name: " name
echo "Hello, $name!"

也可以输入多个变量

#!/bin/bash

read -p "Please enter your first name and last name: " first last
echo "Hello, $first $last!"

(2)算术运算命令

它和C语言有所不同,他不能直接使用+-*/

他需要在命令前加expr命令,再使用加(+)减(-)乘(\*)整除(/)求模(%)

例如
result=`expr 10 + 5`   # 加法
result=`expr 10 - 5`   # 减法
result=`expr 10 \* 5`  # 乘法,需要使用反斜杠转义*
result=`expr 10 / 5`   # 除法
result=`expr 10 % 5`   # 取模

实例中 ` 为键盘左上角的反引号 【`】键

(3)test命令

test语句可测试三种对象:字符、整数、文件属性

test 命令可以以多种不同的方式使用,常见的用法是通过中括号 [ ] 或双括号 [[ ]] 进行条件判断。(注意:“ [ ”左边以及“ ] ”右边都需要加一个空格)

if [ condition ]; then
    # 条件满足时执行的代码块
fi

&字符串测试

s1 = s2 判断两个字符串的内容是否相同
s1! = s2 判断两个字符串的内容是否不相同
-z s 判断字符串s的长度是否为零
-n s 判断字符串s的长度是否不为零


注意:=和!= 两边有留有至少一个空格 否则就是赋值语句,永远为真。

&整数测试

a -eq b 判断两个数字是否相同
a -ne b 判断两个数字是否不相同
a -gt b 判断a是否大于b
a -ge b 判断a是否大于等于b
a -lt b 判断a是否小于b
a -le b 判断a是否小于等于b

&文件测试

  • -e file:判断文件是否存在。
  • -f file:判断文件是否为普通文件。
  • -L file :判断文件是否是软链接文件的操作符
  • -d file:判断文件是否为目录。
  • -r file:判断文件是否存在且可读。
  • -w file:判断文件是否存在且可写。
  • -x file:判断文件是否存在且可执行。
  • -s file:判断文件是否非空。

判断文件是否为空示例

ls file
exit_status=$?

if [ $exit_status -eq 0 ]; then
    echo "命令执行成功"
else
    echo "命令执行失败"
fi

3>结构性语句

结构性语句是指用于控制程序流程的语句,常见的结构性语句包括条件语句(if语句)、循环语句(for循环、while循环)和函数等

&条件测试语句

if [ condition ]

then
    # 执行条件满足时的代码块
else
    # 执行条件不满足时的代码块
fi

if [ $num -gt 10 ]; then
    echo "数字大于10"
else
    echo "数字不大于10"
fi

case expression in
    pattern1)
        # 匹配 pattern1 时执行的代码块
        ;;
    pattern2)
        # 匹配 pattern2 时执行的代码块
        ;;
    pattern3)
        # 匹配 pattern3 时执行的代码块
        ;;
    *)
        # 默认情况下执行的代码块
        ;;
esac

read -p "请输入一个数字:" num

case $num in
    1)
        echo "输入的是数字1"
        ;;
    2)
        echo "输入的是数字2"
        ;;
    3|4|5)
        echo "输入的是3、4或5"
        ;;
    *)
        echo "输入的是其他数字"
        ;;
esac

&循环语句

for 变量名 in 单词表

do
    # 执行循环体内的代码块
done

for i in 1 2 3 4 5; do
    echo "循环次数: $i"
done

while 命令或表达式

do
    # 执行循环体内的代码块
done

count=0

while [ $count -lt 5 ]; do
    echo "循环次数: $count"
    count=`expr $count + 1`
done
4>break与continue

break
使用 while、until、for 循环时,如果想提前结束循环(在不满足结束条件的情况下结束循环),可以使用 break 或者 continue 关键字。

break n
n 表示跳出循环的层数,如果省略 n,则表示跳出当前的整个循环。

#!/bin/bash
declare -i sum
for ((i=1; i<=100; i++))
  do
    sum+=i
    if [ $i -eq 10 ];then
      break;
    fi
  done
echo "The sum is: $sum"

continue
continue n
n 表示循环的层数:


如果省略 n,则表示 continue 只对当前层次的循环语句有效,遇到 continue 会跳过本次循环,忽略本次循环的剩余代码,直接进入下一次循环。
如果带上 n,比如 n 的值为 2,那么 continue 对内层和外层循环语句都有效,不但内层会跳过本次循环,外层也会跳过本次循环,其效果相当于内层循环和外层循环同时执行了不带 n 的 continue。

#!/bin/bash
declare -i sum
for ((i=1; i<=100; i++))
  do
    if [ $i -eq 10 ];then
      continue;
    fi
    sum+=i
  done
echo "The sum is: $sum"

五、shell函数

1>函数的定义格式

方式一

函数名()

{

        函数体

}

方式二

function 函数名()

{

        函数体

}

2>函数调用格式

方式一

value_name=`function_name arg1 arg2`

变量名=`函数名 参数1 参数2`

函数的所有标准输出都传递给了主程序的

 方式二

function_name arg1 arg2

函数名 参数1 参数2

echo $?        # $?上一个命令退出的状态

六、案例

一、案例一

#!/bin/bash
#若命令下无参数,将该目录下的文件复制到backup中去
#若命令下有一个参数,查找该文件是否在该文件夹中
if [ ! -d $HOME/backup ] #判断$HOME/backup 创建thenmkdir 
$HOME/backup
fi
flist=`ls` #将ls的运行结果赋值给flist
for file in $flist #遍历ls的结果
do
    if [ $# = 1 ] #若命令行下有1个参数
    then
        if [ $1 = $file ] #判断你传入的参数在该路径下若存在
        then
            echo "$file found";exit
        fi
    else #若命令下无参数
        cp $file $HOME/backup
        echo "$file copied"
    fi
done

#若命令下无参数,将该目录下的文件复制到backup中去

#若命令下有一个参数,查找该文件是否在该文件

二、案例二

#!/bin/bash 

#判断用户主目录下是否有file_dir dir_dir两个目录
#如果这两个目录存在询问是否删除这两个目录
#若用户输入Y删除目录创建新的file_dir和dir_dir目录
#如果输入的为N退出程序

#请用户输入一个路径,将这个路径下的文件拷贝到file_dir,目录拷贝到dir_dir

#统计拷贝文件以及目录的个数

for dir in $HOME/file_dir $HOME/dir_dir
do
	if [ -d $dir ]
	then
		read -p "是否删除目录$dir
		" OP
		case $OP in
			Y|y)
				rm -rf $dir 
				mkdir $dir
		echo "创建$dir成功"
				;;
			N|n)
				exit
				;;
		esac
	else #文件不存在
		make $dir
		echo "创建$dir成功"
	fi
done

read -p "请输入一个绝对路径
" path

NUM1=0
NUM2=0
Flist=`ls $path` #显示文件夹中的文件和目录
for file in $Flist 
do
	if [ -f $path/$file ]
	then
		cp $path/$file $HOME/file_dir 
		NUM1=`expr $NUM1 + 1`
		echo "$file copied"
	elif [ -d $path/$file ]
	then
		cp -r $path/$file $HOME/dir_dir
		NUM2=`expr $NUM2 + 1`
		echo "$file copied"
	fi
done
echo "文件有$NUM1个,目录有$NUM2个"

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值