Shell学习笔记(三)

 

一. 将命名的输出结果赋值给变量

1. Shell 中有两种方式可以完成命令替换,一种是反引号` `,一种是$(),使用方法如下:

var_name=`command`
var_name=$(command)

运行系统命令 date 可以得到当前的系统时间。在很多时候我们需要记录脚本运行时间,所以只是运行这个命令是没有意义的,必须将该命令的运行结果记录并保存到变量中,并持久化到文件中,才能为后期分析提供有用的参考依据。

#!/bin/bash
DATE_01=`date`
DATE_02=$(date)
echo $DATE_01
echo $DATE_02

如果被替换的命令的输出内容包括多行(也即有换行符),或者含有多个连续的空白符,那么在输出变量时应该将变量用双引号包围,否则系统会使用默认的空白符来填充,这会导致换行无效,以及连续的空白符被压缩掉。

2. 原则上讲,上面提到的两种变量替换的形式是等价的,可以随意使用;但是,反引号毕竟看起来像单引号,有时候会对查看代码造成困扰,而使用 $() 就相对清晰,能有效避免这种混乱。

二. Shell字符串详解

1. 字符串(String)就是一系列字符的组合。字符串是 Shell 编程中最常用的数据类型之一(除了数字和字符串,也没有其他类型了)。

2. 字符串可以由单引号' '包围,也可以由双引号" "包围,也可以不用引号。

       1) 由单引号' '包围的字符串:
           任何字符都会原样输出,在其中使用变量是无效的。
           字符串中不能出现单引号,即使对单引号进行转义也不行。

      2) 由双引号" "包围的字符串:
          如果其中包含了某个变量,那么该变量会被解析(得到该变量的值),而不是原样输出。
         字符串中可以出现双引号,只要它被转义了就行。

     3) 不被引号包围的字符串
        不被引号包围的字符串中出现变量时也会被解析,这一点和双引号" "包围的字符串一样。
        字符串中不能出现空格,否则空格后边的会作为其他变量或者字符串解析。

#!/bin/bash
n=88
str1=c.biancheng.net$n str2="shell \"script\" $n"
str3='my_n: $n'
echo $str1
echo $str2
echo $str3

输出结果:

str1 中包含了$n,它被解析为变量 n 的引用。$n后边有空格,紧随空格的 str2;Shell 将 str2 解释为一个新的变量名,而不是作为字符串 str1 的一部分。str2 中包含了引号,但是被转义了(由反斜杠\开头的表示转义字符)。str2 中也包含了$n,它也被解析为变量 n 的引用。str3 中也包含了$n,但是仅仅是作为普通字符,并没有解析为变量 n 的引用。

3. 获取字符串长度

在 Shell 中获取字符串长度很简单,具体方法如下:

${#string_name}

4. 在 Shell 中你不需要使用任何运算符,将两个字符串并排放在一起就能实现拼接,非常简单粗暴。

#!/bin/bash
name="Shell"
url="http://mp.csdn.net/shell/"
str1=$name$url  #中间不能有空格
str2="$name $url"  #如果被双引号包围,那么中间可以有空格
str3=$name": "$url  #中间可以出现别的字符串
str4="$name: $url"  #这样写也可以
str5="${name}Script: ${url}index.html"  #这个时候需要给变量名加上大括号
echo $str1
echo $str2
echo $str3
echo $str4
echo $str5

运行结果:

$name 和 $url 之间之所以不能出现空格,是因为当字符串不被任何一种引号包围时,遇到空格就认为字符串结束了,空格后边的内容会作为其他变量或者字符串解析。

三. Shell数组

1. Bash Shell 只支持一维数组,不支持多维数组。

2. Shell 数组的定义

在 Shell 中,用括号( )来表示数组,数组元素之间用空格来分隔。由此,定义数组的一般形式为:
 

array_name=(ele1  ele2  ele3 ... elen)

注意,赋值号=两边不能有空格,必须紧挨着数组名和数组元素。

Shell 是弱类型的,它并不要求所有数组元素的类型必须相同,例如:

arr=(20 56 "http://mp.csdn.net/shell/")

Shell 数组的长度不是固定的,定义之后还可以增加元素。

3. 获取数组元素

获取数组元素的值,一般使用下面的格式:
 

${array_name[index]}

其中,array_name 是数组名,index 是下标。

#!/bin/bash
nums=(29 100 13 8 91 44)
echo ${nums[@]}  #输出所有数组元素
nums[10]=66  #给第10个元素赋值(此时会增加数组长度)
echo ${nums[*]}  #输出所有数组元素
echo ${nums[4]}  #输出第4个元素

运行结果:
29 100 13 8 91 44
29 100 13 8 91 44 66
91

4. Shell数组拼接,Shell数组合并

拼接数组的思路是:先利用@或*,将数组扩展成列表,然后再合并到一起。

#!/bin/bash
array1=(23 56)
array2=(99 "http://mpcsdn.net/shell/")
array_new=(${array1[@]} ${array2[*]})
echo ${array_new[@]}  #也可以写作 ${array_new[*]}

5. Shell删除数组元素

在 Shell 中,使用 unset 关键字来删除数组元素,具体格式如下:

unset array_name[index]

如果不写下标,而是写成这样的形式:unset array_name 那么就是删除整个数组,所有元素都会消失。

四. Shell内建命令

1. 所谓 Shell 内建命令,就是由 Bash 自身提供的命令,而不是文件系统中的某个可执行文件。

可以使用 type 来确定一个命令是否是内建命令:

2. 内建命令会比外部命令执行得更快,执行外部命令时不但会触发磁盘 I/O,还需要 fork 出一个单独的进程来执行,执行完成后再退出。而执行内建命令相当于调用当前 Shell 进程的一个函数。

#

ifconfig 就属于外部命令,位于/sbin/ifconfig

3. echo

1) echo 是一个 Shell 内建命令,用来在终端输出字符串,并在最后默认加上换行符。

2) echo 命令输出结束后默认会换行,如果不希望换行,可以加上-n参数,如下所示:

#!/bin/bash
name="Tom"
age=20
height=175
weight=62
echo -n "${name} is ${age} years old, "
echo -n "${height}cm in height "
echo "and ${weight}kg in weight."
echo "Thank you!"

运行结果:

Tom is 20 years old, 175cm in height and 62kg in weight.
Thank you!

3) 默认情况下,echo 不会解析以反斜杠\开头的转义字符。比如,\n表示换行,echo 默认会将它作为普通字符对待。

我们可以添加-e参数来让 echo 命令解析转义字符。

[root@localhost ~]# echo -e "hello \nworld"
hello
world

4. Shell exit命令

   1) exit 是一个 Shell 内置命令,用来退出当前 Shell:
       如果在终端中直接运行 exit 命令,会退出当前登录的 Shell,并关闭终端;
       如果在 Shell 脚本中出现 exit 命令,会停止执行后边的所有代码,立即退出 Shell 脚本。

  2) exit 命令可以接受的参数是一个状态值 n,代表退出时的状态。如果不指定,默认状态值是 0。

5. Shell ulimit命令:显示并设置进程资源限度

  1) 系统的可用资源是有限的,如果不限制用户和进程对系统资源的使用,则很容易陷入资源耗尽的地步,而使用 ulimit 命令可以控制进程对可用资源的访问(ulimit 是一个 Shell 内置命令)。

  2) 默认情况下 Linux 系统的各个资源都做了软硬限制,其中硬限制的作用是控制软限制(换言之,软限制不能高于硬限制)。使用ulimit -a可以查看当前系统的软限制,使用命令ulimit -a –H可查看系统的硬限制。

[root@localhost ~]# ulimit -a
#core文件大小,单位是block,默认为0
core file size          (blocks, -c) 0
#数据段大小,单位是kbyte,默认不做限制
data seg size           (kbytes, -d) unlimited
#调度优先级,默认为0
scheduling priority             (-e) 0
#创建文件的大小,单位是block,默认不做限制
file size               (blocks, -f) unlimited
#挂起的信号数量,默认是8192
pending signals                 (-i) 8192
#最大锁定内存的值,单位是kbyte,默认是32
max locked memory       (kbytes, -l) 32
#最大可用的常驻内存值,单位是kbyte,默认不做限制
max memory size         (kbytes, -m) unlimited
#最大打开的文件数,默认是1024
open files                      (-n) 1024
#管道最大缓冲区的值
pipe size            (512 bytes, -p) 8
#消息队列的最大值,单位是byte
POSIX message queues     (bytes, -q) 819200
#程序的实时性优先级,默认为0
real-time priority              (-r) 0
#栈大小,单位是kbyte
stack size              (kbytes, -s) 10240
#最大cpu占用时间,默认不做限制
cpu time               (seconds, -t) unlimited
#用户最大进程数,默认是8192
max user processes              (-u) 8192
#最大虚拟内存,单位是kbyte,默认不做限制
virtual memory          (kbytes, -v) unlimited
#文件锁,默认不做限制
file locks                      (-x) unlimited

每一行中都包含了相应的改变该项设置的参数,以最大可以打开的文件数为例(open files 默认是 1024),想要增大至 4096 则按照如下命令设置(可参照此方法调整其他参数)。

#设置最大打开的文件数
#该命令会同时设置硬限制和软限制
[root@localhost ~]# ulimit -n 4096
#使用-S参数单独设置软限制
#[root@localhost ~]# ulimit -S -n 4096
#使用-H参数单独设置硬限制
#[root@localhost ~]# ulimit -H -n 4096

使用 ulimit 直接调整参数,只会在当前运行时生效,一旦系统重启,所有调整过的参数就会变回系统默认值。所以建议将所有的改动放在 ulimit 的系统配置文件中。相关配置方法请参考笔者对相关配置文件的注释。

[root@localhost ~]# cat /etc/security/limits.conf
# /etc/security/limits.conf
#该文件是ulimit的配置文件,任何对系统的ulimit的修改都应该写入该文件
#请将所有的设置写到该文件的最后
#Each line describes a limit for a user in the form:
#配置应该写成下面这行的格式,即每个配置占用1行,每行4列
#每列分别是<domain> <type> <item> <value>
#<domain>        <type>  <item>  <value>
#
#其中:
#<domain>可以取的值如下:
#       - 一个用户名
#       - 一个组名,组名前面用@符号
#       - 通配符*
#       - 通配符%
#Where:
#<domain> can be:
#        - an user name
#        - a group name, with @group syntax
#        - the wildcard *, for default entry
#        - the wildcard %, can be also used with %group syntax,
#                 for maxlogin limit
#
#<type>只有以下两个可用值:
#       - soft用于设置软限制
#       - hard用于设置硬限制
#<type> can have the two values:
#        - "soft" for enforcing the soft limits
#        - "hard" for enforcing hard limits
#
#<item>的值可以是以下任意一种:
#        - core - core文件大小的限制 (KB)
#        - data - 最大数据段限制 (KB)
#        - fsize - 最大文件大小 (KB)
#        - memlock - 最大锁定的内存大小 (KB)
#        - nofile - 最大打开文件数
#        - rss - 最大常驻内存值 (KB)
#        - stack - 最大栈空间大小 (KB)
#        - cpu - 最大CPU使用时间 (MIN)
#        - nproc - 最大进程数
#        - as - 虚拟地址空间
#        - maxlogins - 某用户的最大登录数
#        - maxsyslogins - 系统用户最大登录数
#        - priority - 用户进程的运行优先级
#        - locks – 用户最大可以锁定文件的数量
#        - sigpending - 最大挂起的信号量数
#        - msgqueue - POSIX信号队列使用的最大内存值 (bytes)
#        - nice - 最大nice值
#        - rtprio - 最大实时优先级
#
#<item> can be one of the following:
#        - core - limits the core file size (KB)
#        - data - max data size (KB)
#        - fsize - maximum filesize (KB)
#        - memlock - max locked-in-memory address space (KB)
#        - nofile - max number of open files
#        - rss - max resident set size (KB)
#        - stack - max stack size (KB)
#        - cpu - max CPU time (MIN)
#        - nproc - max number of processes
#        - as - address space limit
#        - maxlogins - max number of logins for this user
#        - maxsyslogins - max number of logins on the system
#        - priority - the priority to run user process with
#        - locks - max number of file locks the user can hold
#        - sigpending - max number of pending signals
#        - msgqueue - max memory used by POSIX message queues (bytes)
#        - nice - max nice priority allowed to raise to
#        - rtprio - max realtime priority
#
#<domain>      <type>  <item>         <value>
#
#以下是使用样例,请参照配置
#*               soft    core            0
#*               hard    rss             10000
#@student        hard    nproc           20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
#@student        -       maxlogins       4

猜你喜欢

转载自blog.csdn.net/weixin_40599145/article/details/87686651