shell学习

Shell 指令

  • 什么是shell:shell本质是用户与操作系统之间的交互界面。它既是一个命令行解释器,也是一个脚本语言。
  • 作用:Shell 是用户与操作系统内核(Kernel)之间的桥梁。它允许用户通过命令行或脚本与操作系统进行交互,执行各种任务,如文件管理、程序运行、系统配置等。

一、基础操作指令

1.1 文件操作

  • 文件类型标识bcd-lsp(普通文件、块设备、字符设备、目录、符号链接、套接字、管道)
  • 常用命令
    `ls`:查看目录内容(`-l`显示详情,`-h`友好单位,`-a`显示隐藏文件)
    `chmod`:修改权限(`rwx`对应421)
    `touch`:创建文件
    `mkdir`:创建目录
    `rm`:删除(`-r`递归删除目录)
    `cat`:打印文件内容
    

1.2 重定向与管道

  • 操作符
    >   # 覆盖重定向(例:echo "hello" > file.txt)
    >>  # 追加重定向(例:echo "world" >> file.txt)
    |   # 管道符(例:cat file.txt | grep "error")
    

1.3 文件操作

  • 复制与移动
    `cp -r dir1 dir2`  # 递归复制目录
    `mv old.txt new.txt`  # 重命名文件
    `mv file.txt /target`  # 移动文件
    

二、虚拟机网络配置

2.1 网络连接检查

  ```bash
  `ping www.baidu.com` #测试网络连通性
  `ifconfig` #(Ubuntu)查看IP地址
  `ipconfig` #(Windows)查看IP地址
  ```

2.2 网络模式

  • 桥接模式:Ubuntu与主机独立IP(适用于网络编程)
  • NAT模式:共享主机IP(默认推荐)
  • 主机模式:仅主机与虚拟机通信,无外网

2.3 IP地址查看

  • Ubuntu:ifconfiginet字段
  • Windows:ipconfig中IPv4地址

三、在线下载(APT)

  1. 软件源配置
    • 替换为国内源(清华、阿里等)
    • 备份并编辑/etc/apt/sources.list
    • 替换后更新:sudo apt-get update
  2. 软件管理
    • 安装:sudo apt-get install 软件名
    • 卸载:sudo apt-get remove 软件名(保留配置)
    • 彻底卸载:sudo apt-get purge 软件名
    • 下载安装包:sudo apt-get download 软件名
    • 清理缓存:sudo apt-get clean

四、离线安装(DPKG)

  1. 安装包格式

    • .deb(Ubuntu)与.rpm(Red Hat)
  2. 命令操作

    • 安装:sudo dpkg -i 安装包.deb
    • 卸载:sudo dpkg -P 软件名(删除配置)
    • sudo dpkg -r 软件名(不删除配置)
  3. 依赖问题

    • 离线安装需手动解决依赖(在线自动处理)

五、文件处理指令

  1. 内容查看
    • head -n 文件名:显示前n行,(默认10行)
    • tail -n 文件名:显示后n行,(默认10行)
  2. 搜索与过滤
    • find 路径 -name "模式"(支持通配符*?[]
    • grep "模式" 文件:查找字符串在文件中的位置(支持正则表达式)
  3. 文本处理
    • cut -d分隔符 -f字段(剪切字符串)
    • wc统计行/词/字符数(-l行,-w词)
  4. 权限与属性
    • chgrp修改文件所属组
    • chown修改文件所有者

六、链接文件ln

  1. 硬链接文件
    • ln 源文件名 链接文件名
    • 硬链接文件是普通文件(-
    • 硬链接文件的inode值相同
    • 修改任意硬链接文件内容,其余文件内容也改变
    • 目录文件无法创建硬链接
  2. 软连接
    • ln -s 源文件绝对路径 链接文件绝对路径
    • 软连接文件的文件类型是链接文件l
    • 软链接文件的inode值不同
    • 修改任意硬链接文件内容,其余文件内容也改变
    • 删除源文件后相同路径创建同名文件,链接关系重新生效
    • 允许目录文件创建软链接

七、压缩/解压/归档/拆包

  1. 压缩
    • xz 文件名:生成一个*.xz压缩包
    • bzip2 文件名:生成一个*.bz2压缩包
    • gzip 文件名:生成一个*.gz压缩包
  2. 解压
    • unxz 文件名
    • bunzip2 文件名
    • gunzip 文件名
  3. PS:
    • 压缩效率:xz > bzip2 > gzip
    • 压缩时间:xz > bzip2 > gzip
    • 压缩后原文件会被删除
  4. 归档/拆包
    • tar -cvf *.tar 目标文件/目录:归档不会删除原文件
    • tar -xvf *.tar 目标文件/目录:解包
      • -c:归档
      • -x:解包
      • -C:解包到目标目录
      • -v:显示过程
      • -f:操作文件
      • -J/-j/-z:归档并压缩xz/bz2/gz(解包时可以不加)

八、用户管理

  1. 信息查看
    • whoami:查看用户
    • id:查看用户id
  2. 用户切换
    • sudo su 用户名:切换用户
    • exit:退出当前用户
    • sudo passwd 用户名:修改用户密码
  3. 创建用户
    • sudo useradd 用户名:把用户添加到/etc/passwrod文件
    • sudo adduser:使用模板创建一个新用户
  4. 删除用户
    • sudo userdel 用户名:只从/etc/passwrod删除用户,不删除家目录
    • sudo deluser 用户名:从系统删除用户和模板,不删除家目录
    • sudo userdel 用户名 -r / sudo deluser 用户名 --remove-home:删除用户并删除家目录
  5. 权限及信息修改
    • sudo vim etc/sudoers:添加用户sudo权限(用户名 ALL=(ALL) ALL)
    • usermod -l 新用户名 用户名 :修改用户名
    • usermod -c 描述信息 用户名 :修改用户描述信息
    • usermod -m -d 新目录 原名字 :修改用户家目录
  6. 组操作
    • groupadd 组名:创建一个新的组,组文件/etc/group
    • addgroup 用户名 组名:将用户添加到组
    • groupdel 组名:删除一个组
    • delgroup 用户名 组名:将用户从组中删除

九、电源指令

  1. shutdown
    • shutdown 10:10分钟后关机
    • shutdown 10:00:10点关机
    • shutdown now:立刻关机
      • --show:显示关机动作和时间
      • -r:重启
      • -c:取消关机

十、磁盘指令

  1. 磁盘信息查看
    • df /dev/**:查看/dev/**的使用情况
      • -lh:查看磁盘的情况,单位KMG
      • -a:查看磁盘的情况,显示大小为0的
  2. 挂载
    • mount 磁盘分区 挂载点:将磁盘挂载到挂载点
    • umount 挂载点:取消挂载
  3. 磁盘操作
    • fdisk 物理磁盘路径:对磁盘进行分区等操作
    • mkfd.格式 分区路径: 用目标格式格式化磁盘

十一、shell script脚本

11.1 解释器

  • 常见的解释器:bash/sh/dash/csh/ksh
    • echo &SHELL/cat /etc/shells:查看解释器
  1. shell脚本
    • vim *.sh:创建shell脚本
    • shell脚本通常是以一个#!起始的文本文件如下
       #!/bin/bash 
      
    -这被称为shebang特殊行,在这行中字符#!被置于解释器路径之前,/bin/bash是解释器Bash的路径
    • 使用bash *.shsource *.sh./*.sh运行脚本文件(运行前需要修改文件权限,赋予可执行权限)
  2. 快速执行环境配置
    • 可以使用env命令查看环境变量
    • 打开~/.bashrc文件配置环境变量
        export PATH=$PATH:/……
        #让目标路径下的shell脚本可以在终端使用文件名快速执行,修改仅对当前用户有效
      
    • 打开/etc/bash.bashrc文件配置环境变量
        export PATH=$PATH:/……
        #让目标路径下的shell脚本可以在终端使用文件名快速执行,修改仅对所有用户有效
      
    • 打开/etc/environment文件配置环境变量
        #在目标文件的PATH变量后添加指定路径,用':'分割
        #让目标路径下的shell脚本可以在终端使用文件名快速执行,修改仅对所有用户有效
      

11.3 debug 方法

  • 使用解释器的选项来确认语法错误,这里以bash为例子

  • 使用解释器内置的选项来调试

    bash [-nvx] scripts.sh
    
  • 选项

    • -n 不要执行,仅仅输出语法问题
    • -v 先输出脚本内容
    • -x 将使用到的script先输出到屏幕上
  • 在脚本中指定调试段落

    #!/bin/bash
    set -x
    echo "开始调试"
    # 调试代码
    set +x
    echo "结束调试"
    
  • 使用调试器(类似gdb)

    apt-get install bashdb
    bashdb script.sh
    

11.4 内置命令type

  • type [-tpa] name
    
    • 选项:
      • 不加任何选项与参数时,type 会显示出 name 是外部指令还是 bash 内置指令
      • -t 当加入 -t 参数时,type 会将 name 以下面这些字眼显示出他的意义:
        • file :表示为外部指令;
        • alias :表示该指令为命令别名所设置的名称;
        • builtin :表示该指令为 bash 内置的指令功能;
      • -p 如果后面接的 name 为外部指令时,才会显示完整文件名;
      • -a 会由 PATH 变量定义的路径中,将所有含 name 的指令都列出来,包含 alias

11.5 shell变量

  • shell变量是没有数据类型的,默认为字符串类型,且默认为全局变量

  • shell变量对操作环境会造成影响,如上文中的PATH变量,其决定了你能不能在任何目录下执行某个指令。例如使用ls时系统就是通过PATH变量中的路径来搜索指令的。

  • 变量定义及初始化:

     variabl=hello #variabl指定义的变量名
     variabl=      #注意书写赋值语句`=`两边不能有空格
     variabl="hello world" #当赋值中存在空格时需要使用双引号或者单引号
     variabl='hello world' #单引号中的字符仅为一般字符串
                           #双引号中的特殊字符可以保留其原本特性
    
     variabl_1=$variabl #使用变量进行赋值时需要用'$'符号
    
    
    • 在Linux环境中,使用{大写字母}设定的变量一般是系统内定需要的变量
  • 位置变量:

      $n   #类似于c语言mian函数的argv,其$0中会存储文件名
      $@   #表示所有位置参数,每个参数保持独立(即使包含空格)
      $*   #表示所有位置参数,所有参数整合为一个字符串,用空格分隔
      $#   #表示参数个数
      $$   #获取当前shell的PID
      $?   #获取上一个指令的执行结果,成功返回0,失败返回非0错误值
    
  • 输入/输出变量内容:

     #输出
     echo ${变量} 
     echo $变量
     echo hello world 
     echo -n #不输出换行符
     echo -e #允许用转义字符
    
     #输入
     #使用read进行输入时可以用空格或tab对输入值进行分隔,若输入换行则结束输入
     read a b c #可以一次性对多个变量进行定义并赋值
     read -p #显示提示信息
     read -n #输入变量字符数
     read -t #定时输入
     read -a #输入类型为阵列(数组)
     read -s #加密输入
    
  • 特殊符号

      unset variabl #取消变量
      readonly variabl #设置变量为只读,无法修改值且无法取消
      local variabl #局部变量
      export variabl #将变量转变为环境变量,使其可以在子程序中使用
    
  • 指令输出转换

      #在想使用指令的输出值进行赋值等操作时可以使用反单引号或$(指令)
      a=`指令`
      a=$(指令)
    
  • 字符操作:

      ${#string} #计算字符长度
      string=$str1$str2 #将str1和str2两个字符拼接赋值给string
    
      #字符串截取
      ${string:m} #从左往右,截取第m个后的所有字符
      ${string:m:n} #从左往右,截取第m个后的n个字符
    
      ${string:0-m} #从右往左,截取第m个后的所有字符
      ${string:0-m:n} #从右往左,截取第m个后的n个字符
    
      ${string#*/} #从左往右,截取第一个'/'后的所有内容
      ${string##*/} #从左往右,截取最后一个'/'后的所有内容
    
      ${string%*/} #从右往左,截取第一个'/'后的所有内容
      ${string##*/} #从右往左,截取最后一个'/'后的所有内容
    
  • shell数组:

      #数组定义
      arr={1 2 3 hello world} 
    
      #稀疏数组
      arr[0]=1
      arr[4]=2 #sehll支持稀疏数组,该数组就含2个元素
    
      #数组拼接
      c=(${a[@]}${b[@]})
      c=(${a[*]}${b[*]}) #使用${arr[@]}或${arr[*]}可以输出/获取全部数组元素
    
      #数组长度
      ${#arr[@]}
      ${#arr[*]}
    

11.6 sehll运算

  • -shell中数据默认为字符串类型,擅长字符串,文件等操作

      ((c=a+b)) c=$((a+b))
      c=$[a+b]
      let c=a+b #以上三种运算方式都支持任意整数运算
    

expr指令
  • 在 Bash 中,expr 是一个非常有用的命令,用于进行算术运算、字符串操作和逻辑判断。以下是 expr 的主要用法和一些示例:
算术运算:expr 可以执行基本的算术运算,包括加法、减法、乘法、除法和取模。
算术运算符
  • 运算符说明示例输出
    +加法expr 5 + 38
    -减法expr 5 - 32
    *乘法expr 5 \* 315
    /除法expr 5 / 31
    %取模(余数)expr 5 % 32
  • 注意:乘法运算符 * 需要用反斜杠 \ 转义,否则会被 Shell 误认为是通配符。

字符串操作
  • expr 可以对字符串进行操作,包括匹配、截取和比较。
字符串操作符
  • 运算符说明示例输出
    match匹配字符串expr "abc123" : 'abc\([0-9]*\)'123
    index查找字符在字符串中的位置expr index "abc123" '1'4
    substr截取字符串expr substr "abc123" 4 3123
    length获取字符串长度expr length "abc123"6
  • 注意 match 时尽量加括号,否则返回的是则会返回匹配的字符的个数,若没有匹配则返回 0

逻辑判断

expr 可以进行逻辑判断,返回值为 0(假)或 1(真)。

逻辑运算符
  • 运算符说明示例输出
    =判断是否相等expr 5 = 30
    !=判断是否不相等expr 5 != 31
    <判断是否小于expr 5 < 30
    <=判断是否小于等于expr 5 <= 30
    >判断是否大于expr 5 > 31
    >=判断是否大于等于expr 5 >= 31
关系运算

expr 还支持布尔运算,包括逻辑与(&)、逻辑或(|)和逻辑非(!)。

关系运算符
  • 运算符说明示例输出
    &逻辑与expr 1 = 1 & 2 = 21
    ``逻辑或`expr 1 = 1
    !逻辑非expr ! 1 = 10
注意事项
  1. 空格expr 的参数之间必须有空格,否则会报错。
  2. 转义:某些特殊字符(如 *&)需要用反斜杠 \ 转义。
  3. 整数运算expr 只支持整数运算,不支持浮点数。
  4. 输出格式expr 的输出是字符串,而不是数字。
test指令
  • test 命令用于检查文件属性、字符串、数字等条件,通常在shell脚本中使用。它有两种写法:
    `test expression`
    `[ expression ]` 
    
  • test 命令可以检查文件的存在性、类型和权限等。
    #两种写法等价
    #检查文件是否存在
    test -e /path/to/file
    [ -e /path/to/file ]
    
    #检查是否为普通文件
    test -f /path/to/file
    
    #检查是否为目录
    test -d /path/to/directory
    
    #检查文件权限
    test -r /path/to/file
    test -w /path/to/file
    test -x /path/to/file
    
  • test 命令可以检查字符串的长度和内容。
    #检查字符串是否为空
    test -z "string"
    
    #检查字符串是否非空
    test -n "string"
    
    #检查两个字符串是否相等
    test "str1" = "str2"
    
  • test 命令可以对整形数字进行关系运算
    test $a -gt $b  # 大于
    test $a -lt $b  # 小于
    test $a -eq $b  # 等于
    

11.7 控制语句

判断
if判断
if [ 判断条件 ] 
then
   语句
   if [ 判断条件 ] ; then
   语句
   elif [判断条件] ; then
   语句
   else
   语句
   fi
   语句 
fi
#注意在判断符号之后需要有分号`;`,否则then需要换行
#判断条件里不能写`$(())`,只能写`(())`和`()`
case in判断
   case ${变量} in
   "字符串1")
      语句;;
   "字符串2"|"字符串3")
      语句;;
   *) #default
      语句;;
   esac
#使用 `|` 来连接多个匹配项
#使用 `;;` 来跳过后续的匹配
#可以使用通配符来匹配值

循环
while [condition] #条件成立时进循环
do
   程序
done

until [condition] #条件不成立时进循环
do
   程序
done

select var in 迭代器 #请注意这里会把var的值赋值成迭代器里的某个值,交互式cli用的
do                   #运行后需要使用`ctrl+c`或`ctrl+d`退出循环
   程序
done

# for循环的两种写法
for var in 迭代器
do
   程序
done

for ((i=1;i<=$1>;i++))
do
   程序
done

循环跳转
break n  #跳出n层循环
         #n为1时可以省略

continue n #结束n次循环,进入n+1次循环
           #n为1时可以省略

11.8 函数

函数定义
#shell函数格式
funtion aa()
{
   函数体
}

funtion aa
{
   函数体
}

aa()
{
   函数体
}


#调用
   aa


#sehll函数定义时 funtion 和 () 可以省略其一
#()仅代表函数,不允许添加参数
#函数调用后无需加()

函数传参
#sehll函数传参需要借助位置变量和预定义变量 `$n $* $@ $#`

funtion 函数名()
{
   $0  #文件名
   $1  #参数1
   $2  #参数2

   $@  #所有参数
   $*  #所有参数
   $#  #参数个数

}

函数名 参数1 参数2 参数3 ……

函数返回
  • Bash 函数的返回值本质是一个 退出状态码(范围 0-255),通过 return 或函数最后一条命令的退出状态决定:
return返回
   function check_file() {
    if [ -f "$1" ]; then
        return 0  # 文件存在,返回成功
    else
        return 1  # 文件不存在,返回失败
    fi
   }

   check_file "/etc/passwd"
   echo "Status: $?"  # 输出上一个命令的退出状态码(0 或 1)


   #隐式返回最后一条命令的状态
   function is_user_root() {
      [ "$(id -u)" -eq 0 ]  # 检查是否为 root 用户,最后一条命令的退出状态决定返回值
   }

   is_user_root
   echo "Is root? $?"  # 0=是root,1=不是

通过标准输出返回
  • 若需返回字符串、数字等复杂数据(而非状态码),需通过 echo 或 printf 输出结果,调用者用 $(…) 或反引号捕获
#返回字符串
   function get_date() {
      echo "Today is $(date)"
   }

   result=$(get_date)  # 捕获函数的输出
   echo "$result"      # 输出:Today is Fri Apr 12 10:00:00 UTC 2024


#返回多个值
   function parse_url() {
      local url="$1"
      echo "${url%%/*}"  # 返回协议(如 http:)
      echo "${url##*/}"  # 返回路径最后一部分
   }

   read -r protocol path <<< "$(parse_url "http://example.com/path")"
   echo "Protocol: $protocol, Path: $path"

结合返回
  • 若需同时返回状态码和数据,可通过以下方式:
   function process_data() {
      local input="$1"
      if [ -z "$input" ]; then
         echo "Error: Input is empty" >&2  # 错误信息输出到 stderr
         return 1
      else
         echo "${input^^}"  # 转换为大写并输出到 stdout
         return 0
      fi
   }

   output=$(process_data "hello")
   if [ $? -eq 0 ]; then
      echo "Processed: $output"  # 输出:Processed: HELLO
   else
      echo "Failed to process."
   fi


注意事项
    1. 作用域限制:函数内定义的局部变量需用 local 声明,否则会污染全局作用域。返回值无法直接返回数组或复杂对象,需通过字符串拼接或全局变量传递。
    1. 捕获输出的陷阱:若函数内有其他 echo 语句(如日志),会被一并捕获,建议错误信息输出到 stderr(>&2)。
    1. 状态码范围:return 的值必须在 0-255 之间,超出会取模(如 return 256 实际返回 0)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值