我们可以使用set命令来显示特定进程的所有环境变量集,shell脚本所特有的强大文本处理能力和各种命令函数的组合

  • 栏目:软件 时间:2020-04-05 12:51
<返回列表

公司的无线环境采用mac地址认证的方式,mac地址被绑定到Radius的users配置文件中,将注册了的mac地址作为用户名和密码。为了方便的管理这些mac地址,自己写了一个shell脚本来管理。

辛星浅谈Linux中的环境变量

全局变量和本地环境变量:

bash shell使用一种称为环境变量的特性来存储关于shell会话和工作环境的信息,这也是环境变量的名字的由来。该特性还允许我们把数据存储在内存中,以便于在shell中运行的程序或者脚本中访问它们。bash shell中共有两种类型的环境变量:全局变量和本地变量。

全局环境变量在shell会话和该shell产生的任何子进程中都可见。而本地变量则只在创建它们的shell中可见。在产生需要父进程信息的子进程的应用程序中,这便体现了全局变量的重要作用。系统环境变量使用使用全大写字母来区别于普通用户环境变量。我们使用printenv命令来查看全局环境变量。要查看某个全局变量的值,我们可以使用echo命令,但是在引用某个环境变量名称的时候,我们需要添加一个美元符号,比如echo $HOME来查看家目录。没有任何命令可以只显示本地环境变量,我们可以使用set命令来显示特定进程的所有环境变量集,这其中也包括了全局环境变量。也就是说我们的printenv命令所看到的所有的全局变量都出现在了set命令的输出中。

设置本地环境变量:

我们可以创建在shell进程中可见的本地变量。我们可以为环境变量分配一个数值或者一个字符串,方法是使用等号将变量指定为具体值,比如test=xin,然后我们使用echo $test就可以输出该变量值了。如果我们要指定包含空格的字符串值,我们需要使用单引号来括起来指定字符的起始位置。如果我们没有使用单引号,bash shell将假定下一个字符是另一个命令。

我们bash shell中的一个约定就是,如果创建新环境变量,建议使用小写字母。它有助于我们区分个人环境变量与系统环境变量。

需要注意的是,环境变量名称、等号和值之间不能有空格,这一点很重要,如果我们在其中添加了任何的空格,那么bash shell会把值解释为一个单独的命令。

我们设置了本地变量之后,我们可以在shell进程的任何地方使用它。但是,如果产生了另外一个shell,则不能在子shell中使用它,我们可以用exit来退出子shell,返回到父shell,当然我们可以用bash来进入一个子shell。

设置全局环境变量:

全局环境变量在任何由设置全局环境变量的进程创建的子进程中都可见。创建全局环境变量的方法是创建一个本地环境变量,然后使用export来把它到处到全局环境中。比如我们首先>test=xin,然后>export test。

这里的export命令让它具有了全局性,在导出本地环境变量时,我们不必使用美元符号来引用变量的名称。

移除环境变量:

我们使用unset来移除环境变量,操作范例unset test,注意这里不要使用美元符号。在操作全局环境变量时,如果我们在子进程中使用unset移除全局环境变量,则该操作只对子进程有效,全局环境变量在父进程中依然可用。

默认的shell环境变量:

(1)CDPATH 冒号分割的目录列表,用作cd命令的搜索路径

(2)HOME 当前用户的主目录

(3)IFS 用于分割字段的字符列表,shell使用它们分割文本字符串

(4)MAIL 当前用户邮箱的文件名,对于新邮件,bash shell将检查该文件

(5)MAILPATH 当前用户邮箱的多个文件名,由冒号分割,对于新邮件,bash shell将检查该列表中的各个文件

(6)OPTARG getopts命令处理的最后一个选项参数的值

(7)OPTIND getopts命令处理的最后一个选项参数的索引值

(8)PATH 冒号分隔的目录列表,shell将在这些目录中查找命令

(9)PS1 主shell命令行界面提示字符串

(10)PS2 次shell命令行界面提示字符串

设置PATH环境变量:

(1)注意:PATH还显示了shell查找命令的顺序

(2)比如我们在PATH中追加一个目录,我们可以使用如下的格式范例:PATH=$PATH:/home/xin/test

(3)我们把某些命令的目录追加到PATH环境变量中,我们可以在虚拟目录结构的任何位置执行我们的程序。

(4)我们经常用的一个技巧就是在我们的PATH环境变量中包括一个点符号,这个点符号代表当前目录。

定位系统环境变量:

通过登录Linux系统启动bash shell时,bash默认将检查一些文件以执行命令,这些文件被称为启动文件。bash处理的启动文件依赖于启动bash shell的方法,我们可以用三种方法来启动bash shell:①在登录时作为默认登录shell。②作为非登录shell的交互式shell。③作为非交互式shell运行脚本。

登录shell:

登录shell将查找四个不同的启动文件来处理当前的命令:/etc/profile、$HOME/.bash_profile、$HOME/.bash_login、$HOME/.profile

其中/etc/profile文件是bash shell在系统上的主默认启动文件,系统上的每一个用户在登录时都将执行此启动文件,另外三个启动文件特定于各个用户,并且可以根据各用户的需求自定义它们。当我们登录Linux操作系统时,bash将执行/etc/profile启动文件中的命令。我们还注意到该文件中会export很多的变量为全局变量。

profile文件还使用了另外一个技巧性的特性,那就是能够迭代/etc/profile.d目录中的任何文件的for语句,这使得Linux系统提供了一个放置特定于应用程序的启动文件,这些文件将在我们登录时由shell执行。

对于$HOME目录下的三个文件,它们具有相同的功能,它们提供特定于用户的启动文件,用于定义特定于用户的环境变量,大多数Linux发行版都是使用三者之一,也就是.bash_profile或者.bash_login或者.profile,注意它们三个都是以点号开头,表示它们是隐藏文件,不会显示在普通的ls命令清单中。

交互式shell:

如果启动了一个bash shell而没有登录系统,比如说只在cli提示符中键入bash,则我们启动的就是一个交互式shell,交互式shell与登录shell的行为不同,但是它仍然提供了一个cli提示符来供我们输入命令。

如果bash作为交互式shell启动,它不会处理/etc/profile文件,相反,它会检查用户HOME目录中的.bashrc文件。而.bashrc文件执行两个任务:①首先检查/etc目录中的公共bashrc文件。②为用户输入个人别名和私有脚本函数提供了地方。

而公共/etc/bashrc文件由系统上启动了交互式shell会话的任何人运行。默认文件将设置一些环境变量,但是它没有使用export命令将它们设置为全局性质。请记住,每次启动新交互式shell时都会运行交互式shell启动文件,因此,任何子shell都会自动执行交互式shell启动文件。其中我们也会注意到,/etc/bashrc文件也执行了位于/etc/profile.d目录中的、特定于应用程序的启动文件。

非交互式shell:

它是系统开始执行shell脚本的shell。它的不同之处在于不用担心cli提示符,但是我们仍然希望在每次启动系统中的脚本时运行特定的启动命令。

bash shell提供了BASH_ENV环境变量,当shell开始一个非交互式shell进程时,它将检查该环境变量中表示的待执行启动文件的名称。如果该变量有值,则shell将执行该文件中的命令。

变量数组:

环境变量的一个非常好地特性就是能够当做数组使用,数组是能够保存多个值的变量,数组中的值既可以分别使用,也可以作为整体引用。

要为某个环境变量设置多个值,我们只需要将它们列出在圆括号中,各个值以空格分割,比如>xin=(one two three four five) 不过当我们使用>echo $xin的时候却只会显示数组的第一个值。

如果我们要引用某个单独的数组元素,我们必须使用一个数值索引值,它表示该元素在数组中的位置,索引值放在方括号中,比如:echo ${xin[2]},这里需要注意的是,环境变量数组的索引值从0开始。当然我们也可以在中括号中使用星号通配符来查看所有值,比如echo ${xin[*]}。

我们还可以更改某个索引位置的值,比如xin[2]=star,当然我们还可以使用unset来移除数组中的某个值,比如unset xin[2],当然我们也可以用unset xin来移除整个数组。

全局变量和本地环境变量: bash shell使用一种称为环境变量的特性来存储关于shell会话和工作环境的信息,这也是...

本文地址

shell脚本所特有的强大文本处理能力和各种命令函数的组合,使得管理员的工作能轻松不少。

 韦德体育 1

下面就列出该脚本的功能以示参考:

 

      点击关注微信公众号 wenyuqinghuai

其中用到的Shell脚本技术包括但不限于:

 

分享提纲:

代码示例:

  1. shell中的函数

#!/bin/bash
#

# Source function library.
. /etc/rc.d/init.d/functions

RADIUSD=/usr/sbin/radiusd
LOCKF=/var/lock/subsys/radiusd
CONFIG=/etc/raddb/radiusd.conf
USERCONFIG=/etc/raddb/users

[ -f $RADIUSD ] || exit 0
[ -f $CONFIG ] || exit 0
[ -f $USERCONFIG ] || exit 0

RETVAL=0

OPERATION=$1
MACADDRESS=$2

function help()
{
    clear
    echo $""
    echo $"===================================================================================="
    echo $"For Radius on Fedora/CentOS/RadHat Linux Server, Written by Chris"
    echo $"===================================================================================="
    echo $"A tool to manage Radius server"
    echo $""
    echo $"Usage: $0 {find|add|modify|delete|check|remove|start|stop|status|restart|reload} mac"
    #TODO
    echo $"Usage: $0 {import|export|debug}"
    echo $""
    echo $"For more information please contract dgdenterprise@gmail.com"
    echo $"===================================================================================="
    echo $""
    exit 1
}

function mac()
{
    if [ -z $MACADDRESS ];then
        echo $"no mac address is signed! "
        echo $"$2 is $MACADDRESS"
        exit 1
    else
                if [[ "${#MACADDRESS}" != "12" ]] && [[ "${#MACADDRESS}" != "17" ]] ;then
            echo "mac length is ${#MACADDRESS}"
                        echo "mac address is illegal! "
            exit 1
#                else
#                        echo $"mac which you input is $MACADDRESS"
                fi
        #echo $MACADDRESS | sed -nr '/[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}/p'
        #echo $MACADDRESS | sed -nr '/[A-Fa-f0-9]{2}-[A-Fa-f0-9]{2}-[A-Fa-f0-9]{2}-[A-Fa-f0-9]{2}-[A-Fa-f0-9]{2}-[A-Fa-f0-9]{2}/p'
        #echo $MACADDRESS | sed -nr '/[A-Fa-f0-9]{12}/p'
        if [[ `echo $MACADDRESS | grep -` ]];then
            PROMAC=`echo $MACADDRESS | sed -nr '/[A-Fa-f0-9]{2}-[A-Fa-f0-9]{2}-[A-Fa-f0-9]{2}-[A-Fa-f0-9]{2}-[A-Fa-f0-9]{2}-[A-Fa-f0-9]{2}/p' | tr '[:upper:]' '[:lower:]' | sed 's/-//g'`
        elif [[ `echo $MACADDRESS | grep :` ]];then
            PROMAC=`echo $MACADDRESS | sed -nr '/[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}/p' | tr '[:upper:]' '[:lower:]' | sed 's/://g'`
        else
            PROMAC=`echo $MACADDRESS | tr '[:upper:]' '[:lower:]'`
        fi
        echo $PROMAC
    fi
}

function find()
{
    MAC=`mac`
    echo $"accepted mac is $MAC"
    if [[ `grep $MAC $USERCONFIG` ]]; then
        MACLINE=`grep -n $MAC $USERCONFIG | awk -F ':' '{print $1}'`
        #echo $MACLINE
        MACLINECOUNT=$(echo $MACLINE | wc -w)
        #echo $MACLINECOUNT
        if [[ "$MACLINECOUNT" != "1" ]];then
            echo $"ERROR, this mac $MAC has duplicate record, you should use $0 remove $MAC to remove duplicate record"
            exit 1
        fi
        echo $"Successfully find $MAC in $MACLINE line of file $USERCONFIG! "
        echo
        REVAL=$?
    else
        echo $"Can not find $MAC in file $USERCONFIG! "
        echo
        exit 1
        REVAL=$?
    fi
}

function add()
{
    MAC=`mac`
    echo $"accepted mac is $MAC"
    #find $MAC
    LINENUM=`grep -n "Cleartext-Password :='" users | grep -v # | head -n1 | awk -F ":" '{print $1}'`
    SEDOPERATION=$LINENUM"a"
    sed -i "$SEDOPERATION $MAC    Cleartext-Password :='$MAC'" $USERCONFIG
    find $MAC
    restart
}

function modify()
{
    MAC=`mac`
    find $MAC
    #TODO

}

function delete()
{
        MAC=`mac`
        echo $"accepted mac is $MAC"
        if [[ `grep $MAC $USERCONFIG` ]]; then
                MACLINE=`grep -n $MAC $USERCONFIG | awk -F ':' '{print $1}'`
                ##echo $MACLINE
                #MACLINECOUNT=$(echo $MACLINE | wc -w)
                ##echo $MACLINECOUNT
                #if [[ "$MACLINECOUNT" != "1" ]];then
                #        echo $"ERROR, this mac $MAC has duplicate record, you should use $0 remove $MAC to remove duplicate record"
                #        exit 1
                #fi
                echo $"Successfully find $MAC in $MACLINE line of file $USERCONFIG! "
        echo $"It will be deleted! "
        sed -i "$MACLINE d" $USERCONFIG
        #TODO
        echo $"If you see 'Can not find $MAC in file $USERCONFIG! ', it means successfully! "
        find $MAC
                echo
                REVAL=$?
        else
                echo $"Can not find $MAC in file $USERCONFIG! "
                echo
                REVAL=$?
        fi
}

function check()
{
    MAC=`mac`
    find $MAC
    remove $MAC
}

function remove()
{
    MAC=`mac`
        echo $"accepted mac is $MAC"
    #TODO
    #echo $"backuped file to file $FILENAME"
        if [[ `grep $MAC $USERCONFIG` ]]; then
                MACLINE=`grep -n $MAC $USERCONFIG | awk -F ':' '{print $1}'`
                #echo $MACLINE
                MACLINECOUNT=$(echo $MACLINE | wc -w)
                #echo $MACLINECOUNT
                if [[ "$MACLINECOUNT" == "1" ]];then
                        echo $"WARNNING, this mac $MAC is good record, no duplicate record has found! "
                        exit 0
                fi
    TOREMOVE="$MAC    Cleartext-Password :='$MAC'"
    sed -i "/^$TOREMOVE$/d" $USERCONFIG
    add $MAC
    fi
}

function restart()
{
    service radiusd restart
}

function reload()
{
    service radiusd reload
}

function status()
{
    service radiusd status
}

case "$1" in 
    find)
        find
        RETVAL=$?
    ;;
    add)
        add
        RETVAL=$?
    ;;
    modify)
        modify
        RETVAL=$?
    ;;
    delete)
        delete
        RETVAL=$?
    ;;
    check)
        check
        RETVAL=$?
    ;;
    remove)
        remove
        RETVAL=$?
    ;;
    start)
        start
        RETVAL=$?
    ;;
    stop)
        stop
        RETVAL=$?
    ;;
    status)
        status
        RETVAL=$?
    ;;
    restart)
        restart
        RETVAL=$?
    ;;
    reload)
        reload
        RETVAL=$?
    ;;
    *)
        help
        exit 1
    ;;
esac

  2. shell中的数组

  3. shell中的变量

韦德体育 ,  4. shell中的运算符

  5. Linux的一些命令

  6. 几个自定义的脚本(可以添加到命令中)

 

 

 

1. shell中的函数


 

  1.1)【定义shell函数(define function)】

 

    [ function ] funname [()]

    {

    action;

    [return int;]

    }

 

说明:

实例(testfun1.sh):

 

韦德体育 2韦德体育 3

 1 #!/bin/sh
 2 
 3  fSum 3 2;
 4  function fSum()
 5  {
 6    echo $1,$2;
 7    return $(($1+$2));
 8  }
 9  fSum 5 7;
10  total=$(fSum 3 2);
11  echo $total,$?;
12 
13 sh testfun1.sh
14 testfun1.sh: line 3: fSum: command not found
15 5,7
16 3,2
17 1
18 5

testfun1.sh

 

从上面这个例子我们可以得到几点结论:

  1.2)【函数作用域,变量作用范围】

先我们看一个实例(testfun2.sh ):

韦德体育 4韦德体育 5

 1 #!/bin/sh
 2 
 3 echo $(uname);
 4 declare num=1000;
 5 
 6 uname()
 7 {
 8   echo "test!";
 9   ((num++));
10   return 100;
11 }
12 testvar()
13 {
14   local num=10;
15   ((num++));
16   echo $num;
17 
18 }
19 
20 uname;
21 echo $?
22 echo $num;
23 testvar;
24 echo $num;
25 
26 sh testfun2.sh
27 Linux
28 test!
29 100
30 1001
31 11
32 1001

testfun2.sh

 

我们一起来分析下上面这个实例,可以得到如下结论:

 

2. shell中的数组


 

  2.1)【数组的定义】

  两种方法

arr=(1 2 3 4 5) # 注意是用空格分开,不是逗号!!

  和

array
array[0]="a"
array[1]="b"
array[2]="c"

 

  2.2)【数组的遍历】

for var in ${ arr[@] };
do
    echo $var
done

 

  2.3)【数组其他】

    -- 【读取数组】

    

valuen=${array_name[n]} #获取单个元素
echo ${array_name[@]}  #获取所有元素

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

 

 

 

3. shell中的变量


 

  3.1)定义

      your_name="runoob.com"

    -- 不能有空格

            --可以使用表达式赋值 

      for file in `ls /etc`

 

  3.2)【使用变量】

  

your_name="qinjx"
echo $your_name
echo ${your_name}

 

   -- 可以加 {}, 也可以不加

   --【只读变量】 readonly myUrl

   --【删除变量】 unset variable_name

 

  3.3)【Shell 字符串】

    -- 可以单引号或者双引号,双引号会解析变量

    --获取字符串长度

    

string="abcd"
echo ${#string} #输出 4

     -- 截取字符串

string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

      -- 查找字符串

string="runoob is a great company"
echo `expr index "$string" is`  # 输出 8

 

 

4. shell中的运算符


  4.1)【基本运算符】

  原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

  

#!/bin/bash

val=`expr 2 + 2`
echo "两数之和为 : $val"

   

  4.2)【关系运算符】

      lt : litter than

                 gt: grater than

 

运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 检测两个数是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。

 

    4.3)【字符串运算符】

 

 -z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否为0,不为0返回 true。 [ -n $a ] 返回 true。
str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

 

    4.4)【文件测试运算符】

文件测试运算符用于检测 Unix 文件的各种属性。

属性检测描述如下:

操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。

 

 

  5.Linux的一些命令


 

  5.1)【一些不太常见的命令】

    -- 查看当前发行版本可以使用的shell:cat  /etc/shells

  5.2)【正则表达式】

    基础正则表达式(BRE)

  5.3)【awk命令】

    

  5.4)【xargs命令】

    

 

  6. 几个自定的脚本(可以添加到命令中)


  1)【实现scp下载远程文件到本地】

    -- down.sh 放到  ~/my_cmd

韦德体育 6韦德体育 7

#!/bin/bash

     if [ -z $1 ]
     then
         echo "请输入要下载的远程文件"
     else
         scp -P5860 root@10.x.xx.xx:$1 ~/Downloads
         echo "文件下载到了 ~/Downloads"
     fi

down.sh

    然后在 vim ~/.bashrc 加上 

alias down='sh ~/my_cmd/down.sh'

      就可以使用 down yourRemoteFile  命令下载远程文件到本地了

 

上一篇:但它们都使用了Linux内核 下一篇:没有了

更多阅读

我们可以使用set命令来显示特定进程的所

软件 2020-04-05
公司的无线环境采用mac地址认证的方式,mac地址被绑定到Radius的users配置文件中,将注册了的...
查看全文

你可以通过日志分析系统日志来了解你的

软件 2020-04-04
Linux有一个显著的特点,在正常情况下,你可以通过日志分析系统日志来了解你的系统中发生了...
查看全文

且经常能在邮件列表的签名档中看到一长

软件 2020-04-04
你从互联网上下载了某个文件(比如安装程序、ISO映像文件或压缩文件)后,该文件可能因各种错...
查看全文

友情链接: 网站地图

Copyright © 2015-2019 http://www.koi-bumi.com. 韦德体育有限公司 版权所有