欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux Shell脚本攻略—不止小试牛刀2(变量、数学运算)

程序员文章站 2024-03-09 11:33:53
...

一. 变量和环境变量

脚本语言通常不需要在使用变量之前声明其类型。只需要直接赋值就可以了。
在Bash中,每一个变量的值都是字符串。有一些特殊的变量会被shell环境和操作系统环境用来存储一些特别的值,这类变量就被称为环境变量。

1.1 变量

  • 变量可以通过以下方式进行赋值:var=value。var是变量名,value是赋给变量的值。如果value包含任何空白字符(例如空格),那么它就必须使用单引号或双引号
[email protected]:bashTest$ cat value.sh 
#!/bin/bash
animal=lion
number=10
echo "There are $number ${animal}(s)"
[email protected]:bashTest$ ./value.sh 
There are 10 lion(s)

注意,var=value不同于var = value。把var=value写成var = value是一个常见的错误,前者是赋值操作,后者则是相等操作。


1.2 环境变量

环境变量是未在当前进程中定义,而从父进程中继承而来的变量。

  • export命令用来设置环境变量。设置之后,从当前shell脚本执行的任何应用程序都会继承这个变量。在默认情况下,有很多标准环境变量可供shell用,如PATH、HOME、PWD、USER、UID、SHELL等。
MY_LOVE=1314520
export MY_LOVE
  • PATH:在给出所要执行的命令后,shell会自动在PATH环境变量所包含的目录列表中(各目录路径之间以冒号分隔)查找对应的可执行文件。
[email protected]:bashTest$ echo $PATH
/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin:/opt/hisi-linux/x86-arm/arm-hisiv400-linux/target/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

#添加新路径:
export PATH="$PATH:/home/user/bin"
#也可以使用
$ PATH="$PATH:/home/user/bin"
$ export PATH
  • 可以使用env命令查看所有与终端相关的环境变量。
[email protected]:~$ env
LC_PAPER=zh_CN.UTF-8
LC_ADDRESS=zh_CN.UTF-8
XDG_SESSION_ID=1
LC_MONETARY=zh_CN.UTF-8
TERM=xterm
SHELL=/bin/bash
LC_NUMERIC=zh_CN.UTF-8
SSH_TTY=/dev/pts/1
USER=mrhjlong
#还有很多...
  • 可以使用pgrep命令获得进程的ID号(PID),然后即可获取该进程相关的环境变量:$ cat /proc/$PID/environ
mrhjlong@hjl-virtual-machine:~$ ps
  PID TTY          TIME CMD
 2821 pts/1    00:00:00 bash
 2930 pts/1    00:00:00 ps
mrhjlong@hjl-virtual-machine:~$ pgrep bash
2821
mrhjlong@hjl-virtual-machine:~$ cat /proc/2821/environ         
USER=mrhjlongLOGNAME=mrhjlongHOME=/home/mrhjlongPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/gamesMAIL=/var/mail/mrhjlongSHELL=/bin/bashSSH_CLIENT=192.168.91.1 9357 22SSH_CONNECTION=192.168.91.1 9357 192.168.91.155 22SSH_TTY=/dev/pts/1TERM=xtermXDG_SESSION_ID=1XDG_RUNTIME_DIR=/run/user/1000LANG=en_US.UTF-8LC_NUMERIC=zh_CN.UTF-8LC_TIME=zh_CN.UTF-8LC_MONETARY=zh_CN.UTF-8LC_PAPER=zh_CN.UTF-8LC_NAME=zh_CN.UTF-8LC_ADDRESS=zh_CN.UTF-8LC_TELEPHONE=zh_CN.UTF-8LC_MEASUREMENT=zh_CN.UTF-8LC_IDENTIFICATION=zh_CN.UTF-8

#结合上篇的学习,命令替换获取环境变量:
mrhjlong@hjl-virtual-machine:~$ cat /proc/"$(pgrep bash)"/environ
USER=mrhjlongLOGNAME=mrhjlongHOME=/home/mrhjlongPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/gamesMAIL=/var/mail/mrhjlongSHELL=/bin/bashSSH_CLIENT=192.168.91.1 9357 22SSH_CONNECTION=192.168.91.1 9357 192.168.91.155 22SSH_TTY=/dev/pts/1TERM=xtermXDG_SESSION_ID=1XDG_RUNTIME_DIR=/run/user/1000LANG=en_US.UTF-8LC_NUMERIC=zh_CN.UTF-8LC_TIME=zh_CN.UTF-8LC_MONETARY=zh_CN.UTF-8LC_PAPER=zh_CN.UTF-8LC_NAME=zh_CN.UTF-8LC_ADDRESS=zh_CN.UTF-8LC_TELEPHONE=zh_CN.UTF-8LC_MEASUREMENT=zh_CN.UTF-8LC_IDENTIFICATION=zh_CN.UTF-8
  • 上面的命令返回一个包含环境变量以及对应变量值的列表。每一个变量以name=value的形式来描述,彼此之间由null字符(\0)分隔。将\0替换成\n,那么就可以将输出重新格式化,替换可以使用tr命令来实现:
mrhjlong@hjl-virtual-machine:~$ cat /proc/2821/environ | tr '\0' '\n'
USER=mrhjlong
LOGNAME=mrhjlong
HOME=/home/mrhjlong
#还有很多...

1.3 补充

  • 获得字符串长度:length=${#var}
mrhjlong@hjl-virtual-machine:bashTest$ var=1234568790abcde
mrhjlong@hjl-virtual-machine:bashTest$ echo ${#var}
15
  • 识别当前所使用的shell:echo $SHELLecho $0
mrhjlong@hjl-virtual-machine:bashTest$ echo $SHELL
/bin/bash
mrhjlong@hjl-virtual-machine:bashTest$ echo $0
-bash
  • 检查是否为超级用户:root用户的UID为0。
if [ $UID -ne 0 ]; then
echo Non root user. Please run as root.
else
echo Root user
fi

1.4 函数添加环境变量

prepend函数

  • 可以把prepend函数加入.bashrc中。
prepend() { [ -d "$2" ] && eval $1=\"$2':'\$$1\" && export $1; }
  • 之后可以使用prepend函数添加环境变量:
prepend PATH /opt/myapp/bin
prepend LD_LIBRARY_PATH /opt/myapp/lib
  • 问题:当变量为空则多一个“:”。因此,引入shell的参数扩展形式来解决该问题。
${parameter:+expression}
#如果parameter有值且不为空,则使用expression的值。
prepend() { [ -d "$2" ] && eval $1=\"$2\$\{$1:+':'\$$1\}\" && export $1 ; }

二. shell数学运算

在Bash shell环境中,可以利用let、(( ))和[]执行基本的算术操作,而在进行高级操作时,expr和bc这两个工具会非常有用。

2.1 整数运算

  • let命令:变量名之前不需要再添加$。
[email protected]:bashTest$ cat letMath.sh 
#!/bin/bash
num1=2
num2=8
let ret=num1+num2
echo $ret
let ret++
let ret--
echo $ret
let ret+=4      #等同于let ret=ret+4
let ret-=2      #等同于let ret=ret-2
echo $ret
[email protected]:bashTest$ ./letMath.sh 
10
10
12
  • $[expression]:使用或不使用$访问变量都行,加号两边空格可有可无。
[email protected]:bashTest$ cat math1.sh 
#!/bin/bash
no1=5; no2=8
sum=$[ $no1  +no2]
echo $sum
[email protected]:bashTest$ ./math1.sh   
13
  • $((expression)):使用或不使用$访问变量都行,加号两边空格可有可无。
[email protected]:bashTest$ cat math2.sh 
#!/bin/bash
no1=5; no2=8
sum=$(( $no1  *no2))
echo $sum
[email protected]:bashTest$ ./math2.sh   
40
  • expr命令:必须使用$访问变量,符号两边要有空格。
[email protected]:bashTest$ cat exprMath.sh 
#!/bin/bash
no1=9; no2=2
dev=`expr $no1 / $no2`
sub=$(expr $no1 - $no2)
echo $dev $sub
[email protected]:bashTest$ ./exprMath.sh 
4 7
  • declare关键字:作用就是声明类型,-i表示整数。使用或不使用$访问变量都行,符号两边不能有空格。
[email protected]:bashTest$ cat declareMath.sh 
#!/bin/bash
declare -i no1 no2 sum
no1=5; no2=831
sum=no1+$no2
echo $sum
[email protected]:bashTest$ ./declareMath.sh 
836

2.2 浮点数运算

  • bc命令:bc(选项)(参数)
    选项
    -i:强制进入交互式模式;
    -l:定义使用的标准数学库;
    -w:对POSIX bc的扩展给出警告信息;
    -q:不打印正常的GNU bc环境信息;
    -v:显示指令版本信息;
    -h:显示指令的帮助信息。
    参数
    文件:指定包含计算任务的文件。
[email protected]:bashTest$ cat bcMath.sh 
#!/bin/bash
#设置小数精度
echo "scale=5; 3/7" | bc

#进制转换
no1=192
echo "obase=2;$no1" | bc                #十进制转二进制
no2=11000000
echo "obase=10;ibase=2;$no2" | bc       #二进制转十进制
#平方和平方根

echo "3^3" | bc
echo "sqrt(100)" | bc
[email protected]:bashTest$ ./bcMath.sh 
.42857
11000000
192
27
10
  • awk命令简单使用(后续详解)。
[email protected]:bashTest$ cat awkMath.sh 
#!/bin/bash
echo ` awk -v x=3.1 -v y=7.2 'BEGIN{printf "%.2f\n", x/y}' `
echo $( awk 'BEGIN{x=3.1; y=7.2; printf "%.3f\n", x/y}' )
echo '3.1 7.2' | awk '{printf "%.4f\n", $1/$2}'
[email protected]:bashTest$ ./awkMath.sh 
0.43
0.431
0.4306
相关标签: Linux Shell Bash