Linux Shell程序设计

LInux Shell程序设计

将指定路径加到环境变量$PATH

PATH=$PATH:绝对路径
export PATH

一、变量

1.用户定义的变量

  • 给变量赋值时,等号左右不能有空格
  • $:访问变量
a=33
echo $a

只读变量

readonly a

公共变量

export a

显示变量

echo $a

清除变量

  • set : 显示所有本地定义的变量
unset a

2.shell定义的变量

  • 所有环境变量均为大写

设置环境变量

TEMPVAR=123
export TEMPVAR

显示环境变量

  • 查看所有环境变量
env

清除环境变量

unset TEMPVAR 

常用的shell环境变量

环境变量 含义
HOME 保存注册用户主目录的绝对路径名
PATH 保存路径(冒号分隔)
TERM 终端类型
UID 当前用户标识符
PWD 当前工作目录的绝对路径
PS1 主提示符 特权用户:# 普通用户:$
PS2 辅助提示符:>
IFS 缺省域分隔符 空格、tab
LOGNAME 保存登录名
SHELL 保存缺省shell /etc/passwd中设置

3.位置参数

$1:shell取第一个参数 从1开始
$0:表示当前执行shell程序名(不是位置参数)

4.预定义变量

  • 不能重定义
预定义变量 含义
$0 当前执行的进程名
$# 位置参数的数量
$* 所有位置参数的内容
$? 命令执行后返回的状态 0:成功 1:失败
$$ 当前进程的进程号
$! 后台运行的最后一个进程号

5.参数置换的变量

  • 中间没有空格
  • shell中不能为位置参数赋值
a=${b-200}
如果参数b有值则a=b,否则a=200
a=${b=200}
如果参数b有值则a=b,否则a=200,b=200
a=${b?info}
如果参数b有值则a=b,否则显示 info并退出,如果Info缺省则显示标准信息
a=${b+200}
如果参数b有值,则a=200,否则不置换

二、shell中的引用

1.双引号 “”

  • 不能消除 $ ,\ ,"",反引号`四种

2.单引号 ‘’

  • 消除单引号里面所有特殊字符的含义

3.反引号 `

  • 反引号里的内容作为系统命令
  • 输出变量为命令执行的结果

4.反斜杠 \

  • 屏蔽特殊含义

三、Shell脚本

  • 第一行:#!/bin/bash ——使用bshell解释器
  • 第二行:脚本名称
  • 注释:#

1.eval

  • eval args :将args组合成一个命令执行

2.exec

  • 执行完退出进程

3.export

  • 变量可以带到子shell

4.readonly

  • 将shell变量标识为不可变

5.read

  • 从标准输入设备读入一行,分解成若干字,赋值给shell程序内部定义的变量。

6.shift

  • 在程序中每使用一次shift语句,都使所有的位置参数依次向左移动一个位置,并使位置参数“$#”减1,直到减到0。

7.wait

  • shell等待在后台启动的所有子进程结束。wait的返回值总是真。

8.exit

  • 退出shell程序

9.source(等价于.)

  • 在当前shell环境下读入指定的shell程序文件并依次执行文件中的所有语句。
  • source 文件名(可以不拥有可执行权限)

10.":"空命令

  • 通常放在行的最左边,实际不作任何命令,只返回出口代码0

四、程序流程控制

1.测试命令

1. test "abc" = "def" #注意等号左右空格
2. [ "abc" = "def" ] #注意等号,括号左右空格
[ -z $HOME ] #真为0

=,!=,>,<
-z(字符串是否为空) 1:非空
-n(字符串是否非空)

文件测试

-e 文件名 :如果文件存在则为真
-r 文件名 :如果文件存在且可读则为真
-w 文件名 :如果文件存在且可写则为真
-x 文件名 :如果文件存在且可执行则为真
-s 文件名 :如果文件存在且非空则为真
-d 文件名 :如果文件存在且为目录则为真
-f 文件名 :如果文件存在且为普通文件则为真
-c 文件名 :如果文件存在且为字符型特殊文件则为真
-b 文件名 :如果文件存在且为块特殊文件则为真

逻辑操作符:

-a :逻辑与,操作符两边均为真,结果为真,否则为假。
-o :逻辑或,操作符两边一边为真,结果为真,否则为假。
! :逻辑否,条件为假,结果为真。

混合命令条件执行

使用&&:command1 && command2,这种命令执行方式相当地直接。&&左边的命令(command1)返回真(即返回0,成功被执行)后,&&右边的命令(command2)才能够被执行;

使用||:command1 || command2,||的作用有一些不同。如果||左边的命令(command1)未执行成功,那么就执行||右边的命令(command2);或者换句话说,“如果这个命令执行失败了|| 那么就执行这个命令”>

command1 && command2 && command3,当command1, command2成功时才执行command3 >

command1 && command2 || comamnd3,仅当command1成功,command2失败时才执行command3

2.流控制

两个(())表示执行c语言代码

2.1 if
if 条件1
             then 命令1
             elif 条件2
             then 命令2
             else 命令3
fi
  • if语句必须以单词fi
  • 必须将then部分放在新行
#!/bin/bash
var=$1
if [ $var \< "9" ]
then
   echo "less than 9"
else
   echo "more than 9"
fi

在这里插入图片描述

2.2 case
case "字符串变量" in

  值1)指令1...

;;

  值2)指令2...

;;

      ......

      *)指令3...
      ;;

esac
#!/bin/bash
var=$1
case $var in
	1)
		echo "1"
		;;
	2)
		echo "2"
		;;
	*)
		echo "others"
		;;
esac

在这里插入图片描述

2.3 for
for 变量 in 列表; 
do 
    循环体
done 
#!/bin/bash
# sum of 1 to 100
Sum=0
for i in {1..100};
do
let Sum=$Sum+$i
done
echo "Sum is $Sum"
2.4 while
while 条件(或命令);
do 
    循环体
done 
#!/bin/bash
# sum of 1 to 100
Sum=0
i=0
while ((i<10));
do
let Sum=$Sum+$i
let i=$i+1
done
echo "Sum is $Sum"
2.5 until 直到条件为真才停止循环
until [ 测试条件 ];
do
语句 #可以是多条语句
done
#!/bin/bash
# sum of 1 to 100
var=10
until [ $var -lt 1 ];
do
echo $var
var=$(($var-1))
done

练习1:cut
cut -d : -f 1 /etc/passwd | grep "user$i" 2>> /tmp/etc.err || sudo useradd user$i
##
cut:裁剪 -d:指定间隔符进行裁剪
1:裁剪的第一块
cut -d : -f 1 /etc/passwd:裁剪出第一列
2:表示出错
|:管道
||:逻辑或
grep "user$l":查找user i
##
#用:裁剪 /etc/passwd 内容取第一列 查找 useri 如果错误, 结果重定向到 /tmp/etc.err 如果执行不成功 增加用户 user1 
练习2:乘法表
#!/bin/bash
for((i=0;i<=9;i++))
do
for((j=1;j<=i;j++))
do
let k=i*j
echo -n "$i*$j=$k"
done
#换行
echo " "
done
  • echo -n: 不换行
    在这里插入图片描述

六、Shell命令分组

“()” 和 “{}”

一定注意{}里面的内容要有空格和分号

  • 用(command_list;)将一组命令括起来,则这些命令会由子shell来完成,能保证所有的改变只对子进程产生影响,而父进程不受任何干扰.
#!/bin/bash
echo "test ()"
NUMBER=1
(A=2;B=2;NUMBER=`expr $A + $B`;echo $NUMBER) 
echo $NUMBER
  • {command_list;}则在当前shell中执行。"{}"用于将顺序执行的命令的输出结果用于另一个命令的输入。
#!/bin/bash
echo "test {}"
NUMBER=1
{ A=2;B=2;NUMBER=`expr $A + $B`;echo $NUMBER; }
echo $NUMBER

在这里插入图片描述

七、Shell信号

  • kill –l 命令看到系统中全部可用的信号名

在这里插入图片描述
shell编程只需关心 1 2 3 15

  • 1 SIGHUP 挂起或父进程被杀死
  • 2 SIGINT 来自键盘的中断信号,通常是<CTRL-C>
  • 3 SIGQUIT 从键盘退出
  • 9 SIGKILL 无条件终止
  • 11 SIGSEGV 段(内存)冲突
  • 15 SIGTERM 软件终止(缺省杀进程信号)

1.trap 捕获信号

  • trap ‘commands’ signal-list
#!/bin/bash
#trap
trap "my_exit" 2
LOOP=0
my_exit()
{
echo "You just hit <CTRL-C>,at number $LOOP"
echo "I will now exit"
exit 1
}
while :
do 
LOOP=`expr $LOOP + 1`
echo $LOOP
done

信号2 SIGINT 来自键盘的中断信号
在这里插入图片描述

八、bash程序的调试

bash -x 程序名
  • -n:测试shell脚本语法结构,只读取shell脚本但不执行
  • -x:进入跟踪方式,执行命令时把命令和它们的参数显示出来
  • -e:非交互方式,如果一个命令失败就立即退出
  • -I:交互方式
  • -k:从环境变量中读取命令的参数
  • -r:限制方式,不能执行:cd, 更改PATH,指定全路径名,输出重定向操作
  • -t 执行命令后退出(shell exits)
  • -u 置换时把未设置的变量看作出错
  • -v verbose,当读入shell输入行时把它们显示出来

1.-x -v

  • 通常使用-x进行跟踪执行,执行并显示每一条指令。
  • "-v"选择项使shell在执行程序的过程中,把它读入的每一个命令行都显示出来,
  • "-x"选择项使shell在执行程序的过程中把它执行的每一个命令在行首用一个“+”加上命令名显示出来。并把每一个变量和该变量所取的值也显示出来。
  • 主要区别在于: “-v"打印出命令行的原始内容,而”-x"则打印出经过替换后的命令行的内容

算数运算

  • let expr 只能计算整数

let

  • 不用空格分开
  • 变量计算不用$

expr

  • 运算符两边要有空格
  • *乘法要转义\*
  • 外层要有反引号``

四、Linux函数库

  • 静态函数库:.a为后缀
  • 共享函数库:
发布了100 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_39827677/article/details/104905733