Linux shell

2023-05-16

目录

shell 脚本

shell 概述

shell 分类 

shell 语法

shell 脚本的定义与执行

自定义变量

环境变量 

预设变量

脚本变量的特殊用法

条件测试语句->文件

条件测试语句->字符串

条件测试语句->数字

控制语句

函数


shell 脚本

shell 概述

shell 是用户和 Linux 内核之间的接口程序

Linux 系统中提供了好几种不同的 shell 命令解释器,如 sh、ash、bash 等。一般默认使用 bash 作为默认的解释器。

shell 分类 

系统调用脚本 

/etc/profile
此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行,系统的公共环境变量在这里设置开始自启动的程序,一般也在这里设置

~/.bashrc 
用Home目录的.bashrc,登录时会自动调用,打开任意终端时也会自动调用这个文件一般设置与个人用户有关的环境变量,如交叉编译器的路径等

用户调用脚本

用户编写的脚本

shell 语法

shell 脚本的定义与执行

1、定义以开头:#!/bin/bash,#!用来声明脚本由什么 shell 解释,否则使用默认 shell

2、单个"#"号代表注释当前行 

3、执行:

./test.sh 
bash test.sh 直接指定使用 bash 解释 test.sh
. test.sh 使用当前 shell 读取解释 test.sh

自定义变量

定义变量
变量名=变量值
如:num=10

引用变量
$变量名 
如:i=$num 把变量 num 的值赋给变量 i

显示变量
使用 echo 命令可以显示单个变量取值
echo $num

清除变量
使用 unset 命令清除变量
unset varname

read string
从键盘输入一个字符串付给变量 string

readonly var=100
定义一个只读变量,只能在定义时初始化,以后不能改变,不能被清除。

export var=300
使用 export 说明的变量,会被导出为环境变量,其它 shell 均可使用 

等号两边不能直接接空格符,若变量中本身就包含了空格,则整个字符串都要用双引号、或单引号括起来;

双引号内的特殊字符可以保有变量特性,但是单引号内的特殊字符则仅为一般字符。 

var.sh

#!/bin/bash
echo "this is the var test shell script "

name="edu"
echo "$name is me"
echo '$name is me'

echo "please input a string"
read string 
echo "the string of your input is $string"

readonly var=1000
#var=200
export public_var=300

环境变量 

方法1:临时设置
在终端执行命令

SELF_VAL=999
export SELF_VAL

方法2:永久设置
需要在配置文件(~/.bashrc或/etc/profile)中进行设置即可,设置完毕后需要通过source命令配置文件立即生效

#!/bin/bash

echo "You are welcome to use bash"
echo "Current work dirctory is $PWD"
echo "the host name is $HOSTNAME"
echo "your home dir $HOME"
echo "Your shell is $SHELL"
echo "user env val is $SELF_VAL"

执行结果

richard@rich:~/workspace$ ./export.sh 
You are welcome to use bash
Current work dirctory is /home/richard/workspace
the host name is rich
your home dir /home/richard
Your shell is /bin/bash
user env val is 999

预设变量

$#:传给shell脚本参数的数量
$*:传给shell脚本参数的内容
$1、$2、$3、...、$9:运行脚本时传递给其的参数,用空格隔开
$?:命令执行后返回的状态,"$?":用于检查上一个命令执行是否正确(在Linux中,命令退出状态为0表示该命令正确执行,任何非0值表示命令出错)。
$0:当前执行的进程名
$$:当前进程的进程号

pre.sh 

#! /bin/bash

echo "\$1 = $1"
echo "\$2 = $2"
echo "\$5 = $5"
echo "\$6 = $6"
echo "\$7 = $7"
echo "\$8 = $8"
echo "\$9 = $9"

# if more than 9, must use {}
echo "\${10} = ${10}"
echo "\${11} = ${11}"
echo "\${12} = ${12}"

# 传给shell脚本参数的数量
echo "\$# = $#"

# 传给shell脚本参数的内容
echo "\$* = $*"

# 命令执行后返回的状态
echo "\$? = $?"

# $0:当前执行的进程名
echo "\$0 = $0"

# 获取当前进程的进程号
echo "\$$ = $$"

执行结果

richard@rich:~/workspace$ ./pre.sh 12 13 14 15 a b c d e f g h
$1 = 12
$2 = 13
$5 = a
$6 = b
$7 = c
$8 = d
$9 = e
${10} = f
${11} = g
${12} = h
$# = 12
$* = 12 13 14 15 a b c d e f g h
$? = 0
$0 = ./pre.sh
$$ = 129085

脚本变量的特殊用法

""(双引号):包含的变量会被解释
''(单引号):包含的变量会当做字符串解释
``(数字键1左面的反引号) :反引号中的内容作为系统命令,并执行其内容,可以替换输出为一个变量 

richard@rich:~/workspace$ echo "today is `date` "
today is 2023年 03月 20日 星期一 16:31:30 CST
\ 转义字符 : 同c语言 \n \t \r \a等 echo命令需加-e转义
(命令序列) :由子 shell 来完成,不影响当前 shell 中的变量
{ 命令序列 } : 在当前 shell 中执行,会影响当前变量
#!/bin/bash

name="zhangsan"
#双引号里面的特殊字符,会使用其特殊含义
string1="good moring $name"
#单引号里面的特殊字符,都会失去特殊含义
string2='good moring $name'
echo $string1
echo $string2
echo "-------------------------------"

#反引号:获取一个shell命令的输出结果,一般对有输出结果的命令经常去使用,也可以使用$()与反引号等价
echo "today is date"
echo "today is `date`"
echo 'today is `date`'
echo "-------------------------------"

echo "My dir ls command result: $(ls)"
echo "-------------------------------"
#转义字符:使用时,需要在echo后面加上‐e选项

num=100
#由子shell来完成,不会改变shell中的变量的值
( num=999;echo "in 1 $num" )
echo out 1:$num
echo "-------------------------------"

#在当前shell中执行,会改变shell中的变量的值
{ num=666; echo "in 2 $num"; }
echo out 2:$num
echo "-------------------------------"

条件测试语句->文件

按照文件类型
-e 文件名 文件是否存在
-s 文件名 是否为非空
-b 文件名 块设备文件
-c 文件名 字符设备文件
-d 文件名 目录文件
-f 文件名 普通文件
-L 文件名 软链接文件
-S 文件名 套接字文件
-p 文件名 管道文件

按照文件权限
-r 文件名 可读
-w 文件名 可写
-x 文件名 可执行


两个文件之间的比较
文件 1 -nt 文件 2 文件 1 的修改时间是否比文件 2 新
文件 1 -ot 文件 2 文件 1 的修改时间是否比文件 2 旧
文件 1 -ef 文件 2 两个文件的 inode 节点号是否一样,用于判断是否是硬链接

#!/bin/bash
# -e 文件名 文件是否存在
test -e /dev/qaz
echo $?
echo "--------------------------"

# -e 文件名 文件是否存在
test -e /home
echo $?
echo "--------------------------"

# -d 文件名 目录文件
test -d /home
echo $?
echo "--------------------------"

# -r 文件名 可读
# -w 文件名 可写
# -x 文件名 可执行

mkdir test_sh
chmod 500 test_sh
[ -r test_sh ]
echo $?
[ -w test_sh ]
echo $?
[ -x test_sh ]
echo $?
[ -s test_sh ]
echo $?
echo "--------------------------"

条件测试语句->字符串

s1 = s2    测试两个字符串的内容是否一样
s1 != s2    测试两个字符串的内容是否不一样
-z s1    测试 s1 字符串的长度是否为 0
-n s1    测试 s1 字符串的长度是否不为 

#!/bin/bash
test -z $yn
echo $?

echo "please input a yn"
read yn

[ -z "$yn" ]
echo 1:$?

[ $yn = "y" ]
echo 2:$?

条件测试语句->数字

a -eq b        测试 a 与 b 是否相等
a -ne b        测试 a 与 b 是否不相等
a -gt b        测试 a 是否大于 b
a -ge b        测试 a 是否大于等于 b
a -lt b        测试 a 是否小于 b
a -le b        测试 a 是否小于等于 b

#!/bin/bash
echo "please input a num(1-9)"
read num

[ $num -eq 5 ]
echo $?

[ $num -ne 5 ]
echo $?

控制语句

if 控制语句

格式一:
if [ 条件 1 ]; then
    执行第一段程序
else
    执行第二段程序
fi

格式二:
if [ 条件 1 ]; then
    执行第一段程序
elif [ 条件 2 ];then
    执行第二段程序
else
    执行第三段程序
fi

if_then.sh

#!/bin/bash
echo "Press y to continue"
read yn

if [ $yn = "y" ]; then
    echo "script is running..."
else
    echo "stopped!"
fi

case 控制语句

case $变量名称 in
        “第一个变量内容”) 
                程序段一
                ;; 
        “第二个变量内容”) 
                程序段二
                ;; 
        *) 
                其它程序段
                exit 1 
esac

case1.sh

#!/bin/bash

echo "This script will print your choice"

case "$1" in
    "one")
        echo "your choice is one"
        ;;

    "two")
        echo "your choice is two"
        ;;
	
    "three")
        echo "Your choice is three"
        ;;
    *)
        echo "Error Please try again!"
        exit 1
        ;;
esac

case2.sh

#!/bin/bash
echo "Please input your choice:"
read choice

case "$choice" in
    Y | yes | Yes | YES)
    echo "It's right"
    ;;

    N* | n*)
    echo "It's wrong"
    ;;
    *)

    exit 1
esac

for 控制语句

形式一

for (( 初始值; 限制值; 执行步阶 ))
do 
    程序段
done

for1.sh

#!/bin/bash

# declare 是 bash 的一个内建命令,可以用来声明 shell 变量、设置变量的属性。
# declare 也可以写作 typeset。

declare -i s 
declare -i sum

for (( i=1; i<=100; i=i+1 ))
do
    sum=sum+i
done

echo "The result is $sum"

形式二
for var in con1 con2 con3 ...
do
    程序段
done

for2.sh

#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9
do
    echo $i
done

for3.sh

#!/bin/bash

for name in `ls`
do

if [ -f $name ];then
    echo "$name is file"
elif [ -d $name ];then
    echo "$name is directory"
else
    echo "other"
fi

done

while 控制语句

while [ condition ]
do 
    程序段
done

当 condition 成立的时候进入 while 循环,直到 condition 不成立时才退出循环。

_while.sh

#!/bin/bash
declare -i i
declare -i s

while [ "$i" != "101" ]
do
    s+=i;
    i=i+1;
done

echo "The count is $s"

unitl 控制语句

until [ condition ]
do
    程序段
done

这种方式与 while 恰恰相反,当 condition 成立的时候退出循环,否则继续循环。

#!/bin/bash

declare -i i
declare -i s

until [ "$i" = "101" ]
do
    s+=i;
    i=i+1;
done

echo "The count is $s"

函数

定义函数的两种格式:

格式一:
函数名() { 
    命令 ... 

格式二:
function 函数名() { 
    命令 ... 
}

函数可以放在同一个文件中作为一段代码,也可以放在只包含函数的单独文件中
所有函数在使用前必须定义,必须将函数放在脚本开始部分,直至 shell 解释器首次发现它时,才可以使用
调用函数的格式为:
    函数名 param1 param2 ……
使用参数同在一般脚本中使用特殊变量
    $1 $2 ...$9 一样
函数可以使用 return 提前结束并带回返回值
    return 从函数中返回,用最后状态命令决定返回值。
    return 0 无错误返回
    return 1 有错误返回
#!/bin/bash
is_it_directory()
{
    if [ $# -lt 1 ]; then   
        echo "I need an argument" 
        return 1
    fi

    if [ ! -d $1 ]; then
        return 2
    else
        return 3
    fi
}

echo -n "enter destination directory:"
read direct

is_it_directory $direct

echo "the result is $?"

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux shell 的相关文章

  • 如何将一个文本文件拆分为多个 *.txt 文件?

    我有一个文本文件file txt 12 MB 包含 something1 something2 something3 something4 有没有办法分开file txt分成 12 个 txt 文件 比方说file2 txt file3 t
  • 在Java中执行.lnk文件

    我需要在java中执行 lnk文件 指向exe文件的lnk文件 我能怎么做 在 VB net 中我做 Process Start path 它有效 谢谢你的帮助 Use a 流程构建器 http download oracle com ja
  • 如何获取与 shell 中的文件名模式匹配的所有文件的总文件大小?

    我正在尝试仅使用 shell 来计算与文件名模式匹配的所有文件 在目录树中 的总大小 以字节为单位 这是我到目前为止所拥有的 find name undo exec stat c s awk 总计 1 END 打印总计 有没有更简单的方法来
  • 使用脚本检查 git 分支是否领先于另一个分支

    I have branch1 and branch2我想要某种 git branch1 isahead branch2 这将显示如果branch1已承诺branch2没有 也可能指定这些提交 我无法检查差异原因branch2 is在之前br
  • 如何从 Bash 命令行在后台 Vim 打开另一个文件?

    我正在从使用 Gvim 过渡到使用控制台 Vim 我在 Vim 中打开一个文件 然后暂停 Vim 在命令行上运行一些命令 然后想返回到 Vim Ctrl Z 在正常模式下 暂停 Vim 并返回到控制台 fg可用于将焦点返回到 Vim job
  • 有哪些基于对象的 shell?

    我打算写一个面向对象的shell 基于Python 我已经有很多想法了 但在实现它之前 我想通过一些现有的 shell 来激发我的灵感 我所说的面向对象的基本意思是 参数不仅仅是字符串数组 而且是对象数组 返回值也是一个对象 不仅有 std
  • Linux shell 从用户输入中获取设备 ID

    我正在为一个程序编写安装脚本 该程序需要在其配置中使用 lsusb 的设备 ID 因此我正在考虑执行以下操作 usblist lsusb put the list into a array for each line use the arr
  • 退出代码大于 255 — 可能吗?

    如果是 在哪个操作系统 shell 或其他操作系统上 考虑以下 Java 程序 我使用 Java 只是作为示例 任何语言都适合这个问题 这更多地与操作系统有关 public class ExitCode public static void
  • 使用 libusb 输出不正确

    我用libusb编写了一个程序 我怀疑输出是否正确 因为所有条目都显示相同的供应商和产品 ID 以下是代码 include
  • 正则表达式删除块注释也删除 * 选择器

    我正在尝试使用 bash 从 css 文件中删除所有块注释 我有以下 sed 命令的正则表达式 sed r s w s w d 这可以很好地去除块注释 例如 This is a comment this is another comment
  • Python 脚本:每次打印新行到 shell,而不是更新现有行

    说到Python 我是个菜鸟 我有一个 python 脚本 它给我这样的输出 last ZVZX W3vo9I Downloading video webpage last ZVZX W3vo9I Extracting video info
  • 来自守护程序的错误响应:加入会话密钥环:创建会话密钥:超出磁盘配额

    我尝试在我的服务器上安装 docker 使用本教程 https docs docker com install linux docker ce ubuntu 我想远程运行 docker 镜像并使用 portainer Web 界面来管理一切
  • Ubuntu Python shebang 线不工作

    无法让 shebang 线在 Ubuntu 中为 python 脚本工作 我每次只收到命令未找到错误 test py usr bin env python print Ran which python usr bin python 在 sh
  • Python 3.4.3 subprocess.Popen 在没有管道的情况下获取命令的输出?

    我试图将命令的输出分配给变量 而不让命令认为它正在通过管道传输 原因是 如果正在通过管道传输 则相关命令会给出未格式化的文本作为输出 但如果从终端运行 则会给出颜色格式化的文本 我需要获取这种颜色格式的文本 到目前为止我已经尝试了一些事情
  • 在 bash 中添加(收集)退出代码

    我需要依赖于脚本中的几个单独的执行 并且不想将它们全部捆绑在一个丑陋的 if 语句中 我想使用退出代码 每次执行并添加它 最后 如果这个值超过阈值 我想执行一个命令 伪代码 ALLOWEDERROR 5 run something RESU
  • awk 在循环中使用时不打印任何内容[重复]

    这个问题在这里已经有答案了 我有一堆使用 file 1 a 1 txt 格式的文件 如下所示 A 1 B 2 C 3 D 4 并使用以下命令添加包含每个文件名称的新列 awk print FILENAME NF t 0 file 1 a 1
  • 在 docker 中重定向命令输出

    我想为我的服务器做一些简单的日志记录 它是一个在 Docker 容器中运行的小型 Flask 应用程序 这是 Dockerfile Dockerfile FROM dreen flask MAINTAINER dreen WORKDIR s
  • 在内核代码中查找函数的最佳方法[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我开始浏览内核代码 遇到的一件事是如何跟踪函数调用 结构定义等 有没有一种好的方法可以快速跳转到函数定义并退出 我尝试过 Source N
  • Bash:递归复制命名文件,保留文件夹结构

    我希望 cp R src prog js images icon jpg tmp package 将在目标目录中产生对称结构 tmp package src prog js images icon jpg 但相反 这两个文件都被复制到 tm
  • shell中如何分割字符串

    我有一个变量作为 string ABC400p2q4 我怎样才能分开ABC400 and p2q4 我需要将它分成两个变量 结果我得到 echo var1 ABC400 echo var2 p2q4 可以用任何字母字符代替 ABC 可以用任

随机推荐

  • [513]linux设置开机自启动

    文章目录 自启动方法1自启动方法2方法3 xff1a 在 96 etc rc d init d 96 目录下添加自启动脚本关机要执行的命令 自启动方法1 1 权限编辑 etc rc d rc local cd etc rc d vim rc
  • 个人网页制作(教你制作简单网页)

    我相信很多人或多或少都曾想建立一个个人网站吧 xff0c 或分享生活瞬间 或分享学习心得 或者是分享技术文章 又或者是有其他想法 xff08 打造个人ip 商业变现或是其他 xff09 今天跟大家分享一下一般网站的搭建流程 xff0c 对建
  • 程序员学习能力提升三要素

    IT技术的发展日新月异 xff0c 新技术层出不穷 xff0c 具有良好的学习能力 xff0c 能及时获取新知识 随时补充和丰富自己 xff0c 已成为程序员职业发展的核心竞争力 多年的学习经验总结出了提高程序员学习能力的三个要点 学习人人
  • 基于linux下python的学习(文件操作、模块)

    一 文件操作 操作文件的函数 方法 在python中要操作文件需要记住的1个函数和3个方法 python中一切皆对象 open 打开文件 xff0c 并且返回文件操作对象 read 将文件内容读取到内存 write 将指定内容写入文件 cl
  • 制作Ubuntu 20.04.5 LTS (Focal Fossa)系统U盘的图文教程

    文章目录 前言 一 Ubuntu系统是什么 xff1f 二 下载ubuntu系统 1 打开对应的网站 三 开始制作系统U盘 1 格式化U盘 2 下载刻录软件UltraISO软件 3 用UltraISO软件加载ubuntu20 04 5的系统
  • android:onNewIntent

    本文编写目的 xff1a 供自己查阅 1 通过Intent启到一个Activity的时候 xff0c 就算已经存在一个相同的正在运行的Activity 系统也会创建一个新的Activity实例 为了不让Activity实例化多次 xff0c
  • fedora安装kde桌面

    yum install 64 KDE desktop
  • 怎么让图片在一个正方形div中不变形展示?且超出部分截取(隐藏),且截取图片的中间位置

    divContent width 200px height 200px border 1px solid red overflow hidden divContent img margin 0 padding 0 width 100 hei
  • [并行计算]Matlab并行计算工具箱(Parallel Computing Toolbox)官方文档教程中文版(1)

    Arranged By Zhonglihao 64 2018 请确认Matlab安装时点选了并行计算工具箱 第一章 xff1a parfor循环并行计算 parfor循环介绍 parfor循环是Matlab并行计算工具箱用于并行计算单循环的
  • xquartz Firefox Error: cannot open display: localhost:14.0

    应该是缺少localhost到127 0 0 1的映射 1 export DISPLAY 61 127 0 0 1 14 0 2 firefox OK
  • 百思不得姐之图片处理(保存与下载)

    一 功能图 二 讲解思路 1 回顾上一篇内容 2 创建加载图片类 同时创建xib 3 点击图片查看大图 4 点击查看大图 查看长图 5 model出展示图片的控制器 6 保存图片 7 封装根据网络状态展示不同的图片 三 回顾上一篇内容 1
  • CMake 学习

    目录 CMake学习网站 CMake安装 CMake编译程序 单个源文件的程序编译 在当前目录执行 cmake xff0c 执行结果 执行完成后的文件列表 使用GUN make来编译程序 得到可执行文件 hello 同目录下多源文件程序编译
  • dumpsys meminfo内存详解

    dumpsys meminfo使用方法帮助 adb shell dumpsys meminfo h meminfo dump options a d c s oom process a include all available infor
  • android恢复出厂设置,关机,重启以及系统升级和充电器连接广播

    恢复出厂设置 lt uses permission android name 61 34 android permission MASTER CLEAR 34 gt if Build VERSION SDK INT lt Build VER
  • Cmake系列(三) 在 CMakeLists.txt 引入第三方so库

    将 so 库和头文件拷贝到对应的目录 app src main jniLibs arm libxxx so 修改 CMakeLists txt 文件 第三方so库 这里和之前在第二步中介绍的创建一个新的原生库类似 xff0c 区别在于最后一
  • .net core MemoryCache(本机缓存)过期策略

    过期策略 1 1 永不过期 xff1a 永远不会过期 1 2 设置绝对过期时间点 xff1a 到期后就失效 1 3 设置过期滑动窗口 xff1a 只要在窗口期内访问 xff0c 它的过期时间就一直向后顺延一个窗口长度 1 4 滑动窗口 43
  • Windows asar工具安装使用与破解StarUml

    目录 安装nodejs 使用npm安装asar asar的压缩与解压 破解StarUml windows要破解StarUml xff0c 需要用到asar进行解压与打包 asar可以借助npm来安装 xff0c mac可以用homebrew
  • logcat中 读取垃圾回收消息

    目录 Dalvik 日志消息 ART 日志消息 有时 xff0c 发生垃圾回收事件时 xff0c 相应消息会输出到 Logcat 中 Dalvik 日志消息 在 Dalvik xff08 而不是 ART xff09 中 xff0c 每个 G
  • arm64-v8a、armeabi-v7a、armeabi、x86 abiFilters 详解

    abiFilters的作用 在app的gradle的defaultConfig里面加上如下 ndk abiFilters 34 armeabi v7a 34 指定要ndk需要兼容的架构 这样其他依赖包里mips x86 armeabi ar
  • Linux shell

    目录 shell 脚本 shell 概述 shell 分类 shell 语法 shell 脚本的定义与执行 自定义变量 环境变量 预设变量 脚本变量的特殊用法 条件测试语句 gt 文件 条件测试语句 gt 字符串 条件测试语句 gt 数字