加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

解释器概述 shell基础 shell变量

发布时间:2020-12-15 22:22:02 所属栏目:安全 来源:网络整理
导读:Top NSD SHELL DAY01 案例1:Shell基础应用 案例2:简单Shell脚本的设计 案例3:使用Shell变量 案例4:变量的扩展应用 1 案例1:Shell基础应用 1.1 问题 本案例要求熟悉Linux Shell环境的特点,主要练习以下操作: 切换用户的Shell环境 练习命令历史、命令别
Top

NSD SHELL DAY01

  1. 案例1:Shell基础应用
  2. 案例2:简单Shell脚本的设计
  3. 案例3:使用Shell变量
  4. 案例4:变量的扩展应用

1 案例1:Shell基础应用

1.1 问题

本案例要求熟悉Linux Shell环境的特点,主要练习以下操作:

  1. 切换用户的Shell环境
  2. 练习命令历史、命令别名
  3. 重定向标准输入/输出/错误输出
  4. 管道操作实践

1.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:切换用户的Shell环境

若需要临时使用另一种Shell环境,可以直接执行对应的Shell解释器程序,比如只要执行ksh可以切换到ksh命令行环境。

  1. [[email?protected] ~]# yum -y install ksh ????????????//若缺少ksh请先安装ksh包
  2. .. ..
  3. [[email?protected] ~]# cat /etc/shells
  4. /bin/sh
  5. /bin/bash
  6. /sbin/nologin
  7. /bin/tcsh
  8. /bin/csh
  9. /bin/ksh????????????????????????????????????????//确认当前系统已识别ksh
  10. [[email?protected] ~]# ksh ????????????????????????????//进入ksh环境
  11. [[email?protected]]~# exit ????????????????????????????//返回到切换前的bash环境

若希望修改用户的登录Shell,管理员可以直接通过usermod命令设置。比如,以下操作可将用户zhangsan的登录Shell改为/bin/ksh:

  1. [[email?protected] ~]# usermod -s /bin/ksh zhangsan ????????????//执行修改操作
  2. [[email?protected] ~]# grep ‘zhangsan‘ /etc/passwd
  3. zhangsan:x:516:516::/home/zhangsan:/bin/ksh ????????????//修改后

步骤二:练习命令历史

1)检查历史命令的容量。

默认记录1000条,通过全局变量HISTSIZE设置,对所有用户有效:

  1. [[email?protected] ~]# grep HISTSIZE /etc/profile
  2. HISTSIZE=1000

查看已为当前用户记录的历史命令条数:

  1. [[email?protected] ~]# history | wc -l
  2. 1000

2)查看历史命令列表。

列出最近执行的10条历史命令:

  1. [[email?protected] ~]# history | tail
  2. 1028 grep ‘zhangsan‘ /etc/passwd
  3. 1029 cat /etc/redhat-release
  4. 1030 usermod -s /bin/tcsh zhangsan
  5. 1031 grep ‘zhangsan‘ /etc/passwd
  6. 1032 su - zhangsan
  7. 1033 echo 1234567 | passwd --stdin zhangsan
  8. 1034 su - zhangsan
  9. 1035 grep HISTSIZE /etc/profile
  10. 1036 history | wc -l
  11. 1037 history | tail

3)调用指定的历史命令。

重新执行历史命令列表中的第1028条操作:

  1. [[email?protected] ~]# !1028
  2. grep ‘zhangsan‘ /etc/passwd
  3. zhangsan:x:516:516::/home/zhangsan:/bin/bash

重新执行最近一次以cat开头(根据实际情况变更)的历史命令操作:

  1. [[email?protected] ~]# !cat
  2. cat /etc/redhat-release
  3. Red Hat Enterprise Linux Server release 5.9 (Tikanga)

4)清空已记录的历史命令。

  1. [[email?protected] ~]# history -c ????????????????????//清空自己的历史命令
  2. [[email?protected] ~]# > ~/.bash_history ???????????? //清空记录文件
  3. [[email?protected] ~]# history ????????????????????????//再次检查历史命令列表
  4. 42 > ~/.bash_history
  5. 43 history

步骤三:练习命令别名

1)查看已经定义的命令别名列表。

当前的别名列表:

  1. [[email?protected] ~]# alias
  2. alias cp=‘cp -i‘
  3. alias l.=‘ls -d .* --color=tty‘
  4. alias ll=‘ls -l --color=tty‘
  5. alias ls=‘ls --color=tty‘
  6. alias mv=‘mv -i‘
  7. alias rm=‘rm -i‘
  8. alias which=‘alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde‘

别名设置一般存放在用户的.bashrc文件内:

  1. [[email?protected] ~]# grep ‘^alias‘ ~/.bashrc
  2. alias rm=‘rm -i‘
  3. alias cp=‘cp -i‘
  4. alias mv=‘mv -i‘

2)自定义新的命令别名

添加一个名为lh的命令别名,实际执行的是“ls –lh –color=tty”:

  1. [[email?protected] ~]# alias lh=‘ls -lh‘ ????????????????????//定义别名命令lh
  2. [[email?protected] ~]# alias lh ????????????????????????????//确认定义结果
  3. alias lh=‘ls -lh‘

验证别名命令的效果:

  1. [[email?protected] ~]# lh /etc/fstab ????????????????????????//使用别名
  2. -rw-r--r-- 1 root root 733 10-09 15:34 /etc/fstab
  3. [[email?protected]5 ~]# ls -lh /etc/fstab ????????????????????//使用完整的命令
  4. -rw-r--r-- 1 root root 733 10-09 15:34 /etc/fstab

3)取消别名

取消单个别名:

  1. [[email?protected] ~]# unalias lh ????????????????????????//取消名为lh的命令别名
  2. [[email?protected] ~]# alias lh ????????????????????????????//查询时已没有lh
  3. -bash: alias: lh: not found

步骤四:重定向标准输入/输出/错误输出

标准输入(stdin),描述号为0;标准输出(stdout),描述号为1;标准错误(stderr),描述号为2。

1)重定向标准输出。

使用 > 将命令执行的正常输出重定向到文件:

  1. [[email?protected] ~]# ls -ld /etc/????????????????????????//正常应输出到屏幕
  2. drwxr-xr-x. 140 root root 8192 8月 2 04:45 /etc/
  3. [[email?protected] ~]# ls -ld /etc/ > stdout.txt ????????????//重定向到文件
  4. [[email?protected] ~]# cat stdout.txt ????????????????????//确认重定向输出的结果
  5. drwxr-xr-x. 140 root root 8192 8月 2 04:45 /etc/

> 操作会覆盖目标文件(先清空、再写入):

  1. [[email?protected] ~]# echo "I am the king." > stdout.txt ????????//覆盖目标文件
  2. [[email?protected] ~]# cat stdout.txt ????????????????????????//确认结果
  3. I am the king.

改用 >> 可实现追加重定向输出:

  1. [[email?protected] ~]# ls -ld /etc/ >> stdout.txt ????????????//追加输出
  2. [[email?protected] ~]# cat stdout.txt
  3. I am the king. ????????????????????????????????????????//原有内容还保留
  4. drwxr-xr-x. 140 root root 8192 8月 2 04:45 /etc/

2)重定向标准错误。

对于命令执行出错的信息,使用 > 无法保存,仍然会输出到屏幕。比如,可使用ls命令同时查看两个对象(其中nb.txt并不存在),重定向输出:

  1. [[email?protected] ~]# ls -l nb.txt /etc/fstab > stderr.txt
  2. [[email?protected] ~]# cat stderr.txt ????????????????//正常信息成功重定向到目标文件
  3. -rw-r--r--. 1 root root 541 1月 5 2017 /etc/fstab

使用 2> 可重定向错误信息,比如,可执行一个错误的命令:

  1. [[email?protected] ~]# ls -l nb.txt /etc/fstab 2> stderr.txt
  2. -rw-r--r--. 1 root root 541 1月 5 2017 /etc/fstab
  3. //正确的信息默认输出至屏幕,错误信息重定向到目标文件
  4. [[email?protected] ~]# cat stderr.txt????????????????????????//从文件中查看出错信息
  5. ls: nb.txt: 没有那个文件或目录

类似的,2>> 可实现追加输出:

  1. [[email?protected] ~]# ls tmpfile 2>> stderr.txt
  2. [[email?protected] ~]# cat stderr.txt
  3. ls: nb.txt: 没有那个文件或目录
  4. ls: tmpfile: 没有那个文件或目录

若希望将正常输出、错误输出重定向同一个文件,可使用 &> :

  1. [[email?protected] ~]# ls -l nb.txt /etc/fstab &> stderr.txt
  2. [[email?protected] ~]# cat stderr.txt
  3. ls: nb.txt: 没有那个文件或目录
  4. -rw-r--r--. 1 root root 541 1月 5 2017 /etc/fstab

3)重定向标准输入。

  1. [[email?protected] ~]# mail –s Error root < /etc/passwd

4)案例

  1. [[email?protected] ~]# cat /root/test.sh
  2. #!/bin/bash
  3. for i in {1..10}
  4. do
  5. ????????????useradd user$i 2>>/root/user.log
  6. ????????????echo ‘123456‘ | passwd --stdin user$i >/dev/null
  7. done

步骤五:管道操作实践

借助于管道符“|”,可以将一条命令的标准输出交给另一条命令处理,在一条命令行内可依次使用多个管道。

1)统计/etc/目录下资料的数量。

  1. [[email?protected] ~]# ls -l /etc | wc -l
  2. 254

2)列出Yum库里名称中含cluster的软件包。

  1. [[email?protected] ~]# yum list | grep cluster
  2. cluster-cim.x86_64 ????????????????0.12.1-7.el5 ????RHEL5-Cluster
  3. cluster-snmp.x86_64 ????????????????0.12.1-7.el5 ????RHEL5-Cluster
  4. … …

2 案例2:简单Shell脚本的设计

2.1 问题

本案例要求编写三个脚本程序,分别实现以下目标:

  1. 在屏幕上输出一段文字“Hello World”
  2. 能够为本机快速配好Yum仓库
  3. 能够为本机快速装配好vsftpd服务

2.2 方案

一个规范的Shell脚本构成包括:

  • 脚本声明(需要的解释器、作者信息等)
  • 注释信息(步骤、思路、用途、变量含义等)
  • 可执行语句(操作代码)

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:编写第一个Shell脚本,输出“Hello World”

1)根据手动任务操作编写脚本文件

  1. [[email?protected] ~]# vim /root/first.sh
  2. #!/bin/bash
  3. echo ‘Hello World‘
  4. [[email?protected] ~]# chmod +x /root/first.sh ????????????????????//添加可执行权限

2)执行脚本,测试效果

  1. [[email?protected] ~]# /root/first.sh
  2. Hello World

3)Shell脚本的执行方式:

方法一,作为“命令字”:指定脚本文件的路径,前提是有 x 权限

  1. [[email?protected] ~]# ./first.sh????????????????????????????//指定相对路径
  2. [[email?protected] ~]# /root/first.sh????????????????????????//指定绝对路径

方法二,作为“参数”:使用bash、sh、source来加载脚本文件

  1. [[email?protected] ~]# bash first.sh????????????????????????//开启子进程
  2. [[email?protected] ~]# sh????????first.sh????????????????????????//开启子进程
  3. [[email?protected] ~]# source first.sh????????????????????????//不开启子进程

步骤二:编写为本机快速配Yum仓库的Shell脚本

1)Yum仓库配置文件的参考内容如下:

  1. [[email?protected] ~]# cat /etc/yum.repos.d/rhel.repo
  2. [rhel]
  3. name=redhat
  4. baseurl=file:///misc/cd
  5. enabled=1
  6. gpgcheck=0

2)根据参考文件的内容,编写脚本内容如下:

  1. [[email?protected] ~]# vim /root/yum.sh
  2. #!/bin/bash
  3. rm -rf /etc/yum.repos.d/*.repo
  4. echo ‘[rhel]
  5. name=redhat
  6. baseurl=file:///misc/cd
  7. gpgcheck=0
  8. ‘ > /etc/yum.repos.d/rhel.repo
  9. [[email?protected] ~]# chmod +x /root/yum.sh ????????????????????//添加可执行权限

3)执行脚本,测试效果

执行配置Yum仓库的脚本:

  1. [[email?protected] ~]# /root/yum.sh

检查配置结果:

  1. [[email?protected] ~]# ls /etc/yum.repos.d/* ????????????????????????//仓库配置已建立
  2. /etc/yum.repos.d/rhel.repo
  3. [[email?protected] ~]# yum repolist ????????????????????????????????//Yum仓库已可用
  4. rhel-packages | 3.9 kB 00:00 ...
  5. rhel-packages/primary_db | 3.1 MB 00:00 ...
  6. repo id repo name status
  7. rhel???????????? redhat???????????????????? 3,690
  8. repolist: 3,690

步骤三:编写快速装配vsftpd服务的Shell脚本

1)编写参考脚本文件如下:

  1. [[email?protected] ~]# vim /root/ftpon.sh
  2. #!/bin/bash
  3. yum -y install vsftpd &> /dev/null
  4. systemctl start vsftpd
  5. systemctl enable vsftpd
  6. [[email?protected] ~]# chmod +x /root/ftpon.sh ????????????????//添加可执行权限

3)执行脚本,测试效果

执行快速装配vsftpd服务的脚本:

  1. [[email?protected] ~]# /root/ftpon.sh

确认脚本执行结果:

  1. [[email?protected] ~]# rpm -q vsftpd
  2. vsftpd-3.0.2-10.el7.x86_64
  3. [[email?protected] ~]# systemctl status vsftpd

3 案例3:使用Shell变量

3.1 问题

本案例要求熟悉Shell变量的使用,主要练习或验证下列内容:

  1. 定义/赋值/查看变量
  2. 环境/预定义/位置变量的应用

除了学会建立和引用变量以外,还要认识环境变量PWD、USER、HOME、SHELL,还有预定义变量$0、$$、$?、$#、$*,以及位置变量$1、$2、$10、……的作用。

3.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:变量的定义/赋值/查看

1)新建/赋值变量

新建变量test,赋值“hello world”,通过set命令可以检查变量设置:

  1. [[email?protected] ~]# test=11

2)查看变量

通过echo $变量名 可输出变量值:

  1. [[email?protected] ~]# echo $test
  2. 11

查看变量时,若变量名称与后面要输出的字符串连在一起,则应该以{}将变量名括起来以便区分:

  1. [[email?protected] ~]# echo $testRMB ????????????//无法识别变量名test
  2. [[email?protected] ~]# echo ${test}RMB???? ????????//区分后可以识别
  3. 11RMB

3)撤销自定义变量

若要撤销已有的变量,可使用unset命令:

  1. [[email?protected] ~]# unset test ????????????????//撤销变量test
  2. [[email?protected] ~]# echo $test ????????????????//查看时已无结果

步骤二:使用环境变量

1)查看环境变量相关文件

全局文件为/etc/profile,对所有用户有效;用户文件为~/.bash_profile,仅对指定的用户有效。

查看/etc/profile文件内容:

  1. [[email?protected] ~]# cat /etc/profile
  2. .. ..
  3. HOSTNAME=`/bin/hostname`
  4. HISTSIZE=1000
  5. .. ..
  6. export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC
  7. .. ..

2)使用环境变量

当前用户的环境变量USER记录了用户名、LOGNAME记录了登录名、HOME记录了宿主目录、SHELL记录了登录Shell、HOSTNAME记录主机名、TERM记录终端类型:

  1. [[email?protected] ~]# echo $USER $HOME $SHELL
  2. root /root /bin/bash
  3. [[email?protected] ~]# echo $HOSTNAME
  4. svr5

环境变量PS1表示Shell环境的一级提示符,即命令行提示符(u 用户名、h 主机名、W 工作目录、$ 权限标识):

  1. [[email?protected] src]# echo $PS1 ????????????????//查看默认的一级提示
  2. [[email?protected]h W]$
  3. [[email?protected] src]#PS1=‘hehe#‘ ????????????????//修改一级提示
  4. hehe# ????????????????????????????????????//更改结果
  5. hehe# PS1=‘[u@h W]$ ‘ ????????????????//恢复原有设置
  6. [[email?protected] src]#

环境变量PS2表示二级提示符,出现在强制换行、at任务编辑等场合:

  1. [[email?protected] ~]# echo $PS2 ????????????????????//查看默认的二级提示
  2. >
  3. [[email?protected] src]# cd ????????????????????//强制换行,观察提示符效果
  4. > /root/
  5. [[email?protected] ~]# PS2=‘=> ‘ ????????????????????//手动修改二级提示
  6. [[email?protected] ~]# cd ????????????????????????//再次验证提示符效果
  7. => ~
  8. [[email?protected] ~]# PS2=‘> ‘ ????????????????????//恢复原有设置

3)查看系统变量

使用env可查看所有环境变量:

  1. [[email?protected] src]# env
  2. HOSTNAME=svr5.tarena.com
  3. SHELL=/bin/bash
  4. HISTSIZE=1000
  5. SSH_CLIENT=192.168.4.110 59026 22
  6. OLDPWD=/root
  7. SSH_TTY=/dev/pts/0
  8. USER=root
  9. .. ..

使用set可查看所有变量(包括env能看到的环境变量):

  1. [[email?protected] src]# set
  2. BASH=/bin/bash
  3. BASH_ARGC=()
  4. BASH_ARGV=()
  5. BASH_LINENO=()
  6. .. ..

步骤三:使用位置变量与预定义变量

1)创建一个测试脚本,用来展示。

  1. [[email?protected] ~]# vim location.sh
  2. #!/bin/bash
  3. echo $0????????????????????????????????????????//脚本的名称
  4. echo $1????????????????????????????????????????//第一个参数
  5. echo $2????????????????????????????????????????//第二个参数
  6. echo $*????????????????????????????????????????//所有参数
  7. echo $#????????????????????????????????????????//所有的综合
  8. echo $$????????????????????????????????????????//当前进程的进程号
  9. echo $?????????????????????????????????????????//上一个程序的返回状态码
  10. [[email?protected] ~]# chmod +x location.sh ????????????//添加可执行权限

2)执行脚本location.sh,细心观察结果(高明的武功需要用心参悟)。

  1. [[email?protected] ~]# ./location.sh one 1 2 abc qq 8 7

步骤四:创建账户与修改密码的脚本

1)编写脚本。

  1. [[email?protected] ~]# vim /root/user.sh
  2. #!/bin/bash
  3. useradd $1
  4. echo "$2" |passwd --stdin $1

执行脚本测试:

  1. [[email?protected] ~]# ./user.sh jerry 123456
  2. 更改用户 jerry 的密码 。
  3. passwd: 所有的身份验证令牌已经成功更新。

4 案例4:变量的扩展应用

4.1 问题

本案例要求进一步熟悉Shell变量的赋值控制,主要练习或验证下列内容:

  1. 三种引号对赋值的影响
  2. 使用read命令从键盘读取变量值
  3. 使用export发布全局变量

4.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:三种引号对变量赋值的影响

1)双引号的应用

使用双引号可以界定一个完整字符串。

  1. [[email?protected] ~]# SCHOOL=Tarena IT Group
  2. -bash: IT: command not found ????????????????????//未界定时赋值失败
  3. [[email?protected] ~]# SCHOOL="Tarena IT Group" ????????//界定后成功
  4. [[email?protected] ~]# touch aa bb ????????????????????//创建了两个文件
  5. [[email?protected] ~]# touch "aa bb"????????????????????//创建了一个文件
  6. [[email?protected] ~]# ls????????????????????????????????//查看结果

2)单引号的应用

界定一个完整的字符串,并且可以实现屏蔽特殊符号的功能。

  1. [[email?protected] ~]# echo "$test"
  2. [[email?protected] ~]# echo ‘$test‘

3)反撇号或$()的应用

使用反撇号或$()时,可以将命令执行的标准输出作为字符串存储,因此称为命令替换。

  1. [[email?protected] ~]# tar -czf log-`date +%Y%m%d`.tar.gz /var/log

步骤二:使用read命令从键盘读取变量值

1)read基本用法

执行后从会等待并接受用户输入(无任何提示的情况),并赋值给变量str:

  1. [[email?protected] ~]# read str
  2. What‘s happen ? ????????????????????????//随便输入一些文字,按Enter键提交
  3. [[email?protected] ~]# echo $str ????????????????//查看赋值结果
  4. What‘s happen ?

为了不至于使用户不知所措、莫名其妙,推荐的做法是结合-p选项给出友好提示:

  1. [[email?protected] ~]# read -p "请输入一个整数:" i
  2. 请输入一个整数:240
  3. [[email?protected] ~]# echo $i
  4. 240

2)stty终端显示控制

将回显功能关闭(stty -echo),

将回显功能恢复(stty echo)。

可参考下列操作创建一个测试脚本:

  1. [[email?protected] ~]# vim sttyecho.sh ????????????//创建一个测试脚本
  2. #!/bin/bash
  3. read -p "请输入用户名: " USERNAME ????????????//读取用户名
  4. stty -echo ????????????????????????????????//关闭回显
  5. read -p "请输入密码: " PASSWORD ????????????//读取密码
  6. stty echo ????????????????????????????????//恢复回显
  7. echo "" ????????????????????????????????????//恢复回显后补一个空行
  8. echo "您的用户名是: $USERNAME" ????????????//确认赋值结果
  9. [[email?protected] ~]# chmod +x sttyecho.sh ????????//添加执行权限

执行测试脚本sttyecho.sh,验证效果:

  1. [[email?protected] ~]# ./sttyecho.sh
  2. 请输入用户名: root ????????????????????????//输入root,回车
  3. 请输入密码: ????????????????????????????????//输入1234567(不会显示),回车
  4. 您的用户名是: root ????????????????????????//脚本反馈结果

步骤三:使用export发布全局变量

默认情况下,自定义的变量为局部变量,只在当前Shell环境中有效,而在子Shell环境中无法直接使用。比如已定义的SCHOOL变量,当进入到sh或bash子Shell后,变量SCHOOL将处于未定义的状态:

  1. [[email?protected] ~]# SCHOOL="Tarena IT Group"
  2. [[email?protected] ~]# echo $SCHOOL
  3. Tarena IT Group
  4. [[email?protected] ~]# bash ????????????????????????????//开启bash子进程
  5. [[email?protected] ~]# echo $SCHOOL ????????????????????//查看SCHOOL变量值无结果
  6. [[email?protected] ~]# exit ????????????????????????????//返回原有Shell环境
  7. exit
  8. [[email?protected] ~]# echo $SCHOOL

若希望定义的变量能被子进程使用,可以使用export命令将其发布为全局变量。使用export发布时,只需指定变量名(可以有多个)即可,也可以通过export命令直接设置新的全局变量:

  1. [[email?protected] ~]# export SCHOOL ????????????????????????//发布已定义的变量
  2. [[email?protected] ~]# export XX="1234" ????????????????????//发布新变量

验证刚刚发布的全局变量:

  1. [[email?protected] ~]# bash ????????????????????????????????//进入bash子Shell环境
  2. [[email?protected] ~]# echo $SCHOOL ????????????????????????//查看全局变量的值 .. ..
  3. Tarena IT Group
  4. [[email?protected] ~]# echo $XX
  5. 1234

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读