bash shell 入门

发布于:2025-08-18 ⋅ 阅读:(16) ⋅ 点赞:(0)

shell命令解析器, 将shell命令解释称linux 内核可以理解的指令. redhat系列主流使用/bin/bash.

修改环境变量所在的文件, 环境变量未生效. source file 刷新一下就生效了.

source 是 Shell 环境中的一个内置指令,主要用于 在当前 Shell 会话中直接执行脚本文件,而不是创建子 Shell 运行。它的核心作用是 修改当前 Shell 的环境变量或状态。

. source 命令 都是在当前shell执行. 可以获取设置的局部变量.

父子shell

开子shell与不开子shell的区别就在于,环境变量的继承关系,如在子shell中设置的当前变量,父shell是不可见的。

[root@aaaccbb bin]# ps -f
UID          PID    PPID  C STIME TTY          TIME CMD
root      413890  413889  0 09:55 pts/0    00:00:00 -bash
root      422690  413890  0 10:29 pts/0    00:00:00 ps -f
[root@aaaccbb bin]# bash # 进入子shell
[root@aaaccbb bin]# ps  -f
UID          PID    PPID  C STIME TTY          TIME CMD
root      413890  413889  0 09:55 pts/0    00:00:00 -bash
root      422740  413890  0 10:29 pts/0    00:00:00 bash
root      422796  422740  0 10:30 pts/0    00:00:00 ps -f
[root@aaaccbb bin]# exit
exit
[root@aaaccbb bin]# ps -f
UID          PID    PPID  C STIME TTY          TIME CMD
root      413890  413889  0 09:55 pts/0    00:00:00 -bash
root      423031  413890  0 10:31 pts/0    00:00:00 ps -f
[root@aaaccbb bin]# 

自定义变量.

# a = 2 #错误,不能有空格;  a=2,正确
#a="hello world"
#a='hello word'
# echo $a  #打印设置的局部环境变量
#export a   #提升为全局变量. 
#bash   #进入子shell
#a='2333' #修改变量
#echo $a  
2333
# exit  #退出子shell
# echo $a  #子shell变化, 其他shell看不到. 
hello world

source . 在当前shell执行, ./abc.sh在子shell执行

[root@aaaccbb bin]# new_var='12333'
[root@aaaccbb bin]# echo $new_var
12333
[root@aaaccbb opt]# vi abc.sh
[root@aaaccbb opt]# . abc.sh 
12333
[root@aaaccbb opt]# source abc.sh
12333
[root@aaaccbb opt]# chmod +x abc.sh
[root@aaaccbb opt]# ./abc.sh 

[root@aaaccbb opt]# cat abc.sh
#!/bin/bash

echo $new_var

常用shell

数值计算.

数值计算要用 $((expr)) 或者 $[expr ]
expr 也可, 一般不使用.

root@aaaccbb opt]# echo $((1+5))
6
[root@aaaccbb opt]# echo 1+5 # 默认作为字符串处理
1+5
[root@aaaccbb opt]# 


[root@aaaccbb opt]# expr 1 + 2  #一般不用expr
3
[root@aaaccbb opt]# expr 2 * 5
expr: syntax error: unexpected argument ‘abc.sh’
[root@aaaccbb opt]# expr 2 \* 5
10
[root@aaaccbb opt]# 

[root@aaaccbb opt]# echo $[5*2]
10
[root@aaaccbb opt]# echo $((5*2))
10
[root@aaaccbb opt]# 

只读变量

[root@aaaccbb opt]# readonly b=5
[root@aaaccbb opt]# b=10
-bash: b: readonly variable
[root@aaaccbb opt]# 

unset 撤销变量, readonly不可.

[root@aaaccbb opt]# name='12 45'
[root@aaaccbb opt]# echo $name
12 45
[root@aaaccbb opt]# unset name
[root@aaaccbb opt]# echo $name

[root@aaaccbb opt]# 

shell脚本文件读取参数

$0 打印脚本文件名,$1—$9,打印对应位置的参数, 但是必须使用双引号进行包裹,或者不用任何包裹. 使用单引号不能读取到值.

$1 获取第一个参数

绝对不能使用单引号进行包裹, 可以不进行任何包裹. 要进行字符串拼接 可以使用双引号进行包裹.

[root@aaaccbb opt]# ./hello.sh  xiaoli
hello $1
hello xiaoli
[root@aaaccbb opt]# 

[root@aaaccbb opt]# cat hello.sh
#!/bin/bash

echo 'hello $1' 
echo "hello $1" 
$0 获取脚本文件名
[root@aaaccbb opt]# ./hello.sh 
./hello.sh
[root@aaaccbb opt]# cat hello.sh 
#!/bin/bash

echo "$0"
$# 获取输入参数的个数
[root@aaaccbb opt]# ./hello.sh  1 2 3 4 5 '6   7'
6
[root@aaaccbb opt]# cat hello.sh  
#/bin/bash

echo "$0"

$* $@ 获取所有参数
[root@aaaccbb opt]# ./abc.sh  1 2 3
------------$@---------------
1
2
3
------------$*---------------
1 2 3
[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash

echo '------------$@---------------'
for para in "$@"
do
  echo $para
done

echo '------------$*---------------'
for para in "$*"
do
  echo $para
done

“$*” 所有的参数作为整体. 没有双引号引起来的时候,也是数组.
$@ 无论是否双引号包裹, 都是数组.

$? 获取脚本返回值 . 0正确 其他默认错误. 除非脚本有特殊return
查询变量

语法1: 直接使用变量名查询$var_name
语法2:便用花括号${var_name}
区别: 花括号方式适合拼接字符串


[root@aaaccbb opt]# name=zhangsan
[root@aaaccbb opt]# echo $name123

[root@aaaccbb opt]# echo ${name}123
zhangsan123
[root@aaaccbb opt]# 

test [ 语句 ] 判断返回值
[root@aaaccbb opt]# a=123
[root@aaaccbb opt]# test $a = 123
[root@aaaccbb opt]# echo $?
0
[root@aaaccbb opt]# test $a = 23
[root@aaaccbb opt]# echo $?
1
[root@aaaccbb opt]# [ a = 123 ]
[root@aaaccbb opt]# echo $?
1
[root@aaaccbb opt]# [ $a = 123 ]
[root@aaaccbb opt]# echo $?
0
[root@aaaccbb opt]# 
数值比较&&文件权限

在这里插入图片描述
在这里插入图片描述

[root@aaaccbb opt]# [ 2 gt 12 ]
-bash: [: gt: binary operator expected
[root@aaaccbb opt]# [ 2 -gt 12 ]
[root@aaaccbb opt]# echo $?
1
[root@aaaccbb opt]# [ -r abc.sh ]
[root@aaaccbb opt]# echo $?
0
[root@aaaccbb opt]# 

[root@aaaccbb opt]# [ -f abc.sh ]
[root@aaaccbb opt]# echo $?
0
[root@aaaccbb opt]# [ -d abc.sh ]
[root@aaaccbb opt]# echo $?
1
[root@aaaccbb opt]# 

[root@aaaccbb opt]# [ $a -lt 20 ] && echo  "$a < 20" || echo "$a >=20"
15 < 20

流程控制.

一行写多条语句要用;进行分割.
用if语句,就要用fi结尾.

if 使用

[root@aaaccbb opt]# if [ $a -ge 18 ] ;then echo OK ;fi
OK

[root@aaaccbb opt]# ./abc.sh 
[root@aaaccbb opt]# ./abc.sh atguigu
welcome dddd
[root@aaaccbb opt]# ./abc.sh 1111
[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash

if [ "$1"x = "atguigu"x ]
then echo 'welcome dddd'
fi
[root@aaaccbb opt]#        #添加上x,即使不输入, 也不会报错. 

[root@aaaccbb opt]# ./abc.sh  20
audit
[root@aaaccbb opt]# ./abc.sh  16
yong
[root@aaaccbb opt]# cat abc.sh
#!/bin/bash

if [ $1 -ge 18 ]
then
  echo "audit"
else
  echo "yong"
fi
[root@aaaccbb opt]# 


[root@aaaccbb opt]# ./abc.sh 14
yong
[root@aaaccbb opt]# ./abc.sh 40
audit
[root@aaaccbb opt]# ./abc.sh 60
old man
[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash

if [ $1 -lt 18 ]
then
  echo "yong"
elif [ $1 -ge 60 ]
then
  echo "old man"
else
  echo "audit"
fi
[root@aaaccbb opt]# 

两个同时作为 if 条件. 中间使用连接符进行拼接

-a 代表 and. -o 代表 or.

[root@aaaccbb opt]# if [ $a -ge 18 ] && [ $a -le 35 ] ; then echo OK; fi
[root@aaaccbb opt]# a=15
[root@aaaccbb opt]# if [ $a -ge 18 -a $a -le 35 ]; then echo ok; fi
[root@aaaccbb opt]# a=20
[root@aaaccbb opt]# if [ $a -ge 18 -a $a -le 35 ]; then echo ok; fi
ok
[root@aaaccbb opt]# 

case 多分支语句

在这里插入图片描述

[root@aaaccbb opt]# ./abc.sh  A
very good
[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash

case $1 in
"A")
  echo 'very good'
;;
"B")
  echo 'good'
;;
"C")
  echo 'ok'
;;
*)
 echo 'bad'
;;
esac
[root@aaaccbb opt]# 

for

[root@aaaccbb opt]# ./abc.sh  4
10
[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash

# 数值计算要用(())
for (( i=0; i <= $1; i++ ))
do
  sum=$[ $sum + $i ]
done
echo $sum
[root@aaaccbb opt]# 


[root@aaaccbb opt]# for os in windows linux macos ; do echo $os; done; 
windows
linux
macos
[root@aaaccbb opt]# 

[root@aaaccbb opt]# for i in {1..100}; do sum=$[ $sum + $i] ; done; echo $sum;
5050
[root@aaaccbb opt]# 

while

[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash
j=0
while [ $j -le $1 ]
do
  sum2=$[ $sum2 + $j]
  j=$[ $j + 1 ]
done

read 读取控制台输入.

在这里插入图片描述

[root@aaaccbb opt]# ./abc.sh 
please input your name: gch
welecome gch
[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash

read -t 10 -p "please input your name: " name
echo "welecome $name"
[root@aaaccbb opt]# 

内置函数

basename

basename 截取文件名(无论文件是否存在)

[root@aaaccbb opt]# basename ./abc.sh
abc.sh
[root@aaaccbb opt]# basename /opt/1111
1111
[root@aaaccbb opt]# 

[root@aaaccbb opt]# basename ./abc.sh .sh
abc 

[root@aaaccbb opt]# ./abc.sh 
abc
[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash

echo $( basename $0 .sh)

[root@aaaccbb opt]# 

通过帮助看一下就行了.

date

[root@aaaccbb opt]# ./abc.sh  it
it_1755332964.log
abc
[root@aaaccbb opt]# vi abc.sh 
[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash

echo "$1_$(date +%s).log"

echo $( basename $0 .sh)

[root@aaaccbb opt]# 

dirname

返回的内容和执行的命令有关系. 并且文件必须存在.

[root@aaaccbb opt]# dirname ./abc.sh
.
[root@aaaccbb opt]# dir /opt/aaaa/abc.aoe
dir: cannot access '/opt/aaaa/abc.aoe': No such file or directory
[root@aaaccbb opt]# dir /opt/aaa.sh
dir: cannot access '/opt/aaa.sh': No such file or directory
[root@aaaccbb opt]# dir /opt/abc.sh
/opt/abc.sh
[root@aaaccbb opt]# 

自定义函数

在这里插入图片描述

[root@aaaccbb opt]# ./abc.sh 
input first number:1
input second number:3
sum is: 4
[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash


function sum(){

 sum=$[ $1 + $2 ]
  echo  "sum is: $sum"

}

read -p  "input first number:" a
read -p  "input second number:" b

sum $a $b
[root@aaaccbb opt]# 

获取函数返回值

默认返回值0-255之间, 要获取函数返回值, 需要通过下面的方式进行解决.

[root@aaaccbb opt]# cat abc.sh 
#!/bin/bash


function sum(){

 sum=$[ $1 + $2 ]
  echo $sum 

}

read -p  "input first number:" a
read -p  "input second number:" b

sumx=$(sum $a $b)
echo "sumx: $sumx"
echo $[ $sumx * $sumx]
[root@aaaccbb opt]# ./abc.sh 
input first number:300
input second number:400
sumx: 700
490000
[root@aaaccbb opt]# 

备份

传入要备份的文件目录, 通过定时任务备份到/root/archive/.

编写执行备份的脚本文件 daily_archive.sh

记得添加执行权限. chomod +x daily_archive.sh

[root@aaaccbb opt]# ./daily_archive.sh /uploadPath

DEST_PATH:/root/archive/archive_250817.tar.gz
SOURCE_DIR:/uploadPath

备份完成
[root@aaaccbb opt]# ls -alt /root/archive
总用量 594900
-rw-r--r--   1 root root 609162386 8月  17 10:13 archive_250817.tar.gz
drwxr-xr-x   2 root root      4096 8月  17 10:13 .
dr-xr-x---. 12 root root      4096 8月  17 09:56 ..
[root@aaaccbb opt]#
[root@aaaccbb opt]#
[root@aaaccbb opt]#
[root@aaaccbb opt]# cat daily_archive.sh
#!/bin/bash

# 判断参数数量是否为 1

if [ $# -ne 1 ]
then
        echo "参数数量必须为1"
        exit
fi

# 判断参数是否为文件夹
if [ -d  $1 ]
then
        echo
else
        echo
        echo "待归档路径必须为文件夹"
        exit

fi

# 定义归档的文件名称
DIR_NAME=$( basename $1 )
DIR_PATH=$( cd $(dirname $1); pwd )
DEST_PATH="/root/archive/archive_$(date +%y%m%d).tar.gz"

SOURCE_DIR="${DIRPATH}/${DIR_NAME}"

echo "DEST_PATH:$DEST_PATH"
echo "SOURCE_DIR:$SOURCE_DIR"


# 进行归档

tar -czf $DEST_PATH -C $SOURCE_DIR .

if [ $? -eq 0 ]
then
        echo
        echo "备份完成"
else
        echo "备份出错,请检查"

fi

exit
[root@aaaccbb opt]#

加入定时任务

[root@aaaccbb opt]# crontab -l
no crontab for root
[root@aaaccbb opt]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@aaaccbb opt]#

0 11 * * * /opt/daily_archive.sh /uploadPath

文本处理工具

grep awk sed.

正则表达式入门.

在这里插入图片描述

在这里插入图片描述

[root@aaaccbb archive]# cat /etc/passwd | grep ^a
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@aaaccbb archive]# cat /etc/passwd | grep ^ad
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@aaaccbb archive]#

[root@aaaccbb archive]# cat /etc/passwd | grep bash$
root:x:0:0:root:/root:/bin/bash
nacos:x:1000:1000::/home/nacos:/bin/bash
[root@aaaccbb archive]#

# 完全匹配. 
[root@aaaccbb opt]# cat /etc/passwd | grep ^adm:x:3:4:adm:/var/adm:/sbin/nologin$
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@aaaccbb opt]#

[root@aaaccbb opt]# cat daily_archive.sh | grep r..t
DEST_PATH="/root/archive/archive_$(date +%y%m%d).tar.gz"
[root@aaaccbb opt]#

[root@aaaccbb opt]# cat /etc/passwd | grep ro*t
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
[root@aaaccbb opt]#

#.*   任意字符出现任意次  匹配任意字符串(包括空串)
[root@aaaccbb opt]# cat /etc/passwd | grep ^r.*bash$
root:x:0:0:root:/root:/bin/bash
[root@aaaccbb opt]#

[root@aaaccbb opt]# cat /etc/passwd | grep ^r.*bash$
root:x:0:0:root:/root:/bin/bash
[root@aaaccbb opt]# cat /etc/passwd | grep ^r.*0.*bash$
root:x:0:0:root:/root:/bin/bash
[root@aaaccbb opt]# cat /etc/passwd | grep ^r.*1.*bash$
[root@aaaccbb opt]#

[root@aaaccbb opt]# cat /etc/passwd | grep r[a,o,c]ot
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@aaaccbb opt]#

特殊字符

  / 不需要转译.  $必须转译\$ 并且必须使用''包裹. 
[root@aaaccbb opt]# cat daily_archive.sh | grep '/\$'
SOURCE_DIR="${DIRPATH}/${DIR_NAME}"
[root@aaaccbb opt]#

正则匹配手机号.

开头1.
第二位为: 3,4,5,7,8
剩下9位随便.

{} 必须使用 -E, 指定使用了正则扩展.

[root@aaaccbb opt]# echo "15552535666" | grep -E ^1[345678][0-9]{9}
15552535666
[root@aaaccbb opt]# echo "15552535666" | grep ^1[345678][0-9]{9}
[root@aaaccbb opt]#

cut 对文本进行数据的剪切

cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut命令从文件的每一
行剪切字节、字符和字段并将这些字节、字符和字段输出。
在这里插入图片描述


[root@aaaccbb opt]# cat aaa.txt 
shen guang
zhen dong
wo wo
lai lai
le le
[root@aaaccbb opt]# 

[root@aaaccbb opt]# cut -d " " -f 1 aaa.txt
shen
zhen
wo
lai
le
[root@aaaccbb opt]# 


[root@aaaccbb opt]# cut -d " " -f 2,3 aaa.txt
guang
dong
wo
lai
le
[root@aaaccbb opt]# 

[root@aaaccbb opt]# cat /etc/passwd | cut -d “:” -f 1,6-7

切割获取ip地址
[root@aaaccbb opt]# ifconfig eth0 | grep netmask 
        inet 172.31.181.100  netmask 255.255.240.0  broadcast 172.31.191.255
[root@aaaccbb opt]# ifconfig eth0 | grep netmask | cut -d " " -f 10
172.31.181.100
[root@aaaccbb opt]# 

[root@aaaccbb opt]# ifconfig | grep netmask | cut -d " " -f 10
172.31.181.100
127.0.0.1
[root@aaaccbb opt]# 

awk

在这里插入图片描述
在这里插入图片描述

[root@aaaccbb opt]# cat /etc/passwd | grep ^root | cut -d ":" -f 7
/bin/bash
[root@aaaccbb opt]# 

[root@aaaccbb opt]# cat /etc/passwd | awk -F ":"  '/^root/print $7'
awk: 命令行:1: /^root/print $7
awk: 命令行:1:        ^ syntax error
[root@aaaccbb opt]# cat /etc/passwd | awk -F ":"  '/^root/{print $7}'
/bin/bash
[root@aaaccbb opt]# 

[root@aaaccbb opt]# cat /etc/passwd | awk -F ":"  '/^root/{print $1,$7}'
root /bin/bash
[root@aaaccbb opt]# cat /etc/passwd | awk -F ":"  '/^root/{print $1","$7}'
root,/bin/bash
[root@aaaccbb opt]# 


[root@aaaccbb opt]# cat /etc/passwd | awk -F ":"  '{print $1","$7}'
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin

[root@aaaccbb opt]# cat /etc/passwd | awk -F ":"  'BEGIN{print "begin"} {print $1","$7} END{print "end"}'
begin
root,/bin/bash
bin,/sbin/nologin
end

[root@aaaccbb opt]# cat /etc/passwd | awk -F ":" '{print $3+1}'
1
2
3
4

[root@aaaccbb opt]# cat /etc/passwd | awk -v i=4 -F ":" '{print $3+i}'
4
5
6
7

awk 提取ip地址

$x 空行不考虑.

[root@aaaccbb opt]# ifconfig | awk '/netmask/ {print $2}'
172.31.181.100
127.0.0.1
[root@aaaccbb opt]# 

awk 内置变量.

[root@aaaccbb opt]# awk -F ":" '{print "fileName:"FILENAME", row:"NR",column:"NF}' /etc/passwd
fileName:/etc/passwd, row:1,column:7

[root@aaaccbb opt]# ifconfig | grep -n ^$
9:
18:
[root@aaaccbb opt]# 

[root@aaaccbb opt]# ifconfig | awk '/^$/{print NR}'
9
18
[root@aaaccbb opt]# 

参考地址

3天搞定Linux,1天搞定Shell,清华学神带你通关


网站公告

今日签到

点亮在社区的每一天
去签到