码迷,mamicode.com
首页 > 系统相关 > 详细

bash shell的基本概述与操作

时间:2017-04-06 17:34:06      阅读:493      评论:0      收藏:0      [点我收藏+]

标签:工作环境   linux   用户   

                      Bash shell的基本操作与概念

 

特殊的shell变量

 除了用户自定义的变量以外,在linux系统和bash shell环境中还有一些特殊的变量-环境变量,位置变量,预定义变量。下面分别进行介绍

 

环境变量

  环境变量指的是出于运行需要而由linux系统提前创建的一类变量,主要用于设置用户的工作环境,包括用户的宿主目录,命令查找路径,用户当前目录,登录终端等。环境变量的值由linux系统自动维护,会随着用户状态的改变而改变。

使用env命令可以查看到当前工作环境下的环境变量,对于一些常见的环境变量应了解其各自的用途。例如变量USER表示用户名称,HOME表示用户宿主目录,LANG表示语言和字符集,PWD表示当前所在的工作目录,PATH表示命令搜索路径。

[root@Centos01 ~]# env

HOSTNAME=Centos01.test.com

TERM=xterm

SHELL=/bin/bash

HISTSIZE=1000

SSH_CLIENT=192.168.1.100 4053 22

QTDIR=/usr/lib64/qt-3.3

QTINC=/usr/lib64/qt-3.3/include

SSH_TTY=/dev/pts/1

USER=root

 

PATH变量用于设置可执行程序的默认搜索路径,当仅指定文件名称来执行命令程序时,linux系统将PATH变量指定的目录搜索范围查找对应的可执行文件,如果找不到则会提示command not found.

[root@Centos01 ~]# mkdir /root/scripts

[root@Centos01 ~]# cd /root/scripts

[root@Centos01 scripts]# vi first.sh

[root@Centos01 scripts]# chmod +x first.sh

[root@Centos01 scripts]# ls -lh /root/scripts/first.sh

-rwxr-xr-x 1 root root 44 Jun  4 23:16 /root/scripts/first.sh

[root@Centos01 scripts]# echo $PATH

/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

[root@Centos01 scripts]# cd

[root@Centos01 ~]# first.sh

-bash: first.sh: command not found

[root@Centos01 ~]# PATH="$PATH:/root/scripts"

[root@Centos01 ~]# echo $PATH

/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/root/scripts

[root@Centos01 ~]# first.sh

 

#

# /etc/fstab

# Created by anaconda on Thu Jun  2 19:35:06 2016

#

# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘

# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info

#

/dev/mapper/vg_centos01-lv_root /                       ext4    defaults        1 1

UUID=3bb70b22-a906-43ea-97d1-ca28485afec7 /boot                   ext4    defaults        1 2

/dev/mapper/vg_centos01-lv_home /home                   ext4    defaults        1 2

/dev/mapper/vg_centos01-lv_swap swap                    swap    defaults        0 0

tmpfs                   /dev/shm                tmpfs   defaults        0 0

devpts                  /dev/pts                devpts  gid=5,mode=620  0 0

sysfs                   /sys                    sysfs   defaults        0 0

proc                    /proc                   proc    defaults        0 0

16 /etc/fstab

[root@Centos01 ~]#

 

 

linux系统中,环境变量的全局配置文件为/etc/profile,在此文件中定义的变量作用域所有用户。除此之外,每个用户还有自己的独立配置文件(./bash_profile)。若要长期变更或设置某个环境变量,应在上述文件中进行设置。例如,执行以下操作可以将记录的历史命令条数改为200条,默认为1000条,只针对root用户

[root@Centos01 ~]# vi /root/.bash_profile

export HISTSIZE=200

上述修改只有当root用户下次登录时才会生效,若希望立即生效,应手动修改环境变量或者加载配置文件执行。

[root@Centos01 ~]# source /root/.bash_profile

 

 

位置变量

 

为了在使用shell脚本程序时,方便通过命令行为程序提供操作参数,bash引入了位置变量的概念。当执行命令行操作时,第一个字段表示命令名或脚本程序名,其余的字符串参数按照从左到右的顺序依次赋值给位置变量。

位置变量也成为位置参数,使用$1$2$3$4.....表示,例如当执行命令行“ls -ls /boot/”时,其中第一个位置变量为“-lh”以$1表示,第二个位置变量为/boot/ ,使用$2表示,命令或脚本本身的名称使用$0表示。虽然$0与位置变量的格式,但是$0属于预定义变量而不是位置变量。

为了说明位置变量的作用,下面编写一个加法运算的脚本adder2num.sh,用来计算两个整数的合,需要计算的两个整数在执行脚本时以位置变量的形式提供。

 

[root@Centos01 ~]# vi adder2num.sh

 

#!/bin/bash

sum=`expr $1 + $2`

echo "$1 + $2 = $sum"

 

预定义变量是有bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,也不能直接为预定义变量赋值。预定义变量使用$符号和另一个符号组合表示,较常用的预定义变量的含义如下:

$#:表示命令行中位置参数的个数

$*: 表示所有位置参数的内容

$?: 表示前一条命令执行后的返回状态,返回值为0表示执行正确,返回任何非0值均表示执行出现异常。

$0: 表示当前执行的脚本或程序的名称

 

 

GNUdate提供+%s(小写s), 能打印出自1970-01-01 00:00:00到当前时间的秒数.

 

编写一个备份操作的脚本,用来打包命令行指定的多个文件或目录,并输出相关信息,其中,新建的压缩包文件名称中嵌入秒数。

#!/bin/bash

tarfile=beifen-`date +%s`.tgz

tar zcf $tarfile $* &> /dev/null

echo "已执行 $0 脚本"

echo "共完成 $# 个对象的备份"

echo "具体内容包括: $* "

 

执行结果是:

[root@Centos01 ~]# ./mybak.sh /etc/passwd /etc/shadow

已执行 ./mybak.sh 脚本

共完成 2 个对象的备份

具体内容包括: /etc/passwd /etc/shadow

 

shell条件测试

 

如果一个表达式自身不足以做条件测试的话,可以使用 test [测试表达式] 或者 [ 测试表达式 ]

 

 

I/O重定向

 

标准输出重定向

 

  > :覆盖重定向,目标文件中的原有内容会被消除

  >> :追加重定向,新内容会追加至目标文件尾部

 

  set -C :禁止将内容覆盖输出到已有的文件中 <只在当前shell中有效>

    若要强制覆盖可以使用 >| 例如 cat /etc/fstab >| /tmp/aa.txt

  set +C:关闭以上功能

 

  [root@Centos01 ~]# ls /var > /tmp/etc.out

  [root@Centos01 ~]# ls /var/log/ >> /tmp/etc.out

 

标准错误重定向


[root@Centos01 ~]# cat /etc/issuee 2> /tmp/issue.txt

[root@Centos01 ~]# cat /tmp/issue.txt

cat: /etc/issuee: No such file or directory

[root@Centos01 ~]# cat /etc/issue 2> /tmp/issue.txt

CentOS release 6.5 (Final)

Kernel \r on an \m

[root@Centos01 ~]# cat /tmp/issue.txt 发现文件是空的,因为没有错误输出,所以2>只能重定向错误输出

2> :覆盖从定向错误输出

2>> :追加重定向错误输出

 

将标准输出和错误输出各自定向到不同位置:

[root@Centos01 ~]# tail -100 /etc/rc.d/rc.sysinit > /tmp/sysinit.out 2> /tmp/sysinit.err

[root@Centos01 ~]# cat /tmp/sysinit.err 这个文件是空的

[root@Centos01 ~]# cat /tmp/sysinit.out 这个文件是标准输出

[root@Centos01 ~]# tail -100 /etc/rc.d/rc.sysinidddt > /tmp/sysinit.out 2> /tmp/sysinit.err

[root@Centos01 ~]# cat /tmp/sysinit.err

    tail: cannot open `/etc/rc.d/rc.sysinidddt‘ for reading: No such file or directory

 

可以合并标准输出和错误输出为同一个数据流进行重定向

&> 覆盖重定向

&>> 追加重定向

[root@Centos01 ~]# echo $PATH

/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

You have new mail in /var/spool/mail/root

[root@Centos01 ~]# echo $PATH &> /tmp/path.out

[root@Centos01 ~]# cat /tmp/path.out

/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

[root@Centos01 ~]#

[root@Centos01 ~]# echoooo $PATH &> /tmp/path.out

[root@Centos01 ~]# cat /tmp/path.out

-bash: echoooo: command not found

特殊写法:将标准输出和错误输出写到同一个文件可以使用2>&1

[root@Centos01 ~]# echo "$PATH" > /tmp/path.out 2>&1

[root@Centos01 ~]# echoddd "$PATH" >> /tmp/path.out 2>&1

[root@Centos01 ~]# cat /tmp/path.out

/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

-bash: echoddd: command not found

 

输入重定向:将原本需要有键盘输入的数据,同过文件来读入。 <

[root@Centos01 ~]# useradd jerry

[root@Centos01 ~]# vi pass.txt

[root@Centos01 ~]# passwd --stdin jerry < pass.txt

 

[root@Centos01 ~]# cat aa.txt

test stdin

使用cat命令在键盘上输入一些数据,然后写入catfile文件中

[root@Centos01 ~]# cat > catfile

testing

cat file tset

输入crtl+d结束

此时就会有catfile文件产生,而且该文件的内容就是刚刚输入的内容,那么是否可以使用其他文件来替换键盘输入呢

[root@Centos01 ~]# cat > catfile < aa.txt

[root@Centos01 ~]# cat catfile

test stdin

[root@Centos01 ~]#

我们可以用cat直接将输入的消息输出到catfile中,并且当输入EOF时,该次输入就结束,可以这样做

[root@Centos01 ~]# cat > catfile <<EOF

> this is a test testing

> ok now stop

> EOF

You have new mail in /var/spool/mail/root

[root@Centos01 ~]# cat catfile

this is a test testing

ok now stop

[root@Centos01 ~]#

 

 


[root@Centos01 ~]# tr abc ABC < /etc/fstab

 

#

# /etC/fstAB

# CreAted By AnACondA on Thu Jun  2 19:35:06 2016

#

# ACCessiBle filesystems, By referenCe, Are mAintAined under ‘/dev/disk‘

# See mAn pAges fstAB(5), findfs(8), mount(8) And/or Blkid(8) for more info

#

/dev/mApper/vg_Centos01-lv_root /                       ext4    defAults        1 1

UUID=3BB70B22-A906-43eA-97d1-CA28485AfeC7 /Boot                   ext4    defAults        1 2

/dev/mApper/vg_Centos01-lv_home /home                   ext4    defAults        1 2

/dev/mApper/vg_Centos01-lv_swAp swAp                    swAp    defAults        0 0

tmpfs                   /dev/shm                tmpfs   defAults        0 0

devpts                  /dev/pts                devpts  gid=5,mode=620  0 0

sysfs                   /sys                    sysfs   defAults        0 0

proC                    /proC                   proC    defAults        0 0

 

[root@Centos01 ~]# tr ‘a-z‘ ‘A-Z‘ < /etc/fstab

 

#

# /ETC/FSTAB

# CREATED BY ANACONDA ON THU JUN  2 19:35:06 2016

#

# ACCESSIBLE FILESYSTEMS, BY REFERENCE, ARE MAINTAINED UNDER ‘/DEV/DISK‘

# SEE MAN PAGES FSTAB(5), FINDFS(8), MOUNT(8) AND/OR BLKID(8) FOR MORE INFO

#

/DEV/MAPPER/VG_CENTOS01-LV_ROOT /                       EXT4    DEFAULTS        1 1

UUID=3BB70B22-A906-43EA-97D1-CA28485AFEC7 /BOOT                   EXT4    DEFAULTS        1 2

/DEV/MAPPER/VG_CENTOS01-LV_HOME /HOME                   EXT4    DEFAULTS        1 2

/DEV/MAPPER/VG_CENTOS01-LV_SWAP SWAP                    SWAP    DEFAULTS        0 0

TMPFS                   /DEV/SHM                TMPFS   DEFAULTS        0 0

DEVPTS                  /DEV/PTS                DEVPTS  GID=5,MODE=620  0 0

SYSFS                   /SYS                    SYSFS   DEFAULTS        0 0

PROC                    /PROC                   PROC    DEFAULTS        0 0

 

[root@Centos01 ~]# tr -d abc

alpha

lph

amnbak

mnk

 

此处生成文档

[root@Centos01 ~]# cat << EOF

> how are you?

> how old are you?

> EOF

how are you?

how old are you?

[root@Centos01 ~]# cat >> /tmp/test.out << EOF

> how are you?

> how old are you?

> EOF

[root@Centos01 ~]# cat /tmp/test.out

how are you?

how old are you?

利用<<右侧的控制符,可以终止一次输入,而不必输入ctrl+d来结束。这对程序的编写很有帮助。那么为什么要使用命令输出重定向呢?如果没有接触过脚本,这个问题一定会很难理解,下面是一些命令输出重定向的场合:

1. 当屏幕输出的信息很重要,而且我们需要将它存下来的时候

2. 后台执行的程序,不希望它干扰屏幕正常的输出结果

3. 一些系统的例行命令的执行结果,希望它可以存下来

4. 一些执行命令,我们已经知道它可能的错误消息,所以想以2>/dev/null将它丢掉

5. 错误消息与正确消息需要分别输出

 

大家都知道每个命令都有输入和输出,我们可不可以把前一个命令的输出当做后面命令的输入,大家都知道一个命令的输入可以从一个文件中读取,能不能从前一个命令中读取呢,这种机制就叫做管道,管道即把第一个命令的输出送给第二个命令当输入

[root@Centos01 ~]# echo $PATH

/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

 

[root@Centos01 ~]# echo $PATH | tr ‘a-z‘ ‘A-Z‘

/USR/LIB64/QT-3.3/BIN:/USR/LOCAL/SBIN:/USR/LOCAL/BIN:/SBIN:/BIN:/USR/SBIN:/USR/BIN:/ROOT/BIN

 

[root@Centos01 ~]# echo $PATH | tr ‘a-z‘ ‘A-Z‘| tr -d ‘U‘

/SR/LIB64/QT-3.3/BIN:/SR/LOCAL/SBIN:/SR/LOCAL/BIN:/SBIN:/BIN:/SR/SBIN:/SR/BIN:/ROOT/BINYou have

 

[root@Centos01 ~]# ls -al /etc | less 使用ls命令输出后的内容,就能够被less读取,并且利用less的功能,我们就能够前后翻动相关的信息,很方便

 

 

将登陆到系统上的用户信息中的后3行的信息转换为大写字母后保存至/tmp/who.out文件中

[root@Centos01 ~]# who | tail -n 3 | tr ‘a-z‘ ‘A-Z‘ > /tmp/who.out

/etc/passwd/文件中的前5行内容转换为大写后保存至/tmp/passwd.out文件中

[root@Centos01 ~]# cat /etc/passwd | head -n 5 | tr ‘a-z‘ ‘A-Z‘ > /tmp/passwd.out

[root@Centos01 ~]# cat /tmp/passwd.out

ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH

BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN

DAEMON:X:2:2:DAEMON:/SBIN:/SBIN/NOLOGIN

ADM:X:3:4:ADM:/VAR/ADM:/SBIN/NOLOGIN

LP:X:4:7:LP:/VAR/SPOOL/LPD:/SBIN/NOLOGIN

 

脚本示例

1. 创建一个组newgroup,id号为4000

2. 创建一个用户test,id号为3001,附加组为newgroup

3. 创建目录/tmp/hellod

4. 复制/etc/fstab至上面的目录中

5. 改变目录及内部文件的属主和属组为test

6. 让目录及内部文件的其他用户没有任何权限

[root@Centos01 ~]# cat aa.sh

#!/bin/bash

 

groupadd -g 4000 newgroup

useradd -u 3001 -G newgroup test

mkdir /tmp/hellod

cp /etc/fstab /tmp/hellod

chown -R test:test /tmp/hellod

chmod -R o= /tmp/hellod

 

或者

 

#!/bin/bash

 

myGroup="newgroup"

myUser="test"

myDir="/tmp/hellod"

myID=3001

 

groupadd -g 4000 $myGroup

useradd -u $myID -G $myGroup $myUser

mkdir $myDir

cp /etc/fstab $myDir

chown -R $myUser:$myUser $myUser

chmod -R o= $myDir

 

 

变量的命名要求

只能使用数字、字母、下划线组成

不能以数字开头

不能使用程序中关键字

要做到见名之意

awk可以处理后续文件,也可以读取来自前一个命令的标准输出。awk主要是处理“每一行字段内的数据”,而默认的字段分隔符为空格键或tab键,举例来说,用last可以将登录者的数据取出来,结果如图所示:

若想取出账号与登录者的IP地址,且账号与IP地址之间以tab键隔开,则会变成这样:

[root@Centos01 ~]# last | awk ‘{print $1 "\t" $3}‘

root192.168.1.100

root192.168.1.100

rebootboot

root:0.0

root:0

awk是以行尾处理单位,而以字段为最小的处理单位

awk举例:

[root@Centos01 ~]# ifconfig eth0 | grep "HWaddr"

eth0      Link encap:Ethernet  HWaddr 00:0C:29:1A:E3:AA  

[root@Centos01 ~]# ifconfig eth0 | grep "HWaddr" | awk ‘{print $5}‘

00:0C:29:1A:E3:AA

[root@Centos01 ~]# hwaddr=$(ifconfig eth0 | grep "HWaddr" | awk ‘{print $5}‘)

[root@Centos01 ~]# echo hwaddr

hwaddr

[root@Centos01 ~]# echo $hwaddr

00:0C:29:1A:E3:AA

[root@Centos01 ~]# grep "bash$" /etc/passwd

root:x:0:0:root:/root:/bin/bash

mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash

cacti:x:500:500::/home/cacti:/bin/bash

[root@Centos01 ~]# grep "bash$" /etc/passwd | awk -F: ‘{print $1,$7}‘

root /bin/bash

mysql /bin/bash

cacti /bin/bash

[root@Centos01 ~]#

特殊变量:

$0;脚本名称自身

$?: 上一条命令的执行状态,状态用数字来表示:0-255 0表示成功,1-255表示失败

命令执行成功了,成功的标记叫状态返回值,而正常的命令执行后的结果叫返回值。

 

环境变量:用来定义bash的工作特性,用于保存当前会话的属性信息。

显示所有环境变量:export,env,printenv

envenvironment(环境)的缩写。

执行env命令即可获得当前shell环境下所有环境变量及其内容

[root@Centos6 ~]# env

 

定义环境变量:

 

export Var_Name="Value"

例如:

[root@Centos6 ~]# echo $PATH

/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

[root@Centos6 ~]# mkdir /root/sbin

[root@Centos6 ~]# export PATH=/root/sbin/

[root@Centos6 ~]# cat /etc/fstab

-bash: cat: command not found

重新登录该终端就又可以访问了

[root@Centos6 ~]# cat /etc/fstab

 

#

# /etc/fstab

# Created by anaconda on Thu Jun  2 21:38:10 2016

#

# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘

# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info

#

/dev/mapper/vg_centos6-lv_root /                       ext4    defaults        1 1

UUID=f8f486f4-8f58-4619-92f9-0fdde943166c /boot                   ext4    defaults        1 2

/dev/mapper/vg_centos6-lv_home /home                   ext4    defaults        1 2

/dev/mapper/vg_centos6-lv_swap swap                    swap    defaults        0 0

tmpfs                   /dev/shm                tmpfs   defaults        0 0

devpts                  /dev/pts                devpts  gid=5,mode=620  0 0

sysfs                   /sys                    sysfs   defaults        0 0

proc                    /proc                   proc    defaults        0 0

 

不重新登录该终端也可以,[root@Centos6 ~]# export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

 

若要在PATH环境变量中增加/root/sbin

[root@Centos6 ~]# echo $PATH

/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

[root@Centos6 ~]# export PATH=$PATH:/root/sbin

[root@Centos6 ~]# echo $PATH

/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/root/sbin

[root@Centos6 ~]# export PATH=/root/sbin:$PATH

[root@Centos6 ~]# echo $PATH

/root/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/root/sbin

改过来

[root@Centos6 ~]# export PATH=$PATH:/root/sbin

 

bash的配置文件:持久保存用户配置

profile:为交互式登录用户提供配置

/etc/profile --->全局的,对所有用户有效

/etc/profile.d/*.sh  --->全局的,对所有用户有效

每个用户家目录下的~/.bash_profile   --->个人的,仅对当前用户有效,

profile的功能:

设定环境变量

运行命令或脚本时

 [root@Centos6 ~]# cat .bash_profile 由于只配置了root用户的.bash_profile,只对root用户生效。

# .bash_profile

 

# Get the aliases and functions

if [ -f ~/.bashrc ]; then

. ~/.bashrc

fi

 

# User specific environment and startup programs

 

PATH=$PATH:$HOME/bin

 

export PATH

echo "welcome here...."  --->添加此行

 

重新登录的时候就会显示

Last login: Tue Jun 14 16:21:44 2016 from 192.168.1.100

welcome here....


bashrc:为非交互式登录用户提供配置

.bashrc功能:

可以设定本地变量,让脚本运行时有变量可以使用

可以定义命令别名

[root@Centos6 ~]# cat .bashrc

# .bashrc

 

# User specific aliases and functions

 

alias rm=‘rm -i‘

alias cp=‘cp -i‘

alias mv=‘mv -i‘

 

# Source global definitions

if [ -f /etc/bashrc ]; then

. /etc/bashrc

fi

 

登录类型:

交互式登录:

直接通过终端输入用户名密码登录系统

其实su - 用户名 或者 su -l 用户名方式登录也算是交互式登录

 

对于交互式用户来讲是读取配置文件的顺序

首先会读取/etc/profile/etc/profile.d/*.sh,接着读~/.bash_profile,~/.bashrc,在读/etc/bashrc

/etc/profile--->/etc/profile.d/*.sh--->~/.bash_profile--->~/.bashrc--->/etc/bashrc 如有冲突,最后被source的生效

 

非交互式:

su 用户名

图形界面的终端也是非交互式登录

执行脚本的时候需要使用解释器来解释执行,解释器在解释脚本时会读取配置文件先设置解释环境的

/etc/bashrc:全局

~/.bashrc:个人配置

对于非交互式用户来讲是读取配置文件的顺序

~/.bashrc---> /etc/bashrc--->/etc/profile.d/*.sh

 

 

通知shell重读配置文件的命令:source .bashrc或者 . .bashrc

bash的编程

程序有3中执行流程:

1. 顺序执行:如果有很多命令的时候,自上而下逐条被执行,

2. 选择执行: 选择执行肯定会有n个分支,事先有个条件判断,符合条件的分支将被执行,不符合分支的条件将不被执行

3. 循环执行:对于计算机而言拉磨式的执行。即对同一段代码反复执行有限次,所以必须要有退出条件,否则会进入无限循环

若想实现以上流程的定义需要用到所谓的编程控制语句,此前声明变量,为变量赋值的我们称之为赋值语句

 

所以一个程序代码是由语句和表达式组成的。为了实现定义以上的流程就会用到控制语句

 

控制语句:

bash的循环控制语句:for while until

 

for 循环是一种事先就知道循环次数的,遍历指定列表的方式来实现的循环。

 

for 变量名 in 列表; do

语句1

语句2

done

 

for 语句中变量名是用来变量赋值而非引用变量,不能使用$,切记

 

使用for循环添加三个用户

 

分析:使用useradd添加用户,执行3遍,这三遍当中如果那个用户,每一遍都使用同一个变量来引用,而每一遍执行的时候都把变量的值改一下就可以实现了


for usreName in shuguang liming huanghun;do

useradd $userName

done

当程序执行这段代码的时候,首先会把shuguang的这个字符串赋值给userName这个变量,而后执行useradd $userName这条语句,执行完就done结束了,然后进入下一次循环,将liming这个字符串赋值给userName这个变量,而后执行useradd $userName这个语句,执行完就done结束了,然后进入下一次循环,直到遍历完整个列表。所以列表中存储的元素的个数决定循环的次数。

[root@Centos6 ~]# cat autouseradd.sh

#!/bin/bash

 

for userName in shuguang liming huanghun;do

   useradd $userName

done

检测脚本是否有语法错误

[root@Centos6 ~]# bash -n autouseradd.sh

执行脚本

[root@Centos6 ~]# bash autouseradd.sh

验证三个用户是否添加成功

[root@Centos6 ~]# tail -3 /etc/passwd

shuguang:x:500:500::/home/shuguang:/bin/bash

liming:x:501:501::/home/liming:/bin/bash

huanghun:x:502:502::/home/huanghun:/bin/bash

 

使用for循环添加10个用户,分别为user101-user110

分析:for循环的列表中有10个用户,写起来也很繁琐

列表生成的方法:只要能够实现在命令行中展开的功能都可以生成列表

生成数字序列:

可以使用花括号 {start..end} {1..10}

可以使用seq start end

[root@Centos6 ~]# seq 1 10

1

2

3

4

5

6

7

8

9

10

[root@Centos6 ~]#

很显然seq命令既然执行后生成序列,我们做个命令的引用就可以生成列表

[root@Centos6 ~]# seq 1 2 10  其中2为步长

1

3

5

7

9

[root@Centos6 ~]# for userName in $(seq 101 110);do echo $userName;done

101

102

103

104

105

106

107

108

109

110

[root@Centos6 ~]# for userName in $(seq 101 110);do echo user$userName;done

user101

user102

user103

user104

user105

user106

user107

user108

user109

user110

直接把echo换成useradd就循环添加10user101-user110的用户了

[root@Centos6 ~]# for userName in $(seq 101 110);do useradd user$userName;done

[root@Centos6 ~]# tail -10 /etc/passwd

user101:x:503:503::/home/user101:/bin/bash

user102:x:504:504::/home/user102:/bin/bash

user103:x:505:505::/home/user103:/bin/bash

user104:x:506:506::/home/user104:/bin/bash

user105:x:507:507::/home/user105:/bin/bash

user106:x:508:508::/home/user106:/bin/bash

user107:x:509:509::/home/user107:/bin/bash

user108:x:510:510::/home/user108:/bin/bash

user109:x:511:511::/home/user109:/bin/bash

user110:x:512:512::/home/user110:/bin/bash

或者

[root@Centos6 ~]# cat useradd.sh

#!/bin/bash

for userName in `seq 101 110`;do

useradd user$userName

echo "Add user$userName successfully."

done

文本处理类命令:wc

[root@Centos6 ~]# wc /etc/issue

 3  9 47 /etc/issue  3行,9个单词,47个字节

 wc [option] [file]...

 -l:统计行数

 -c:统计字节数

 -w:统计单词数

 

 写一个脚本,用for循环实现

 1.显示/etc/init.d/functions,/etc/rc.d/rc.sysinit/etc/fstab各有多上行

 #!/bin/bash

for wcline in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab;do

  echo "$wcline的行数为:" `cat $wcline | wc -l`

done

或者

[root@Centos6 ~]# cat wcline.sh

#!/bin/bash

for wcline in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab;do

  echo "$wcline: `wc -l $wcline | cut -d‘ ‘ -f1` lines;"

done

或者

[root@Centos6 ~]# cat wcline.sh

#!/bin/bash

for wcline in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab;do

  lineCount=`wc -l $wcline | cut -d‘ ‘ -f1`

  echo "$wcline: $lineCount lines;"

done

 2.将上题中三个文件复制到/tmp目录中,分别将每个文件的最近一次修改时间改为20163151327

 for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab;do

  cp - $fileName /tmp

  touch -m -t 201603151327 /tmp/`basename $fileName`

done

[root@Centos6 tmp]# ll functions rc.sysinit fstab

-rw-r--r-- 1 root root   866 Mar 15 13:27 fstab

-rw-r--r-- 1 root root 18586 Mar 15 13:27 functions

-rwxr-xr-x 1 root root 19688 Mar 15 13:27 rc.sysinit

 3.显示/etc/passwd中第3,7,11个用户的用户名和用户id

 [root@Centos6 tmp]# cat uid.sh

#!/bin/bash

 

for lineNo in 3 7 11;do

  head -n $lineNo /etc/passwd | tail -1 | cut -d: -f1,3

done

[root@Centos6 tmp]# bash uid.sh

daemon:2

shutdown:6

operator:11

 

 4.file命令显示/var/log目录下的每个文件的内容类型

[root@Centos6 ~]# cat file.sh

#!/bin/bash

dirName=/var/log

for fileName in $dirName/*;do

file $fileName

done

执行脚本,验证结果

[root@Centos6 ~]# bash file.sh

/var/log/anaconda.ifcfg.log: ASCII text

/var/log/anaconda.log: ASCII English text

/var/log/anaconda.program.log: ASCII English text, with very long lines, with overstriking

/var/log/anaconda.storage.log: ASCII C++ program text, with very long lines

/var/log/anaconda.syslog: ASCII English text, with very long lines

/var/log/anaconda.xlog: ASCII English text

/var/log/anaconda.yum.log: ASCII text

/var/log/audit: directory

/var/log/boot.log: ASCII English text, with CRLF, CR line terminators, with escape sequences

/var/log/btmp: empty

/var/log/ConsoleKit: directory

 

for总结:

通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环

生成列表的总结:

1. 直接给出列表

2. 使用文件名通配的方式生成序列

3. 可以使用{}seq命令生成数字序列

4. 使用命令生成 catls

 

bash中的算数运算

 

bash中无需事先声明变量,bash是一种弱类型的语言,无需区分变量类型,既然不用区分类型,变量中数据存储的默认格式是字符串,所以字符串是不能进行数值运算的,

 

[root@Centos6 ~]# num1=1

[root@Centos6 ~]# num2=3

[root@Centos6 ~]# $num1+$num2

-bash: 1+3: command not found

[root@Centos6 ~]# sum=$num1+$num2

[root@Centos6 ~]# echo $sum

1+3

[root@Centos6 ~]#

 

若想进行数值运算:

 

declare

-i: 整形

-x: 环境变量

 

let varName=算数表达式

varName=$[算数表达式]

varName=$((算数表达式))

varName=`expr $num1 + $num2`

[root@Centos6 ~]# aa=$[$num1*$num2]

[root@Centos6 ~]# echo $aa

3

[root@Centos6 ~]# let sum=$num1+$num2

[root@Centos6 ~]# echo $sum

4

[root@Centos6 ~]# aa=$(($num1*$num2))

[root@Centos6 ~]# echo $aa

3

[root@Centos6 ~]# expr $num1 + $num2

4

操作符:+ - * / %

bash不能进行浮点计算

[root@Centos6 ~]# let er=$num1/$num2

[root@Centos6 ~]# echo $er

0

自加运算

total=$[$total+1]

let total+=1

let total++

[root@Centos6 ~]# a=40

[root@Centos6 ~]# a=$[$a+2]

[root@Centos6 ~]# echo $a

42

[root@Centos6 ~]# a=40

[root@Centos6 ~]# echo $a

40

[root@Centos6 ~]# let a+=2

[root@Centos6 ~]# echo $a

42

[root@Centos6 ~]#

练习

1. 计算100以内所有正整数之和

 

每次都是sum自身的基础上加i

[root@Centos6 ~]# cat sum.sh

#!/bin/bash

 

declare -i sum=0

for i in {1..100};do

 let sum=$sum+$i

done

echo "the sum is: $sum"

执行脚本

[root@Centos6 ~]# bash sum.sh

the sum is: 5050

可以单步执行时加-x参数

[root@Centos6 ~]# bash -x sum.sh

+ declare -i sum=0

+ for i in ‘{1..100}‘

+ let sum=0+1

+ for i in ‘{1..100}‘

+ let sum=1+2

+ for i in ‘{1..100}‘

+ let sum=3+3

 

2. 分别计算100以内所有偶数之和和奇数之和

[root@Centos6 ~]# cat oddsum.sh

#!/bin/bash

declare -i oddsum=0,evensum=0

for i in `seq 2 2 100`;do

  oddsum=$[$oddsum+$i]

done

 

for j in `seq 1 2 100`;do

  evensum=$[$evensum+$j]

done

echo "the evensum is $evensum,the odd sum is: $oddsum"

 

3. 计算当前系统所有用户的ID之和

 

[root@Centos6 ~]# cat useridsum.sh

#!/bin/bash

declare -i uidSum=0

for i in `cut -d: -f3 /etc/passwd`; do

  uidSum=$[$uidSum+$i]

done

  echo "the UIDSum is: $uidSum"

执行脚本结果如下:

[root@Centos6 ~]# bash useridsum.sh

the UIDSum is: 70943

 

4. 计算/etc/init.d/functions /etc/rc.d/rc.sysinit /etc/issue三个文件的字符数之和

[root@Centos6 ~]# cat bytecount.sh

#!/bin/bash

 

declare -i bytesCount=0

for file in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/issue; do

  let bytesCount=$bytesCount+`wc -c $file | cut -d‘ ‘ -f1`

done

  echo $bytesCount

执行脚本的结果

[root@Centos6 ~]# bash bytecount.sh

38321

 

5. 新建用户user1-user10,并计算用户的id之和

[root@Centos6 ~]# cat userid.sh

#!/bin/bash

declare -i uidSum=0

for i in `seq 1 10`; do

  useradd user$i

  let uidSum=$uidSum+`id -u user$i`

done

echo  $uidSum

执行脚本

[root@Centos6 ~]# bash userid.sh

5195

 

位置参数:

$0:脚本自身

$1:脚本的第一个参数

$2:

[root@Centos6 ~]# cat pos.sh

#!/bin/bash

 

echo $1

echo $2

echo $0

[root@Centos6 ~]# chmod +x pos.sh

[root@Centos6 ~]# ./pos.sh 5 9

5

9

./pos.sh

[root@Centos6 ~]# cat pos.sh

#!/bin/bash

 

echo "the sum is: $[$1+$2]."

[root@Centos6 ~]# ./pos.sh 10 20

the sum is: 30.

$# 引用位置参数的个数

[root@Centos6 ~]# cat pos.sh

#!/bin/bash

 

echo "the sum is: $[$1+$2]."

echo "the mul is: $[$1*$2]."

 

echo $#

 

[root@Centos6 ~]# ./pos.sh 10 20 3 8

the sum is: 30.

the mul is: 200.

4

$* 引用所有的位置参数

[root@Centos6 ~]# cat ./pos.sh

#!/bin/bash

 

echo "the sum is: $[$1+$2]."

echo "the mul is: $[$1*$2]."

 

echo $#

echo $*

[root@Centos6 ~]# ./pos.sh 4 5 7 7

the sum is: 9.

the mul is: 20.

4

4 5 7 7

 

交互式脚本

给变量默认值

varName=${varName:-value}

如果varName不空,则返回varName的值,否则返回value的值

如果varName不空,则其值不变;否则,varName会使用value作为其值

[root@Centos6 ~]# echo $a

42

[root@Centos6 ~]# a=${a:-45}

[root@Centos6 ~]# echo $a

42

[root@Centos6 ~]# unset a

[root@Centos6 ~]# a=${a:-45}

[root@Centos6 ~]# echo $a

45

举例:

[root@Centos6 ~]# cat read1.sh

#!/bin/bash

read -t 5 -p "Enter a number:" num1

num1=${num1:-0}

echo $num1

[root@Centos6 ~]# bash read1.sh

Enter a number:6

6

5秒钟不输入任何数字,num1的值为0

[root@Centos6 ~]# bash read1.sh

Enter a number:0

 

[root@Centos6 ~]# read a b

50 100

[root@Centos6 ~]# echo $a

50

[root@Centos6 ~]# echo $b

100

[root@Centos6 ~]# read c d

30

[root@Centos6 ~]# echo $c

30

[root@Centos6 ~]# echo $d

 

[root@Centos6 ~]#

 

[root@Centos6 ~]# read e f

2 4 5 6 7

[root@Centos6 ~]# echo $e

2

[root@Centos6 ~]# echo $f

4 5 6 7

[root@Centos6 ~]#

 

练习:

1. 通过键盘给定一个文件路径,来判断文件内容类型:

[root@Centos6 ~]# cat yyy.sh

#!/bin/bash

read -p "Enter a file path: " filename

file $filename

[root@Centos6 ~]# bash yyy.sh

Enter a file path: /etc/fstab

/etc/fstab: ASCII text

 

bash编程之条件判断

条件判断的目的是:判定后续操作的前提条件是否满足

条件判断的常用类型:

整数测试:

字符测试:

文件测试:

布尔值:

真,假

逻辑运算:

与运算:

&& =

&& =

&& =

&& =

 或运算

  || =

|| =

|| =

|| =

非运算

!真 =

!假 =

bash如何做测试

1 test 表达式

2 [ 表达式 ] 表达式两端必须要有空格

 

在什么样的场景中使用bash条件测试

bash中条件判断使用if

单分支

if 条件; then

分支1

fi

双分支

if 条件; then

分支1

else

分支2

fi

多分支

if 条件1then

分支1

elif 条件2; then

分支2

elif 条件3; then

分支3

...

else

分支n;

fi

只要命令用作条件,就表示引用的是其状态结果(即执行成功与否),而非命令的输出结果,因此,不能使用命令替换符(``,$(),只有将命令执行的结果保存到变量当中,或引用命令执行结果时需要使用反撇号$()

练习:

1. 让用户指定一个文件,判定如果文件有空白行,就显示空白行数

 

[root@Centos6 ~]# cat yin.sh

#!/bin/bash

#

read -p "Enter a file path: " filename

 

if grep "^$" $filename &> /dev/null; then

  linesCount=`grep "^$" $filename | wc -l`

  echo "$filename has $linesCount space lines."

fi

执行结果

[root@Centos6 ~]# bash yin.sh

Enter a file path: /etc/rc.d/rc.sysinit

/etc/rc.d/rc.sysinit has 96 space lines.

如果输入/etc/passwd,由于没有空格,分支语句将不会被执行。

[root@Centos6 ~]# bash yin.sh

Enter a file path: /etc/passwd

[root@Centos6 ~]#

 

2. 让用户指定一个文件,判定如果文件有空白行,就显示空白行数,如果没有空白行,就显示没有空白行

#!/bin/bash

#

read -p "Enter a file path: " filename

 

if grep "^$" $filename &> /dev/null; then

  linesCount=`grep "^$" $filename | wc -l`

  echo "$filename has $linesCount space lines."

else

  echo "$filename hava no space line."

fi

执行结果

[root@Centos6 ~]# bash yin.sh

Enter a file path: /etc/passwd

/etc/passwd hava no space line.

 

3. bash整数测试

二元测试

-gt:大于 [ $num1 -gt $num2 ]

-lt:小于

-ge:大于等于

-le:小于等于

-ne:不等于

-eq:等于

练习:

1. 用户通过命令行输入两个数字,比较大小,整数是通过命令行参数传递而来的

[root@Centos6 ~]# cat euu.sh

#!/bin/bash

#

if [ $1 -gt $2 ]; then

  echo "the max num is $1."

else

  echo "the max num is $2."

fi

[root@Centos6 ~]# chmod +x euu.sh

[root@Centos6 ~]# ./euu.sh 67 98

the max num is 98.

[root@Centos6 ~]# ./euu.sh 12 30

the max num is 30.

 

脚本自定义退出:

[root@Centos6 ~]# cat exit.sh

#!/bin/bash

echo "hello"

exit 6

echo "world"

执行脚本

[root@Centos6 ~]# bash exit.sh

hello

[root@Centos6 ~]# echo $?

6

如果注释exit 6

[root@Centos6 ~]# cat exit.sh

#!/bin/bash

echo "hello"

#exit 6

echo "world"

执行脚本

[root@Centos6 ~]# bash exit.sh

hello

world

[root@Centos6 ~]# echo $?

0

修改脚本为

[root@Centos6 ~]# cat exit.sh

#!/bin/bash

ls /etcccc

echo "hello"

#exit 6

echo "world"

执行脚本

[root@Centos6 ~]# bash exit.sh

ls: cannot access /etcccc: No such file or directory

hello

world

[root@Centos6 ~]# echo $?

0

判断两个数字的大小,如果用户只输入1个数字,没有办法判断,所以还可以补充一下上面的脚本

[root@Centos6 ~]# cat euu.sh

#!/bin/bash

#

if [ $# -lt 2 ]; then

  echo "stupid..."

  echo "`basename $0` argu1 argu2"

  exit 4

fi

 

if [ $1 -gt $2 ]; then

  echo "the max num is $1."

else

  echo "the max num is $2."

fi

执行脚本的的结果如下

[root@Centos6 ~]# ./euu.sh 20

stupid...

euu.sh argu1 argu2

[root@Centos6 ~]# ./euu.sh 20 10

the max num is 20.

 

练习:

1. 写一个脚本,实现如下功能

   让用户通过键盘输入一个用户名,如果用户存在,就显示其用户名和uid否则就显示用户名不存在

[root@Centos6 ~]# cat aa2.sh

#!/bin/bash

read -t 10 -p "Enter a username:" username

# username-${username:-root}

if id $username &> /dev/null; then

  userid=`id -u $username`

  echo "$username: $userid"

else

  echo "$username not exist."

fi   

执行脚本

[root@Centos6 ~]# bash aa2.sh

Enter a username:huarong

huarong not exist.

[root@Centos6 ~]# bash aa2.sh

Enter a username:user1

user1: 515

2. 让用户通过键盘输入一个用户名,如果用户不存在就退出,如果用户的uid大于等于500,就说明他是普通用户,否则就说明是管理员或系统用户

[root@Centos6 ~]# cat aa3.sh

#!/bin/bash

read -p "Enter a username:" username

 

if ! id $username &> /dev/null; then

  echo "$usernam not exist."

  exit 6

fi

 

userid=`id -u $username`

if [ $userid -ge 500 ]; then

   echo "A common user;"

else

   echo "Admin or system user;"

fi

执行脚本

[root@Centos6 ~]# bash aa3.sh

Enter a username:root

Admin or system user;

[root@Centos6 ~]# bash aa3.sh

Enter a username:user1

A common user;

 

3. 让用户通过键盘输入一个用户名,如果用户不存在就退出,如果其UID等于GID,就说他是一个"good guy",否则就说他是个"bad guy"

 

[root@Centos6 ~]# cat aa4.sh

#!/bin/bash

read -p "Enter a username:" username

 

if ! id $username &> /dev/null; then

  echo "$usernam not exist."

  exit 6

fi

 

if [ `id -u $username` -eq `id -g $username` ]; then

   echo "good guy"

else

echo "bad guy"

fi

执行脚本

 

4. 判断当前系统上的所有用户是good guy还是bad by

for username in `cut -d: -f1 /etc/passwd`; do

  if [ `id -u $username` -eq `id -g $username` ]; then

   echo "good guy"

else

echo "bad guy"

fi

done

 

5. 写一个脚本,实现如下功能:

    添加10个用户stu1-stu10,但要先判断用户是否存在,如果存在,就显示其已经存在,否则就添加此用户,,最后显示一共添加了几个用户

[root@Centos6 ~]# cat aa5.sh

#!/bin/bash

declare -i usercount=0

for i in {1..10}; do

  if id stu$i &> /dev/null; then

     echo "stu$i exists."

  else

     useradd stu$i && echo "stu$i add finished."

     let usercount++

  fi

done

  echo "add $usercount users;"

6. 200以内所有3的整数倍的正整数之和

[root@Centos6 ~]# cat sum1.sh

#!/bin/bash

declare -i sum=0

for i in {1..200}; do

  if [ $[$i%3] -eq 0 ]; then

     let sum+=$i

  fi

done

  echo "the sum is: $sum."

[root@Centos6 ~]# bash sum1.sh

the sum is: 6633.

 

组合条件测试,对条件做逻辑运算

与运算的短路操作

与:

条件1 && 条件2

条件1为假,则最终结果一定为假,因此条件2将不被执行

条件1为真,则最终结果取决于后面条件,因此条件2必须被执行

[root@Centos6 ~]# username=root

[root@Centos6 ~]# id $username && echo "$username exist"

uid=0(root) gid=0(root) groups=0(root)

root exist

[root@Centos6 ~]# username=roooot

[root@Centos6 ~]# id $username && echo "$username exist"

id: roooot: No such user

[root@Centos6 ~]#

或:

条件1 || 条件2

条件1为真,则最终结果一定为真,因此条件2将不被执行。

ot@Centos6 ~]# username=root

[root@Centos6 ~]# id $username &> /dev/null || echo "$username not  exist"

[root@Centos6 ~]#

条件2为假,则最终结果取决于后面条件,因此条件2必须被执行

[root@Centos6 ~]# username=roooot

[root@Centos6 ~]# id $username &> /dev/null || echo "$username not  exist"

roooot not  exist

[root@Centos6 ~]# id $username &> /dev/null && echo "$username exist." || echo "$username not  exist"

root exist.

[root@Centos6 ~]# username=rootttt

[root@Centos6 ~]# id $username &> /dev/null && echo "$username exist." || echo "$username not  exist"

rootttt not  exist

非:! 条件

 

bash编程之字符测试

   双目:

       >

       <

      ==等于,等值比较

      ~~:左侧是字符串,右侧是一个模式,判定左侧的字符串能否右侧的模式所匹配,通常只在[[]中使用,模式中可以使用行首,行尾锚定符,但模式不要叫引号

    单目:

    -n $stringvar:字符串是否不空,不空为真,空则为假

    -z $stringvar:字符串是否为空,空则为真,不空则假

 

stringA="root"

stringB="hello"

[ "stringA" == "stringB" ]

echo $?

1

stringB="root"

 

双引号不能被省略

 

[root@centos01 ~]# clear

[root@centos01 ~]# stringA="root"

[root@centos01 ~]# [ -n "$stringA" ]

[root@centos01 ~]# echo $?

0

[root@centos01 ~]#

 

[root@centos01 ~]# [ -z "$stringA" ]

[root@centos01 ~]# echo $?

1

[root@centos01 ~]# [ -z "$stringB" ]

[root@centos01 ~]# echo $?

0

[root@centos01 ~]# [[ "$stringA"] =~ ot ]]

[root@centos01 ~]# echo $?

0

[root@centos01 ~]# [[ "$stringA"] =~ to ]]

[root@centos01 ~]# echo $?

1

[root@centos01 ~]#

判定某用户的默认shell是以sh结尾的

[root@centos01 ~]# [[ `grep "^$username\>" /etc/passwd | cut -d: -f7` =~ sh$ ]]

[root@centos01 ~]# echo $?

0

判定所有用户是否拥有可登陆shell

[root@centos01 ~]# cat aa1.sh

#!/bin/bash

for username in `cut -d: -f1 /etc/passwd`; do

 if [[ `grep "^$username\>" /etc/passwd | cut -d: -f7` =~ sh$ ]]; then

    echo "login user: $username"

 else

    echo "nologin user: $username"

 fi

done

 

bash编程之文件测试

单目测试

-e file:

-a file: 测试文件是否存在

-f file /path/to/file:测试是否为普通文件

-d file /path/to/somefile:测试是否为目录文件

-b file /path/to/somefile:测试文件是否为块设备文件

-c file /path/to/somefile:测试文件是否为字符设备文件

-h file /path/to/somefile:测试文件是否为符号链接文件

-p file /path/to/somefile:测试文件是否为管道文件

-r /path/to/somefile 测试其有效用户是否对此文件有读取权限

-w /path/to/somefile 测试其有效用户是否对此文件有写入权限

-x /path/to/somefile 测试其有效用户是否对此文件有执行权限

双目测试

file1 -nt file2:测试file1是否为file2更 新一些

[root@Centos6 tmp]# filename=/tmp/hellodir

[root@Centos6 tmp]# [ -e $filename ] || mkdir $filename

[root@Centos6 tmp]# ls


 

 

 

让用户交互式输入一个用户名,先判定用户是否存在,不存在,则以7为退出码;

判断用户的shell是否为/bin/bash;如果是,则显示为"bash user",退出码为0,否则显示为not bash user,退出码为1

[root@Centos6 ~]# cat aa1.sh

#!/bin/bash

#

read -p "Enter a user name: " username

if ! id $username &> /dev/null; then

  echo "No such user."

  exit 7

fi

 

usershell=`grep "^$username\>" /etc/passwd | cut -d: -f7`

 

if [[ "$usershell" == "/bin/bash" ]]; then

   echo "bash user."

   returnValue=0

else

   echo "Not bash usre."

   returnValue=1

fi

exit $returnValue

执行脚本

[root@Centos6 ~]# bash aa1.sh

Enter a user name: bin

Not bash usre.

[root@Centos6 ~]# echo $?

1

[root@Centos6 ~]# bash aa1.sh

Enter a user name: binnn

No such user.

[root@Centos6 ~]# echo $?

7

[root@Centos6 ~]# bash aa1.sh

Enter a user name: root

bash user.

 

编写一下脚本:

显示如下菜单:

cpu) show cpu info;

mem) show memory info;

quit) quit

enter your option:

如果用户选择cpu,则显示文件/proc/cpuinfo的信息

如果用户选择mem,则显示文件/proc/meminfo的信息

如果用户选择quit,则退出,且退出码为5

如果用户键入其他字符,则显示未知选项,请重新执行脚本,退出码为6

[root@Centos6 ~]# bash aa6.sh

cpu) print cpu information

mem) print memory information

quit) Quit

Enter your option: quit

quit

[root@Centos6 ~]# cat aa6.sh

#!/bin/bash

#

returnValue=0

cat <<EOF

cpu) print cpu information

mem) print memory information

quit) Quit

EOF

 

read -p "Enter your option: " useroption

useroption=`echo $useroption | tr ‘A-Z‘ ‘a-z‘`

if [[ "$useroption" == "cpu" ]];then

  cat /proc/cpuinfo

elif [[ "$useroption" == "mem" ]];then

  cat /proc/meminfo

elif [[ "$useroption" == "quit" ]];then

  echo "quit"

  returnValue=6

else

  echo "unkown option"

  returnValue=7

fi

exit $returnValue

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


本文出自 “apache” 博客,请务必保留此出处http://xiaorenwutest.blog.51cto.com/12754924/1913280

bash shell的基本概述与操作

标签:工作环境   linux   用户   

原文地址:http://xiaorenwutest.blog.51cto.com/12754924/1913280

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!