shell讲义-变量

Linux Shell 讲义

Variables

变量类型

分为环境变量(全局变量) , 普通变量(局部变量)特殊位置参数变量

环境变量(全局变量)
  1. 可以在创建它们的shell及其派生出来的任意子进程shell中使用,环境变量又可分为自定义环境变量和bash内置环境变量。
  2. 环境变量一般是指用export导出的变量。
  3. 设置环境变量的相关配置文件
  • 用户的环境变量

    • ~/.bash_profile
    • ~/.bashrc
  • 全局的环境变量

    • /etc/profile
    • /etc/bashrc
    • /etc/profile.d/*
      • 如果要在登录后初始化或加载内容,就把脚本放在该目录下,不需要加可执行权限。
      • 设置登录提示
        1. echo "welcome " >> /etc/motd
        2. echo “welcome” > /etc/profile.d/login.sh
普通变量(局部变量)
  1. 只能在创建它们的shell函数或者shell脚本中使用
  2. 变量赋值,分为三种:xxx=value,xxx=‘value’,xxx=“value”,把命令结果赋值给一个变量,它们的区别:
xxx=value
  • 建议 连续的数字连续的字符串 赋值时,使用这个赋值方式。
num=123
str=hello
echo "num:"${xxx}
echo "str:"${str}
# output
#  num:123
#  str:hello
xxx=‘value’
  • 希望原样打印引号里面的内容的时候,使用这个赋值方式。
  • 示例,参照 grammar/vaiable.sh/variable1 函数
a=192.168.1.2
b='192.168.1.2-$a'
c="192.168.1.2-$a"
echo "a=$a"
echo "b=$b"
echo "c=${c}"

# output:
#   a=192.168.1.2
#   b=192.168.1.2-$a
#   c=192.168.1.2-192.168.1.2
xxx=“value”
  • 建议字符串中带有空格希望解析内容中的变量 的时候,使用这种形式
  • 示例,参照 grammar/vaiable.sh/variable1 函数
a="this is a test"
b="pwd is $(pwd)"
echo "a:"${a}
echo "b:"${b}

# output:
# a:this is a test
# b:pwd is /home/zhangrj/git/pgr/shell/grammar 
把命令结果赋值给一个变量
  • 使用 ``
  • 使用 $()
  • 示例:
pwd1=`pwd`
pwd2=$(pwd)
echo "pwd1:"${pwd}
echo "pwd2:"${pwd}

# output
#  pwd1:/home/zhangrj/git/pgr/shell/grammar
#  pwd2:/home/zhangrj/git/pgr/shell/grammar
附注:

avatar

案例:
grep是如何引号变量的值的
  • 参照 strings/grep.sh/variable1 函数 grep 过滤字符串时给过滤的内容加引号
cat variable.log
teachers
oldboy

OLDBOY="teachers"
echo "\"$OLDBOY\":"$(grep "$OLDBOY" grep1.log)
echo "'$OLDBOY':"$(grep '$OLDBOY' grep1.log)
echo "$OLDBOY:"$(grep $OLDBOY grep1.log)

#  output
# "teachers":teachers
# 'teachers':
#  teachers:teachers
awk 是如何引号变量的值的
  1. 变量定义为单引号的时候,awk是如何引用变量的值
    1. 参照 strings/awk.sh/awk1
    ETT='oldgirl'
    
    echo "'${ETT}'-\"$ETT\"":$(awk 'BEGIN {print "$ETT"}')
    echo "'${ETT}'-$ETT":$(awk 'BEGIN {print $ETT}')
    echo "'${ETT}'-'$ETT'":$(awk 'BEGIN {print '$ETT'}')
    echo "'${ETT}'-\"'$ETT'\"":$(awk 'BEGIN {print "'$ETT'"}')
    
    # output
    # 'oldgirl'-"oldgirl":$ETT
    # 'oldgirl'-oldgirl:
    # 'oldgirl'-'oldgirl':
    # 'oldgirl'-"'oldgirl'":oldgirl
    
  2. 变量定义为双引号的时候,awk是如何引用变量的值
    1. 参照 strings/awk.sh/awk3
    ETT="oldgirl"
    
    echo "\"${ETT}\"-\"$ETT\"":$(awk 'BEGIN {print "$ETT"}')
    echo "\"${ETT}\"-$ETT":$(awk 'BEGIN {print $ETT}')
    echo "\"${ETT}\"-'$ETT'":$(awk 'BEGIN {print '$ETT'}')
    echo "\"${ETT}\"-\"'$ETT'\"":$(awk 'BEGIN {print "'$ETT'"}')
    
    # output 
    # oldgirl-"oldgirl":$ETT
    # oldgirl -'oldgirl'-oldgirl:
    # oldgirl -'oldgirl'-'oldgirl':
    # oldgirl - "'oldgirl'":oldgirl
    
    
  3. 变量直接定义的时候,awk是如何引用变量的值
    1. 参照 strings/awk.sh/awk2
    ETT=oldgirl
    
    echo "${ETT}-\"$ETT\"":$(awk 'BEGIN {print "$ETT"}')
    echo "${ETT} -'${ETT}'-$ETT":$(awk 'BEGIN {print $ETT}')
    echo "${ETT} -'${ETT}'-'$ETT'":$(awk 'BEGIN {print '$ETT'}')
    echo "${ETT} - \"'$ETT'\"":$(awk 'BEGIN {print "'$ETT'"}')
    
    # output 
    # "oldgirl"-"oldgirl":$ETT
    # "oldgirl"-oldgirl:
    # "oldgirl"-'oldgirl':
    # "oldgirl"-"'oldgirl'":oldgirl
    
  4. 先用echo加符号输出变量,然后通过管道给awk.
    ETT="oldgrid"
    echo "$ETT" |awk '{print $0}'
    # output
    # oldgrid
    
sed 是如何引号变量的值的
cat sed.log
teachers
oldboy

OLDBOY="teachers"
echo "\"$OLDBOY\"":"$(sed -n /"$OLDBOY"/p sed.log)"
echo "$OLDBOY":"$(sed -n /$OLDBOY/p sed.log)"
echo "'$OLDBOY'":"$(sed -n /'$OLDBOY'/p sed.log)"

#  output
# "teachers":teachers
# 'teachers':
#  teachers:teachers
特殊位置参数变量

分为$0,$n,$#,$*,$@

avatar

$1$4…$9${10}… 和 $# 特殊变量
  • 参照 grammar/variable.sh/variable4
echo "echo $# $(echo \${1..15})" > n.sh
echo 'echo $# $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}' >> n.sh
cat n.sh
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}

sh n.sh {a..z}

# output 
# a b c d e f g h i a0 a1 a2 a3 a4 a5
# a b c d e f g h i j k l m n o

# Note:
# 位置变量参数数字大于9时,需要用大括号将数字括起来.
$0 特殊变量
  • 参照 grammar/variable.sh/variable5 函数
echo 'echo $0' > n5.sh

echo 'echo "dirname:"$(dirname "$0")' >> n5.sh
echo 'echo "basename:"$(basename "$0")'    >> n5.sh
# cat n5.sh
# echo $0
# echo "dirname:"$(dirname "$0")
# echo "basename:"$(basename "$0")

sh n5.sh 
# output 
# n5.sh
# dirname:.
# basename:n5.sh

sh `pwd`/n5.sh
# output 
# /home/zhangrj/git/pgr/shell/grammar/n5.sh
# dirname:/home/zhangrj/git/pgr/shell/grammar
# basename:n5.sh
$@,$* 特殊变量
  • @ 不 加 引 号 跟 @不加引号跟 @*是一样的
  • $@加引号表示把所有参数视为单一参数
  • 参照 grammar/variable.sh/variable6 函数
Shell 进程中的特殊状态变量

分为$?,$$,$!,$_

avatar

$$ 特殊状态变量
  • 参照 grammar/variable.sh/variable7 函数
  • 示例:使用$$实现系统中多次执行某一个脚本后的进程只有一个
cat > n6.sh << EOF
#!/bin/sh
pidpath=/tmp/exec.pid
if [ -f "\$pidpath" ]
then 
	kill \`cat \$pidpath\` > /dev/null >& 1
	rm -f \$pidpath
fi
echo \$\$ > \$pidpath

sleep 300
EOF

变量相关操作

查看
  1. set:输出所有的的变量,包括全局和局部。
  2. env:只显示全局变量。
  3. declare(替代早期的typeset):输出所有的变量,函数,整数和已经导出的变量。
设置环境变量
  1. export xxx=“123”
  2. xxx=“123”;export xxx
  3. declare -x xxx=“123”

Bash内置变量命令

常用的内部命令有:echo,eval,exec,export,read,shift

echo

avatar

示例:-n 不换行输出内容

cat > n8.sh << EOF
#!/bin/sh
echo oldboy;echo oldgirl
echo -n oldboy;echo oldgirl
EOF
sh n8.sh
# output

# oldboy
# oldgirl

# oldboyoldgirl

示例: -e 解析转义字符

cat > n9.sh << EOF
#!/bin/sh
echo "oldboy\toldgirl\noldboy\toldgirl"
echo 
echo -e "oldboy\toldgirl\noldboy\toldgirl"
EOF

sh n9.sh
# output 
# oldboy\toldgirl\noldboy\toldgirl
#
# oldboy    oldgirl
# oldboy    oldgirl
eval
  • 格式 eval args
  • shell 读入参数args,并将它们组合成一个新的命令,然后执行
    示例:
cat > n10.sh << EOF
echo \\\$\$#
eval "echo \\\$\$#"
EOF
sh n10.sh arg1 arg2
# output 
# $2
# args
exec,exec命令和重定向
  • 图示:
    avatar

  • 格式:exec 命令参数

  • 说明:exec 命令在不创建子进程的前提下,转去执行指定的命令,执行完成之后,该进程也就结束了(也就是最初的shell)

示例:

cat > n11.sh << EOF
seq 5 > /tmp/tmp.log
exec < /tmp/tmp.log
while read line
do
    echo \$line
done
echo ok
EOF
read
  • 格式:read 变量名表
  • 说明:从标准输入读取字符串信息,传给shell程序内部定义的变量.
  • 示例:
cat > r1.sh << EOF
read -t 5 -p "please input two variables:" a b
echo "\$a \$b " |awk '{print (\$1,\$2,\$1 + \$2)}'
EOF

sh r1.sh 

shift
  • 格式:shift-Shift positional parameters
  • 说明:shift安装如下方式重新命名所有的位置参数变量,也就是$2变成$1,$3变成$2
  • 示例:
cat > n12.sh << EOF
echo \$1 \$2
if [ \$# -eq 2 ];then
    shift 
    echo \$1
fi
EOF

sh n12.sh 1 2 

# output 
# 1 2 
# 2

shell变量子串

avatar

${#parameter} 获取字符串长度

示例

cat > n13.sh << EOF
string="hello,everyone my name is xiaoming"
len=\${#string}

echo "len:"\$len
EOF

sh n13.sh
# output 
# len:34

示例:使用其他方式:expr,参照 strings/expr.sh/expr1 函数

cat > s1.sh << EOF
string="hello,everyone my name is xiaoming"
len=\`expr length "\$string"\`

echo "len:"\$len
EOF

sh s1.sh
# output 
# len:34

示例:使用其他方式:awk,参照 strings/expr.sh/awk4 函数

cat > a1.sh << EOF
string="hello,everyone my name is xiaoming"
echo "len_1":\$(echo \${string} |awk '{print length(\$0)}')
echo "len_2":\$(echo \${string} |awk -F "" '{print NF}')
EOF

sh a1.sh
# output
# len:34
# len:34

${parameter#word},${parameter##word},${parameter%word},${parameter%%word} 四种获取字串的方法
  • 参照 strings/variable.sh/variable14 函数
  • 示例
cat > n14.sh << EOF
string="abcABC123ABCabc"
echo "str:"\${string}

echo "one_1:"\${string#a*C}
echo "one_2:"\${string#a*c}
echo

echo "two_1:"\${string##a*C}
echo "two_2:"\${string##a*c}
echo 

echo "three_1:"\${string%a*C}
echo "three_2:"\${string%a*c}
echo

echo "four_1:"\${string%%a*C}
echo "four_2:"\${string%%a*c}

EOF
sh n14.sh

# output 
# str:abcABC123ABCabc
# one_1:123ABCabc
# one_2:ABC123ABCabc
# 
# two_1:abc
# two_2:
# 
# three_1:abcABC123ABCabc
# three_2:abcABC123ABC
# 
# four_1:abcABC123ABCabc
# four_2:
${parameter/pattern/string},${parameter//pattern/string} 字符串替换

示例:

cat > n15.sh << EOF
string="I am oldboy,yes , oldboy"
echo "str:"\${string}
echo
echo "substr_1:"\${string/oldboy/oldgirl}
echo
echo "substr_2:"\${string//oldboy/oldgirl}
EOF

sh n15.sh 
# output 
# substr_1:I am oldgirl,yes , oldboy
# substr_2:I am oldgirl,yes , oldgirl
获取子串
示例:使用expr获取子串

参照 strings/expr.sh/expr2函数

cat > s2.sh << EOF
string="hello,everyone my name is xiaoming"
substr=\`expr substr "\$string" 1 5\`

echo "substr:"\${substr}
EOF

sh s2.sh

# output
# hello
示例:使用awk获取子串

参照 strings/awk.sh/expr2函数


shell特殊扩展变量

![avatar][shell特殊扩展变量]

  • 示例
cat > n16.sh << EOF
test_A=
echo "test_A:"\${test_A}
result_A=\${test_A:-UNSET}
echo "result_A_1:"\$result_A",test_A_1:"\${test_A}
result_B=\${test_A:=UNSET}
echo "result_B_1:"\$result_B",test_A_1:"\${test_A}
EOF

sh n16.sh

# output 
# test_A:
# result_A_1:UNSET,test_A_1:
# result_B_1:UNSET,test_A_1:UNSE

变量的数值计算

![avatar][shell常用的算术运算符号]

![avatar][shell常见的算术运算命令]

(()) 数值运算,用于整数运算

![avatar][双小括号((xxx))的操作方法]

示例:

echo $(( 1 + 1))  # output:2

((i=5)) # 定义变量
((i = i * 2)) # 对定义的i变量进行运算
echo $i  # 获取i的值,并且打印


a=8
echo $((a=a+1)) # output 9,a的值为9
echo $(a+1) #output 9,a的值为8

echo $((3 < 8)) # output 1
echo $((8 > 7 && 5 == 5)) #output 1


if ((8 > 7 && 5 == 5))
then 
    echo yes
fi
#output yes


# 总结:
# "(())" 在执行命令的时候不需要加$符号,但是要输出,就要加$符号
# "(())" 里的所有字符之间没有空格,有一个空格或多个空格都不会影响结果
let 运算命令的用法
  1. 语法格式:let赋值表达式

示例:

i=2
i=i+8 #没有使用let进行赋值
echo $i # 没有使用let,i直接输出i+8

unset i
i=2
let i=i+8   # 使用let对i进行赋值,等同于((i=i+8))
echo $i     # i输出为10
expr 用于算术运算
  1. 语法格式 expr Expression
  2. 使用expr的使用应该注意
    1. 运算符及用于计算的数字左右都至少有一个空格,否则会报错
    2. 使用乘号时,必须用反斜杠屏蔽其特殊含义
    3. expr 在shell中可配合变量进行计算,但需要用反引号(``)将计算表达式括起来
    4. 利用expr做计算的时候变量必须是整数的规则,可以判断一个变量是整数还是字符串

示例:

expr 2 + 2 # output 4 

expr 2 \* 4 # output 8,*号用\来转义


i=5
i=`expr $i  + 7`
echo $i # output 12

示例: 判断一个变量或字符串是否是整数

  1. 使用expr运算的返回值判断 , 参照 strings/expr.sh/expr3函数
cat > s3.sh << EOF
read -p "input:" i 
expr \$i + 6 &> /dev/null 
if ((\$?==0))
then 
    echo yes
else
    echo no
fi
EOF
sh s3.sh 

# output 
# read 
# 123
# yes
  1. 使用expr match判断 , 参照 strings/expr.sh/expr4函数
cat > s4.sh << EOF
if [[ \`expr match "\$1" "[0-9][0-9]*\$"\` == 0 ]]
then
    echo "\$1 is not a num"
else
    echo "\$1 is a num"
fi
EOF
sh s4.sh 11  # output 11 is a num
sh s4.sh oldboy # output oldboy is not a num
bc 实现运算功能
  1. bc 除了支持整数之外,还支持小数运算
  2. 示例:
echo 3 + 5 |bc #output 8

echo "scale=2;355/113" |bc # 使用scale保留两位小数,3.14

echo {1..10} |tr " " "+" |bc # {1..10}是生成以空格分隔的数字序列,并交给tr将空格替换为+号

seq -s "+" 10 |bc  # seq是生成数字序列,-s 指定数字序列之间的分隔符
awk 实现计算
  1. awk 适用于整数和小数,运算很精确
  2. 示例:
cat > a3.sh << EOF
echo "7.7 3.8" |awk '{print (\$1 - \$2)}'

echo "3 9" |awk '{print (\$1 + 3) * \$2}'
EOF

sh a3.sh
# output
# 3.9
# 54
declare (typeset) 适用于定义整数变量,直接进行计算
cat > d1.sh << EOF
declare -i A=10 B=7
A=A+B
echo \$A
EOF
sh d1.sh

# output
# 17
$[] 用于整数运算
cat > d2.sh << EOF
i=5
i=\$[i+6]
echo \$i

echo \$[2 * 3]
echo \$[2 ** 3]
EOF

sh d2.sh
# output
# 11
# 6
# 8
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

q375923078

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值