当前位置:   article > 正文

Shell基础_shell ps -ef|grep ^

shell ps -ef|grep ^

Shell

bash

#shell会话可以存储用户执行的命令,使用history查看
[root@master ~]# history | tail -n 10
  101  setenforce 0
  102  etenforce 
  103  getenforce 
  104  ping www.baidu.com
  105  shutdown now
  106  vim /etc/my.cnf 
  107  cat /etc/my.cnf 
  108  history 
  109  history | less
  110  history | tail -n 10
  
#变量HISTFILE是指存放历史命令的文本文件路径
[root@master ~]# echo $HISTFILE
/root/.bash_history
[root@master ~]# tail -n 10 /root/.bash_history 
ss -anlt
setenforce 0
getenforce 
yum -y install ncurses-compat-libs
mysql -uroot -p'sRgWy6inmT%2' -e "set password = password('sakura123');"
mysql -uroot -p'sRgWy6inmT%2' -e "set password = password('sakura123');" --connect-expired-password
mysql -uroot -psakura123
vim /etc/my.cnf 
systemctl restart mysqld.service 
mysql -uroot -psakura123
[root@master ~]# 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

#history命令
#一般使用-c和-r选项
-c //清空历史命令
-r [历史命令文件存放路径] //恢复历史命令

[root@master ~]# history -c
[root@master ~]# history 
    1  history 
[root@master ~]# history -r ~/.bash_history 
[root@master ~]# history | tail -n 5
  160  mysql -uroot -psakura123
  161  vim /etc/my.cnf 
  162  systemctl restart mysqld.service 
  163  mysql -uroot -psakura123
  164  history | tail -n 5
[root@master ~]# 

#调用历史命令
#![历史命令id]
[root@master ~]# history | tail -n 5
  162  systemctl restart mysqld.service 
  163  mysql -uroot -psakura123
  164  history | tail -n 5
  165  echo "123"
  166  history | tail -n 5
[root@master ~]# !165
echo "123"
123
[root@master ~]# 

#!!  //执行上一条命令
[root@master ~]# echo "123"
123
[root@master ~]# !!
echo "123"
123
[root@master ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

变量

变量只能以数字、字母、下划线开头,并且严格区分大小写

变量分为环境变量局部变量(环境变量和局部变量在后面单独分类详细说明)

环境变量也称为全局变量,不管是父shell还是子shell,都可以使用,例如之前安装中间件时经常会用的$PATH设置环境变量,环境变量也分为“自定义”和“内置”两种

局部变量一般用于脚本或函数里

#使用等号给变量复制,引用时要加上$
[root@master ~]# name="tom"
[root@master ~]# echo $name
tom
[root@master ~]# echo name
name
[root@master ~]# echo ${name}
tom
[root@master ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

父shell和子shell

[root@master ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
        ├─VGAuthService
        ├─agetty
        ├─auditd───{auditd}
        ├─crond
        ├─dbus-daemon───{dbus-daemon}
        ├─polkitd───5*[{polkitd}]
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd───sshd───sshd───bash───pstree  //现在是在bash中,也就是父shell
        ├─sssd─┬─sssd_be
        │      └─sssd_nss
        ├─systemd───(sd-pam)
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        ├─tuned───4*[{tuned}]
        └─vmtoolsd───3*[{vmtoolsd}]
[root@master ~]# bash
[root@master ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
        ├─VGAuthService
        ├─agetty
        ├─auditd───{auditd}
        ├─crond
        ├─dbus-daemon───{dbus-daemon}
        ├─polkitd───5*[{polkitd}]
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd───sshd───sshd───bash───bash───pstree  //输入bash,进入新的shell
        ├─sssd─┬─sssd_be
        │      └─sssd_nss
        ├─systemd───(sd-pam)
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        ├─tuned───4*[{tuned}]
        └─vmtoolsd───3*[{vmtoolsd}]
[root@master ~]# 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

在父shell中定义的变量,如果切换到子shell,是不会生效的,同理在子shell中定义的变量也无法在父shell中生效

每次执行脚本时,都会调用sh或bash解释器,所以不会保留当前shell的变量

但是如果使用“source”或“.”+符号,就会在当前shell加载

[root@test ~]# vim 1.txt 
[root@test ~]# cat 1.txt  //向1文件中写入一个定义变量的语句
#!/bin/bash

name=jerry
[root@test ~]# name=tom   //在当前shell中定义name为tom
[root@test ~]# bash 1.txt   //使用bash开启一个子shell执行脚本
[root@test ~]# echo $name   //打印name,还是tom,因为脚本执行是在子shell中,而不是父shell
tom
[root@test ~]# source 1.txt   //使用source执行,在当前的shell中执行
[root@test ~]# echo $name     //打印name,发现已经改变了,因为执行的是当前的shell
jerry
[root@test ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

引号

#单引号:无法识别特殊语法。只要是单引号中的内容,都会以字符串的形式处理,不会识别特殊符号和命令
[root@test ~]# name1=tom 
[root@test ~]# echo $name1
tom
[root@test ~]# name2="${name1}" //双引号可以识别到定义的name1变量,并将name1的值赋给name2
[root@test ~]# echo $name2
tom
[root@test ~]#

#双引号:可以识别特殊语法。能识别特殊字符以及命令,如果想在双引号中不识别,可以使用“\”反斜杠进行转义
[root@test ~]# name3='${name1}' //同样是赋值操作,单引号就无法读取到name1的值
[root@test ~]# echo $name3
${name1}
[root@test ~]# 

#反引号:识别命令,并将命令执行的结果传回给bash
[root@test ~]# name=`ls`
[root@test ~]# echo $name  //将ls执行的结果赋值给name
1.txt anaconda-ks.cfg mysql-5.7.34-linux-glibc2.12-x86_64.tar.gz passwd
[root@test ~]# 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

变量

本地变量

定义shell变量时,变量名不需要加$

本地变量只在当前shell生效,退出或进入新shell时,变量失效

环境变量

环境变量一般指的是使用export导出的变量,用于定义shell的运行环境,保证shell命令的正确执行。

环境变量可以在命令行界面中临时创建,但是退出当前shell或登录子shell后就会失效,如果想永久生效,需要修改环境变量配置文件。PATH只是环境变量的一种

#针对当前用户生效的配置文件:
[root@test ~]# ls ~/.bash_profile 
/root/.bash_profile
[root@test ~]# 
#针对远程用户生效的配置文件:
[root@test ~]# ls ~/.bashrc 
/root/.bashrc
[root@test ~]# 
#全局生效的配置文件:
[root@test ~]# ls /etc/profile
/etc/profile
[root@test ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

读取变量配置文件顺序:先加载全局配置文件,在加载/.bashrc,最后加载/.bash_profile。如果三个文件中定义的变量相同,以最后的~/.bash_profile为准

检查系统环境变量的命令

#set:输出所有的变量,包括全局变量和局部变量
[root@test ~]# name=tom
[root@test ~]# echo $name
tom
[root@test ~]# set | grep ^name
name=tom
[root@test ~]# 

#env:只显示全局变量
[root@test ~]# env | wc -l
29
[root@test ~]# 

#输出所有变量,等同于set
[root@test ~]# declare | wc -l
1578
[root@test ~]# set | wc -l
1578
[root@test ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

显示和设置环境变量:export

#unset取消变量或函数
[root@test ~]# echo $name
tom
[root@test ~]# unset name
[root@test ~]# echo $name

[root@test ~]# 

#readroly设置只读变量,当前shell失效时变量也失效
[root@test ~]# readonly password="123"
[root@test ~]# echo $password
123
[root@test ~]# password="123456"  //重新设置password时会提示该变量为只读变量
-bash: password: readonly variable
[root@test ~]# 

#export设置环境变量
[root@test ~]# export a=123
[root@test ~]# echo $a
123
[root@test ~]# export | wc -l  //列出所有的环境变量
27
[root@test ~]# 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

特殊变量

shell的特殊变量,主要用于脚本、函数参数传递中

$0:文件名
$1、2、3...n:参数(大于10后写为${10},参数中间用空格隔开)
$#:统计参数的个数
$*$@ :都表示传递给脚本的所有参数,当$*$@不被双引号包围时,没有任何区别,当被双引号包围时,$*会将所有参数看成一个整体,而$@是将每一个参数看成整体,例如:
"$*" : "a,b,c,d"

"$@" : "a"
"b"
"c"
"d"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
[root@test ~]# vim test1.sh
[root@test ~]# cat test1.sh 
#! /bin/bash

echo '打印 $0 $1 $2 $3的结果'
echo $0 $1 $2 $3
echo '------------------'


echo '打印 $#的结果'
echo $#
echo '------------------'

echo '打印 $*的结果'
echo $*
echo '------------------'


echo '打印 $@的结果'
echo $@

[root@test ~]# bash test1.sh w x b
打印 $0 $1 $2 $3的结果
test1.sh w x b  
------------------
打印 $#的结果
3
------------------
打印 $*的结果
w x b
------------------
打印 $@的结果
w x b
[root@test ~]# 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

特殊状态变量

$?:取出上一次命令的返回值,0为正确,非0错误
$$:当前shell的进程号
$!:上一次后台进程的PID
$_:取上一次命令的最后一个参数
  • 1
  • 2
  • 3
  • 4

示例:

// $?
[root@test ~]# ls passwd 
passwd
[root@test ~]# echo $?
0
[root@test ~]# ls sadadas
ls: cannot access 'sadadas': No such file or directory
[root@test ~]# echo $?   //查看不存在的文件时,报错,返回值为非0
2
[root@test ~]# 

// $$
[root@test ~]# echo $$  //可以放到脚本中,获取到的就是当前脚本的pid
1558
[root@test ~]# 

// $!
//先执行一个后台命令
[root@test ~]# nohup ping www.baidu.com & 1> /dev/null
[1] 1650
[root@test ~]# nohup: ignoring input and appending output to 'nohup.out'
[root@test ~]# 
[root@test ~]# echo $!
1650
[root@test ~]# ps -aux | grep ping
root        1650  0.0  0.2  55256  4780 pts/0    S    19:47   0:00 ping www.baidu.com
root        1653  0.0  0.0  12140  1064 pts/0    R+   19:49   0:00 grep --color=auto ping
[root@test ~]# 

// $_
[root@test ~]# bash test1.sh w x b 
打印 $0 $1 $2 $3的结果
test1.sh w x b
------------------
打印 $#的结果
3
------------------
打印 $*的结果
w x b
------------------
打印 $@的结果
w x b
[root@test ~]# echo $_  //取最后一个参数
b
[root@test ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

shell子串

bash内置命令

内置命令在所有的linux发行版里都能够识别

echo
eval
exec
export
read
shift
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

echo:

-n:不换行输出
-e:解析字符穿中的特殊符号
#特殊字符:
\n:换行
\r:回车
\t:制表符(四个空格)
\b:退格

#ecoh命令自带换行,输出多个echo可以用分号连接
[root@test ~]# echo "今天是星期一" ; echo "是雨天"
今天是星期一
是雨天
[root@test ~]# 
#加上-n就不会换行
[root@test ~]# echo -n "今天是星期一" ; echo "是雨天"
今天是星期一是雨天

#echo没加-e选项时不会识别特殊字符
[root@test ~]# echo "今天是星期一\n是雨天"
今天是星期一\n是雨天
[root@test ~]# echo -e "今天是星期一\n是雨天"
今天是星期一
是雨天
[root@test ~]# 

#除了echo打印,还有printf打印,printf会自动识别特殊字符
[root@test ~]# printf "今天是星期一\n是雨天\n"
今天是星期一
是雨天
[root@test ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

eval:

#执行多个命令,以分号隔开
[root@test ~]# eval echo "132" ; pwd
132
/root
[root@test ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5

exec

#执行完命令后自动exit退出
[root@test ~]# su - tom //切换到tom用户
Last login: Mon Mar 20 08:14:11 CST 2023 on pts/0
[tom@test ~]$ exec ls /tmp/   //执行ls后退出
vmware-root_928-2731217671  vmware-root_932-2722632322	vmware-root_941-4022177618  vmware-root_954-2722108059
vmware-root_929-3980167385  vmware-root_938-2689078411	vmware-root_943-4013723344
vmware-root_930-2722763397  vmware-root_939-4022308693	vmware-root_951-4013330126
[root@test ~]#   //回到了root用户

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

子串语法

${变量}  :返回变量值
${#变量}  :返回变量长度(字符长度)
${变量:start}  :(返回变量start之后的值,后面有具体案例便于理解)
${变量:start:length}  :(返回变量start之后的值,但是受限制于length)
${变量#test}  :(从变量开头删除最短匹配的test字串)
${变量##test}  :(从变量开头删除最长的test字串)
${变量%test}  :(从结尾删除最短的test)
${变量%%test}  :(从结尾删除最长的test)
${变量/test/test1}  :(将匹配到的第一个test替换为test1)
${变量//test/test1}  :(将匹配到的所有test替换为test1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

子串实际案例

#shell变量截取字符串通常有两种方式:从指定位置开始截取 和 从指定字符(子字符串)开始截取
[root@test ~]# name=sakura
[root@test ~]# echo $name
sakura

#输出变量
[root@test ~]# echo ${name}
sakura

#统计变量的长度(字符长度)
[root@test ~]# echo ${#name}
6

#根据索引截取start后的字符(start是指数字,索引是从0开始算,例如这里的sakura索引就是012345)
[root@test ~]# echo ${name:2}
kura

#根据索引截取字符串并指定长度
[root@test ~]# echo ${name:2:1}  
k

#删除子串 
[root@test ~]# name2="sakura sakura sakura"
[root@test ~]# echo ${name2}
sakura sakura sakura
#从头匹配,删除匹配到最短的s*a(*是通配符,表示任意长度的字符)
[root@test ~]# echo ${name2#s*a}
kura sakura sakura
#从头匹配,删除匹配到最长的s*a
[root@test ~]# echo ${name2##s*a}

[root@test ~]# 

#井号'#'表示从头匹配,'%'表示从尾匹配,用法与上面一样,此处就不做赘述


#将匹配到的第一个sak替换为abc
[root@test ~]# echo $name2
sakura sakura sakura
[root@test ~]# echo ${name2/sak/abc}
abcura sakura sakura

#将匹配到的所有sak替换为abc
[root@test ~]# echo ${name2//sak/abc}
abcura abcura abcura
[root@test ~]# 
#注意!替换不会修改原有变量
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

shell统计变量长度的命令

shell统计字符长度的方式有很多,但是效率最高速度最快的是echo ${#name}

#统计字符长度的命令

#通过管道符接wc命令的-L选项,意思为找出文本中最长的一行输出他的长度
[root@test ~]# echo ${name} | wc -L
6

#利用数值计算命令expr的length选项统计字符长度
[root@test ~]# expr length ${name}
6

#awk的length选项统计$0的长度
[root@test ~]# echo ${name} | awk '{print length($0)}'
6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

比较统计字符长度命令的速度

#time计算命令执行时长,seq -s以:为分隔符产生序列并赋值给x,打印x到黑洞中
#使用${#x}
[root@test ~]# time for n in {1..1000};do x=`seq -s ":" 100`;echo ${#x} &> /dev/null;done

real	0m1.042s  //实际运行时间
user	0m0.420s  //用户态执行时间
sys	0m0.438s      //内核态执行时间
[root@test ~]# 

#使用wc -L 命令
[root@test ~]# time for n in {1..1000};do x=`seq -s ":" 100`;echo ${x} | wc -L  &> /dev/null;done

real	0m2.343s
user	0m0.984s
sys	0m0.968s

#使用expr命令
[root@test ~]# time for n in {1..1000};do x=`seq -s ":" 100`;expr length ${name}  &> /dev/null;done

real	0m1.831s
user	0m0.799s
sys	0m0.718s

#使用awk
[root@test ~]# time for n in {1..1000};do x=`seq -s ":" 100`;echo ${name} | awk '{print length($0)}'  &> /dev/null;done

real	0m2.980s
user	0m1.212s
sys	0m1.363s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

可见,${#变量}统计字符长度最快

批量修改文件名

准备测试环境:

[root@test ~]# mkdir test
[root@test ~]# cd test/
[root@test test]# touch test{1..5}_linux.jpg
[root@test test]# touch test{1..5}_linux.png
[root@test test]# ls
test1_linux.jpg  test2_linux.jpg  test3_linux.jpg  test4_linux.jpg  test5_linux.jpg
test1_linux.png  test2_linux.png  test3_linux.png  test4_linux.png  test5_linux.png
[root@test test]# 

#现在要求去掉test目录下所有文件中的“linux”后缀
[root@test test]# for file_name in `ls /root/test/*_linux*`;do mv ${file_name} ${file_name//_linux/} ;done
[root@test test]# ls
test1.jpg  test1.png  test2.jpg  test2.png  test3.jpg  test3.png  test4.jpg  test4.png  test5.jpg  test5.png
[root@test test]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

shell扩展变量

#“:-”用法
[root@test ~]# name1=tom
[root@test ~]# echo $name1
tom
[root@test ~]# echo $name2

[root@test ~]# echo $name3

#解释:定义name1变量值为tom,name2和name3为空
[root@test ~]# name3=${name1:-jerry} && echo $name3
tom
#解释:当name1有值时,将name1的值赋给name3并且打印
[root@test ~]# name3=${name2:-jerry} && echo $name3
jerry
#解释:当name2为空时,将":-"后面的"jerry"赋给name3并且打印
[root@test ~]# echo $name1
tom
[root@test ~]# echo $name2

#注意!此处name2仍然为空,上面的操作只是将Jerry赋给了name3,不会赋给name2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
#“:=”用法
[root@test ~]# name1=tom
[root@test ~]# echo $name1 
tom
[root@test ~]# echo $name2

[root@test ~]# echo $name3

#解释:与上面一样,只给name1赋值,name2和name3为空
[root@test ~]# name3=${name1:=jerry} && echo $name3
tom
[root@test ~]# name3=${name2:=jerry} && echo $name3
jerry
#解释:":-"和":="的区别在于给name2赋值,":-"会跳过,":="会赋值
[root@test ~]# echo $name1
tom
[root@test ~]# echo $name2
jerry

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
#":?"用法
#用法比较简单,有值时返回值,没有值时返回问号后面的内容
[root@test ~]# name1=tom
[root@test ~]# echo $name1
tom
[root@test ~]# echo $name2

[root@test ~]# echo ${name1:?变量为空}
tom
[root@test ~]# echo ${name2:?变量为空}
-bash: name2: 变量为空
[root@test ~]# 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
#":+"用法
[root@test ~]# name1=tom
[root@test ~]# echo $name1 
tom
[root@test ~]# echo $name2

[root@test ~]# echo ${name1:+jerry}
jerry
[root@test ~]# echo ${name2:+jerry}

#解释:变量有值时,重新将加号后的文本赋给变量,如果变量没有值,就啥也不做
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

父子shell

执行脚本的三种方式:

1:source script 或 . script #在当前shell执行脚本,脚本中的变量不会在当前shell中失效
2:/bin/bash script #指定bash解释器执行脚本,开启子shell运行脚本
3:./script #与2一样都会开启子shell,变量只在子shell生效,会在当前shell失效
  • 1
  • 2
  • 3

父shell

判断当前是否在父shell

#方法一:使用pstree命令查看到如下内容就说明在父shell
[root@test ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
      .........
        ├─sshd───sshd───sshd───bash───pstree
      .........
[root@test ~]# 

#方法二:ps进程管理命令查看
[root@test ~]# ps -ef --forest 
root        1179     987  0 12:16 ?        00:00:00      \_ sshd: root@pts/0
root        1219    1179  0 12:16 pts/0    00:00:00          \_ -bash
root        1810    1219  0 17:16 pts/0    00:00:00              \_ ps -ef --forest
[root@test ~]# 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

子shell

#linux内置变量$BASH_SUBSHELL,如果是在当前shell执行的命令就会返回0,如果是开启子shell执行,就会返回非0
[root@test ~]# echo $BASH_SUBSHELL
0
[root@test ~]# (cd /opt/ ; (cd /root/) ;echo $BASH_SUBSHELL)
1
[root@test ~]# (cd /opt/ ; (cd /root/ ;echo $BASH_SUBSHELL))
2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

内置命令和外置命令

内置命令和外置命令的区别:

内置命令是指在系统启动时,就会加载到内存中,执行效率高,但占用资源

外置命令则需要用户先从硬盘中读取程序文件,再读入内存

#外置命令就是指用户自己下载的文件系统,是处于bash shell之外的程序
#一般存放在/bin;/usr/bin;/sbin;/usr/sbin,type命令可以判断命令是内置还是外置
[root@test ~]# type ps 
ps is hashed (/usr/bin/ps) #提示是外置命令
[root@test ~]# type cd
cd is a shell builtin  #提示是内置命令
[root@test ~]# 

#查看所有的内置命令
[root@test ~]# compgen -b
.
:
[
alias
bg

..........

unset
wait
[root@test ~]#
#执行外部命令时,一般都会开启子shell执行
[root@test ~]# ps -f --forest 
UID          PID    PPID  C STIME TTY          TIME CMD
root        1545    1544  0 09:29 pts/0    00:00:00 -bash
root        1621    1545  0 10:19 pts/0    00:00:00  \_ ps -f --forest
[root@test ~]# 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/185007
推荐阅读
相关标签
  

闽ICP备14008679号