bash编程基础

119 阅读5分钟

Shell是什么?

  • shell不仅是命令行,也可以是GUI
  • shell是操作系统和用户交互的“接口”
  • 一般来说,shell是unix shell,也可以认为是CLI

命令是什么?

  • 命令本质是一个程序
  • 这些程序具有发起系统调用(system call)的能力
  • 编写shell脚本,就是编排这些程序的执行
  • shell语法解析器负责一行一行的解析shell命令

常用的shell解释器

  • bash
  • sh
  • zsh
  • cmd
  • powerShell
  • Wsl(window subsystem of linux )

常见bash命令有哪些

  • 文件新建

    • touch 新建文件
    • mkdir 新建目录
  • 文件删除

    • rmdir 删除文件夹

    • rm

      • rm ./single-file 删除单个文件
      • rm -r ./a-dir 递归删除(删除目录)
      • rm -rf ./a-dir-with-file 递归强制删除
  • 文件移动

    • mv

      • mv ./source/a.txt ./target
      • mv -f ./source/a.txt ./target 移动并强制覆盖同名文件
      • mv -n ./source/a.txt ./target 移动并不覆盖同名文件
      • mv -n ./source/a.txt ./source/b.txt 重命名
    • cp

      • cp ./source/a.txt ./target 复制
      • cp -R ./source/ ./target/ 递归复制(复制目录)
  • 文件查看

    • cat cat ./package.json 查看文件
    • head head -n ~/.logs/service-a.log查看文件的前10行
    • tail tail -n ~/.logs/service-a.log 查看文件的后10行
  • 文件编辑

    • nano

      nano是Linux上最简单的文本编辑器,操作简单,功能也比较初级

    • vi / vim

      vi是一款功能强大的编辑器,vim是vi的加强版

  • 进程相关

    • ps

      • ps 查看当前登录用户的进程
      • ps -ax 查看所有进程
    • lsof

      • lsof 查看所有网络相关文件
      • lsof -p 2333 查看pid=2333的进程打开的文件
    • top 显示实时的进程状态

    • kill

      • kill pid 杀死进程
      • kill -9 pid 强杀进程

      kill命令实际上并不是真的去杀死进程,本质是想进程发送信号。例如 kill -s SIGUSR1 34534 实际上可以调用node应用,因为node会在SIGUSR1进入调试模式。

      优雅退出的原理就是监听SIGTERM信号,并递归退出子进程。

      kill -9 发送SIGKILL信号,容易导致进程没有完成自己的清理工作就已经退出,出现僵尸进程。

  • 其他

    • grep 对结果的每一行进行筛选

      • lsof -i | grep LISTEN 找到所有被监听的端口,当不知道哪些端口被占用时,可以使用
    • awk 对结果列的筛选

      • docker rm (docker ps -a | awk 'NR>1 {print 1}') 删除所有docker容器

bash编程基础

全局变量

 COURSE=ENGINEERING
 export COURSE=ENGINEERING

可以不用export =两边不能有空格

局部变量

 local COURSE=ENGINEERING

函数内部才有用

环境变量

 $PATH:指定命令的搜索路径
 $HOME:指定用户的主工作目录(即用户登录Linux系统时候的默认目录)
 $HISTSIZE:指保存历史命令记录的条数
 $LOGNAME:指当前用户的登录名
 $HOSTNAME:指主机的名称
 $SHELL:指当前用户用的哪种Shell
 $LANG/$LANGUGE:和语言相关的环境变量,使用多种语言的用户可以修改此环境变量
 $MAIL:指当前用户的邮箱存放目录

变量基本类型

 #String
 ASTRING=abcdefg
 ASTRING="hello"
 ​
 #Number  不能直接使用数字 否则会被认为是字符串
 ANUMBER=$[1 + 1]
 ANUMBER=$(( 1 + 1 ))
 ​
 #Array
 AARRAY=(what's the day today)
 AARRAY=(1 2 3 4 5)
 AARRAY[1]=0
 ## zsh下标起始为1 bash下标起始为0

运算

组合
 ASTRING=world
 ANUMBER=2
 #####
 STR="Hello $ASTRING"
 echo $STR
 # Hello world
 SEQ=(1 $ANUMBER 3 4)
 echo $SEQ
 # 1 2 3 4
数学运算符
 ANUMBER=$(1 + 2)
 ANUMBER=$(1 - 2)
 ANUMBER=$(1 * 2)
 ANUMBER=$(1 / 2)

条件语句

if then
 if condition1
 then 
   command1
 elif condition2
 then 
   command2
 else 
   commandN
 if
case
 case $VAR in 
   condition1)
     command1
     ;;
   condition2)
     echo command2
     ;;
   *)
     echo command3
     ;;
 esac
比较符
 -z var            #检查变量var是否为空
 -d file           #检查file是否存在并是一个目录
 -e file           #检查file是否存在
 -f file           #检查file是否存在并为一个文件
 -r file           #检查file是否存在并可读
 -s file           #检查file是否存在并非空
 -w file           #检查file是否存在并可写
 -x file           #检查file是否存在并可执行
 -O file           #检查file是否存在并属于当前用户
 -G file           #检查file是否存在并默认组与当前用户相同
 file1 -nt file2   #检查file1是否比file2新
 file1 -ot file2   #检查file1是否比file2旧

举个例子

 ## 判断是否是一个文件
 if [ -f "./file"]
 then echo "it's a file"
 else echo "it's a dir"
 fi
for循环
 for index in 1 2 3 4 5;do
   echo "index="$index
 done
 ​
 for ((i=0; i<5; i++));do
   echo $i
 done
while循环
 while(($i<=10));do
   echo $i
 done

函数

函数的定义
 function custom_echo() {
   local prefix="input is"
   # $n 表示传入的第n个实参
   # 此处判断是否有参数$1传入
   if [ -z $1 ];then
     echo "no input"
   else
     echo "$prefix $1"
   fi
   return 0
 }
函数的调用与返回值
 custom_echo     #unkonw
 custom_echo abc #input is abc
 custom_echo abc #input is abc
 echo $?         #0

shell状态码,是shell运行每个命令都使用状态码(exit status)来告诉shell它完成了处理。退出状态码是一个0-255之间的整数值,在命令执行结束时由命令传入给shell。可以在命令执行结束后,立即使用$?捕获。

其他特殊变量
 $#  #传递到脚本或函数的参数个数
 $*  #以一个单字符串显示所有向脚本传递的参数  
 $$  #脚本运行的当前进程id
 $!  #后台运行的最后一个进程的id号
 $@  #与$*相同,但是使用时加引号,并在引号中返回每个参数
 $-  #显示shell使用的当前选项,与set命令功能相同
 $?  #显示最后命令的退出状态码。0表示没有错误,其他任何值表示有错误

重定向

什么是重定向?
  • 重定向,全程是I/O重定向,默认情况下,bash程序从终端接收输入,并在终端打印输出(标准输入、标准输出)
  • 如果你想改变输入的来源,或是输出的目的地,那么就需要使用"重定向"

怎么使用

只需要记住四个符号

 command > file  #将输出重定向到file
 command < file  #将输入重定向到file
 command << file #将输入重定向到file的部分内容
 command >> file #将输出以追加的方式重定向到file
 ls > ./ls.log   #将ls命令的输出记录在./ls.log文件中(重复会被覆盖)
 ls >> ./ls.log  #将不会被覆盖,而是在末尾追加

交互式程序

  • echo / read
 echo "xxx"      #打印并换行
 echo -n "xxx"   #打印且不换行
 read var        #读取输入,存入变量var
 read -n 1 var   #读取输入的第1个字符,存入变量var

举例:

 echo -n "What's your first name?";\
 read firstName;\
 echo -n "What's your second name?";\
 read secondName;\
 echo "$firstName $secondName";

编写一个bash命令,每次输入文件夹名称,直到退出

function cdAndLs() {
    cd $1;
    ls;
}

function getPackageName() {
    echo -n "input packageName...";\
    read packageName;\
    return 0;
}


getPackageName;
echo $packageName;
while [ -d $packageName ];do
    cdAndLs $packageName;
    getPackageName;
done;
echo "this is a file;"