变量

变量取一部分

$ name="neighsyncd.service"
$ echo ${name%.*} 
neighsyncd

内部域分隔符 IFS

Shell 脚本中有个变量叫 IFS(Internal Field Seprator) ,内部域分隔符。

从下面的例子中可以看出,如果是用冒号引起来,表示这个变量不用IFS替换!!所以可以看到这个变量的"原始值"。反之,如果不加引号,输出时会根据IFS的值来分割后合并输出! $* 是按照IFS中的第一个值来确定的!下面这两个例子还有细微的差别!

$ IFS=:;
$ set x y z
$ echo $*
x y z

$ echo "$*"
x:y:z

$ echo $@
x y z

$ echo "$@"
x y z

$ IFS="|"
$ arr=(1 2 3)
$ echo ${arr[0]}
1 2 3

$ echo "${arr[0]}"

数组

数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似)。与大部分编程语言类似,数组元素的下标由 0 开始。语法如下:

array_name=(value1 value2 ... valuen)

  • 数组赋值:

array_name[0] = value1
array_name[1] = value2
array_name[2] = value3

  • 读取数组:

index=0
echo ${array_name[$index]}

  • 获取所有元素:

echo ${array_name[*]}

  • 获取数组长度:

echo ${#array_name[*]}

字典

遍历

#必须先声明
declare -A dic
dic=([key1]="value1" [key2]="value2" [key3]="value3")

#打印指定key的value
echo ${dic["key1"]}
#打印所有key值
echo ${!dic[*]}
#打印所有value
echo ${dic[*]}
#字典添加一个新元素
dic+=([key4]="value4")

#遍历key值
for key in $(echo ${!dic[*]})
do
    echo "$key : ${dic[$key]}"
done

getopt

https://www.cnblogs.com/yxzfscg/p/5338775.html

set 命令

  • -a:标示已修改的变量,已供输出到环境变量

使用declare命令定义一个新的环境变量"mylove",并且将其值设置为"meinv",输入如下命令:

declare mylove='meinv' #定义新变量

再使用set命令将新定义的变量输出为环境变量,输入如下命令:

set -a mylove #设置为环境变量

执行该命令后,将会新添加对应的环境变量。

用户可以使用env命令和grep命令分别显示和搜索环境变量"mylove",输入命令如下:

env | grep mylove #显示环境变量值

此时,该命令执行后,将输出查询到的环境变量值。

撤销 set 命令

通过+号撤销set命令,如通过set +x停止调试模式。

declare命令

Linux declare命令用于声明 shell 变量。

declare为shell指令,在第一种语法中可用来声明变量并设置变量的属性([rix]即为变量的属性),在第二种语法中可用来显示shell函数。若不加上任何参数,则会显示全部的shell变量与函数(与执行set指令的效果相同)。

语法:

declare [+/-][rxi][变量名称=设置值] 或 declare -f

参数说明

+/-  "-"可用来指定变量的属性,"+"则是取消变量所设的属性。
-f  仅显示函数。
r  将变量设置为只读。
x  指定的变量会成为环境变量,可供shell以外的程序来使用。
i  [设置值]可以是数值,字符串或运算式。

实例:

declare -r ROOT_PASS="root"
declare -r USER_PASS="12345"

declare -r HOST_DGNAME="docker"
declare -r HOST_DGID="$(getent group | grep docker | awk -F: '{print $3}')"

参数

$@

$@ 表示shell命令后面的所有参数,包括$0

$#

$# 表示shell命令的所有参数个数,包括$#

shift

shell 命令的下标向左shift一位:$0不变, $1 消失, $2 变成 $1

getopts 获得参数

命令格式:

getopts optstring name [arg]

说明

  • optstring:表示要识别的命令行选项形式,如果一个字母后面有一个":",表示该命令行选项后面要跟一个参数。如optsting写成"co:f:",表示支持-c、-o、-f选项识别,-o和-f选项后面需要跟一个参数

  • name:每次调用它前,getopts都会将下一个选项放置在shell变量$name中,如果传入命令行中不存在name选项,则将其重新初始化-

  • arg:表示要解析参数,在shell脚本中使用时,默认解析的是执行shell脚本传入的参数,所以这个部分可省略不写

值得注意的是,当匹配到一个需要参数的选项时,getopts将选项后面跟的参数存放到shell中的OPTARG变量里,OPTIND表示下一个要被处理的命令行参数的索引。

如果找到一个选项,则返回true; 如果遇到选项结尾或发生错误,则false

while getopts "t:m:k:n:s:d:" OPTION; do
    case $OPTION in
    t)
        tbfile=$OPTARG
        echo $tbfile
        ;;
    m)
        vmfile=$OPTARG
        echo $vmfile
        ;;
    *)
        echo "error"
    esac
done

shift $((OPTIND-1))

运行结果:

root@ubuntu ~ # ./test.sh -t hh -m aa
hh
aa

root@ubuntu ~ # ./test.sh -t hh 11 -m aa
hh

root@ubuntu ~ # ./test.sh -t hh -m
hh
./test.sh: option requires an argument -- m
error

cp

cp命令直接覆盖不提示按Y/N的方法:

  • 在CP命令前面加一个斜杠: \cp -rf zongguofeng linuxzgf

  • 取消别名 alias="cp -i"

重定向

如果希望屏蔽 stdout 和 stderr,可以这样写:

$ command > /dev/null 2>&1

小脚本

显示git分支

~/.bashrc加入如下脚本:

function git_branch {
    branch="`git branch 2>/dev/null | grep "^\*" | sed -e "s/^\*\ //"`"
    if [ "${branch}" != "" ];then
        if [ "${branch}" = "(no branch)" ];then
            branch="(`git rev-parse --short HEAD`...)"
        fi
        echo " ($branch)"
    fi
}
export PS1='\u@\h \[\033[01;36m\]\W\[\033[01;32m\]$(git_branch)\[\033[00m\] \$ '

网络速率可读性

将数字转换为更可读的网络速率或PPS,如 2048 转换为 2K

function rate2readable() {
    num=$1
    if [[ $num -le 1024 ]];then
        echo $num
    elif [[ $num -le $((1024*1024)) ]];then
        num=$(echo "scale = 2;  $num / 1024" | bc)
        echo $num"K"
    elif [[ $num -le $((1024*1024*1024)) ]];then
        num=$(echo "scale = 2;  $num / 1024 / 1024" | bc)
        echo $num"M"
    else
        num=$(echo "scale = 2;  $num / 1024 / 1024 / 1024" | bc)
        echo $num"G"
    fi
}

参考