linux-运维进阶-09 编写Shell脚本

linux-运维进阶-09 编写Shell脚本

可以将Shell终端解释器当作人与计算机硬件之间的“翻译官”,它作为用户与Linux系统内部的通信媒介,除了能够支持各种变量与参数外,还提供了诸如循环、分支等高级编程语言才有的控制结构特性。

  • 交互式(Interactive):用户每输入一条命令就立即执行。
  • 批处理(Batch):由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中诸多的命令。

指定解释器

脚本的第一行

用于指定脚本使用哪个shell程序做为脚本中命令的解释器

使用bash做为脚本命令的解释器

#!/bin/bash

使用zsh做为脚本的命令解释器

#!/bin/zsh

创建一个脚本

[root@localhost ~]# vim hello.sh

里面输入:
#!/bin/bash
echo "helloworld"
保存退出

执行一个脚本

[root@localhost ~]# ./hello.sh
-bash: ./hello.sh: Permission denied	#发现你的权限不够
[root@localhost ~]# 

添加执行权限

脚本写完后运行,利用./执行发现权限不够。Linux文件创建之后默认是没有可执行权限的,可以用chmod给文件或目录添加上可执行权限

[root@localhost ~]# ll
[root@localhost ~]# chmod +x hello.sh 
[root@localhost ~]# ll
[root@localhost ~]# ./hello.sh 
helloworld
[root@localhost ~]# 

上面两次ll出来的文件列表,是为了对比出添加权限前后文件权限的变化,x表示可执行。

没有执行权限情况下想要执行脚本的两种方式

首先咱们在新建一个脚本
[root@localhost ~]# vim aaa.sh
里面输入:
#!/bin/bash
echo "hello aaa"
保存退出

验证它无权限被执行
[root@localhost ~]# ./aaa.sh
-bash: ./aaa.sh: Permission denied

解释器后面跟上脚本

[root@localhost ~]# bash aaa.sh 
hello aaa

点加空格后面跟上脚本或者脚本的全路径

[root@localhost ~]# . aaa.sh 
hello aaa

Shell脚本执行的几种方法

在脚本拥有可执行权限之后,我们就可以去执行脚本,执行脚本有以下几种方式:

在脚本所在目录下时

[root@localhost ~]# ./hello.sh 
helloworld
[root@localhost ~]# . hello.sh 
helloworld
[root@localhost ~]# bash hello.sh 
helloworld
[root@localhost ~]# sh hello.sh 
helloworld
[root@localhost ~]# 

不在脚本所在目录下时

[root@localhost ~]# mkdir -p a/b/c/d
[root@localhost ~]# cd a
[root@localhost a]# bash /root/hello.sh 
helloworld
[root@localhost a]# cd b/c/d
[root@localhost d]# pwd
/root/a/b/c/d
[root@localhost d]# ./../../../../hello.sh 
helloworld
[root@localhost d]# 

接受用户的参数

脚本的参数就是脚本后面跟的用户输入的选项或者是变量

在脚本中

  • 脚本的名字使用$0来表示
  • 脚本的参数个数使用$#表示
  • 脚本的第N个参数使用$N表示(例如脚本第三个参数$3)
[root@localhost ~]# vim hello.sh 
输入:
#!/bin/bash
echo "脚本名称:$0"
echo "参数个数:$#"
echo "第一个参数:$1"
echo "第二个参数:$2"
echo "第三个参数:$3"
echo "第四个参数:$4"
echo "第五个参数:$5"

执行该脚本:

[root@localhost ~]# bash hello.sh 1 2 3 4 5

判断用户参数(下面两种写法)

[root@localhost ~]# vim isroot.sh
输入:

#!/bin/bash
if [ $USER == root ];
then
    echo "当前用户是管理员"
else
    echo "当前用户不是管理员"    
fi
[ $USER = root ] && echo "当前用户是管理员" || echo "当前用户不是管理员"
exit 0

执行该脚本:

[root@localhost ~]# bash isroot.sh 
当前用户是管理员
当前用户是管理员
[root@localhost ~]# 

可用的整数比较运算符

运算符 作用
-eq 是否等于
-ne 是否不等于
-gt 是否大于
-lt 是否小于
-le 是否等于或小于
-ge 是否大于或等于

常见的字符串比较运算符

运算符 作用
= 比较字符串内容是否相同
!= 比较字符串内容是否不同
-z 判断字符串内容是否为空
 [root@localhost ~]# [ $LANG="EN.US.UTF-8" ]&&echo "is English"
is English
[root@localhost ~]# 

Shell中的四则运算

注意:方括号外取值符号$不能少,方括号内一定要用空格把方括号和里面的命令隔开

[root@localhost ~]# i=$[10 * 10]
[root@localhost ~]# echo $i
100
[root@localhost ~]# echo $[999 + 999]
1998
[root@localhost ~]# 

写一个判断内存是否够用的脚本

[root@localhost ~]# vim isfree.sh

输入:

#!/bin/bash
# 此脚本用于判断内存是否够用,标准为空闲内存大于总内存的20%(说明脚本功能)
# bash isfree.sh (说明脚本的用法)
# 作者:feng(说明脚本作者)
# qq:略(说明作者的联系方式)
 
# 可能有些脚本里有复杂参数或者函数,请在最下面进行说明
 
Totalmem=`free -m | grep Mem | awk '{print $2}'`
Freemem=`free -m | grep Mem | awk '{print $4}'`
i=$[ $Totalmem/5 ]
[ $Freemem -gt $i ] && echo "内存够用" || echo "内存紧缺,请抓紧清理内存"

执行:

[root@localhost ~]# bash isfree.sh 
内存够用
[root@localhost ~]# 

if流程控制语句

上面判断用户参数时,我们已经使用过了if语句

现在再来一次

linux shell 中判断文件、目录是否存在

-e filename 如果 filename存在,则为真
-d filename 如果 filename为目录,则为真
-f filename 如果 filename为常规文件,则为真
-L filename 如果 filename为符号链接,则为真
-r filename 如果 filename可读,则为真
-w filename 如果 filename可写,则为真
-x filename 如果 filename可执行,则为真
-s filename 如果文件长度不为0,则为真

[root@localhost ~]# vim 1.sh

输入:

#!/bin/bash
DIR="/root/test"
if [ ! -d $DIR ]
then
	echo "目录不存在" 
	mkdir /root/test
else
	echo "目录已经存在"
fi
exit 0
[root@localhost ~]# bash 1.sh 
目录不存在
[root@localhost ~]# bash 1.sh 
目录已经存在

结果如下图:

判断主机是否能正常访问百度的脚本

[root@localhost ~]# vim baidu.sh

输入:

#!/bin/bash
# example: ./testhost.sh www.baidu.com
if [ $# -eq 1 ] 
then
    ping -c 4 -i 0.2 -W 3 $1 &> /dev/null
else 
    echo "example:  $0 www.baidu.com"
fi
 
if [ $? -eq 0 ] 
then
    echo "主机$1能正常访问"
    exit 0
else
    echo "主机$1无法访问"
    exit 1
fi
[root@localhost ~]# bash baidu.sh 
example:  baidu.sh www.baidu.com
主机能正常访问
[root@localhost ~]# 

判断成绩的脚本

[root@localhost ~]# vim result.sh
 #!/bin/bash
read -p "Enter your score(0-100): " sc
if [ $sc -gt 100 ] || [ $sc -lt 0 ] ; then
    echo "Error,Please input score 0~100!"
    exit 2
elif [ $sc -ge 85 ] && [ $sc -le 100 ]; then
    echo "$sc is Excellent"
elif [ $sc -ge 60 ] && [ $sc -le 84 ]; then
    echo "$sc is Pass"
else
    echo "$sc is Fail"
fi
[root@localhost ~]# bash result.sh 
Enter your score(0-100): 90
90 is Excellent
[root@localhost ~]# 

for循环

题目:在linux上创建一个脚本,名为/root/makeusers,此脚本能实现为系统创建本地用户,并且这些用户的用户名来自一个包含用户名列表的文件。

同时满足下列要求:
  此脚本要求提供一个参数,此参数就是包含用户列表的文件
  如果没有提供参数,此脚本应该给出下面的提示信息 Usage:/root/makeusers ,然后退出并返回相应的值

如果提供一个不存在的文件名,此脚本应该给出下面的提示信息 Input file not found 然后退
出并返回相应的值

创建的用户登录 shell 为/bin/false,此脚本不需要为用户设置密码

首先,了解一下新建用户的命令:

[root@localhost ~]# useradd -s /bin/fasle "testuser"
[root@localhost ~]# cat /etc/passwd

通过cat命令查看所有用户信息,可以看到如下图,用户testuser已经成功创建出来了

现在开始写脚本:

[root@localhost ~]# vim foruser.sh
#!/bin/bash
if [ $# -ne 1 ];then
    echo 'Usage: $0 <userfile><>'
    exit 1
elif [ ! -f "$1" ];then
    echo "input file not found"
    exit 2
else
    for USER in $(cat "$1");do
        useradd -s /bin/false $USER
    done
fi

新建一个包含用户名的文件,里面随便设置几个用户

[root@localhost ~]# vim user.txt
aaa
bbb
ccc
ddd

执行脚本

[root@localhost ~]# bash foruser.sh user.txt 
[root@localhost ~]# cat /etc/passwd

如下图,几个用户已经被成功添加了!

把for循环改成wheel循环的写法

另外再写一个脚本:

[root@localhost ~]# vim wheeluser.sh
#!/bin/bash
if [ $# -eq 1 ];then
    if [ -f "$1" ];then
        while read username;do
            useradd -s /bin/false $username &>/dev/null
        done<$1 #跳出循环
    else
        echo "Input file not found"
    fi  
else
    echo "Usage: $0 <userfile>"
fi

重新编辑一下user.txt

[root@localhost ~]# vim user.txt 
aaawww
bbbwww
cccwww
dddwww

执行脚本

[root@localhost ~]# bash wheeluser.sh user.txt 
[root@localhost ~]# cat /etc/passwd

如下图,几个用户已经被成功添加了!

case语句

在 linux上创建一个名为/root/script.sh 的脚本,让其提供下列特性:
  当运行/root/script.sh all,输出为 none
  当运行/root/script.sh none,输出为 all
  当没有任何参数或参数不是 all 或者 none 时,其错误输出产生以下的信息:

/root/script.sh all|none

开始写脚本

[root@localhost ~]# vim script.sh
#!/bin/bash
case $1 in
    all)
    echo "none"
    ;;  
    none)
    echo "all"
    ;;  
    *)  
    echo "Usage: $0 all|none"
    ;;  
esac

执行脚本:

[root@localhost ~]# bash script.sh all
none
[root@localhost ~]# bash script.sh none
all
[root@localhost ~]# bash script.sh abc
Usage: script.sh all|none
[root@localhost ~]# 

如下图

本篇到此结束

原文地址:https://blog.csdn.net/weixin_42560249/article/details/88796854

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2280端口映射到公网,发现经常被暴力破解,自己写了个临时封禁ip功能的脚本,实现5分钟内同一个ip登录密码错误10次就封禁这个ip5分钟,并且进行邮件通知使用步骤openwrt为19.07.03版本,其他版本没有测试过安装bashmsmtpopkg
#!/bin/bashcommand1&command2&wait从Shell脚本并行运行多个程序–杨河老李(kviccn.github.io)
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/phpls-ls 2.编辑修改.bash_profile文件(没有.bash_profile文件的情况下回自动创建)sudovim~/.bash_profile在文件的最后输入以下信息,然后保存退出exportPATH="/Applications/MAMP/bin/php/php7.2.20/b
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如zh_CN之类的语言包,进行中文语言包装:apt-getinstalllanguage-pack-zh-hans3、安装好后我们可以进行临时修改:然后添加中文支持: locale-genzh_CN.UTF-8临时修改> export LC_ALL='zh_CN.utf8'> locale永久
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexadecimalbash2#[0~1]0[0~7]0x[0~f]or0X[0~f]perl0b[0~1]0[0~7]0x[0~f]tcl0b[0~1]0o[0~7]0x[0~f]bashdifferentbaserepresntationreference2.StringlengthLanguageStr
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全命令补全方法:yum-yinstallbash-completionsource/usr/share/bash-completion/bash_completionsource<(kubectlcompletionbash)echo"source<(kubectlcompletionbash)">>~/.bashrc 
参考这里启动jar包shell脚本修改过来的#!/bin/bash#默认应用名称defaultAppName='./gadmin'appName=''if[[$1&&$1!=0]]thenappName=$1elseappName=$defaultAppNamefiecho">>>>>>本次重启的应用:$appName<
#一个数字的行#!/bin/bashwhilereadlinedon=`echo$line|sed's/[^0-9]//g'|wc-L`if[$n-eq1]thenecho$linefidone<1.txt#日志切割归档#!/bin/bashcd/data/logslog=1.logmv_log(){[-f$1]&&mv$1$2
#文件增加内容#!/bin/bashn=0cat1.txt|whilereadlinedon=[$n+1]if[$n-eq5]thenecho$lineecho-e"#Thisisatestfile.\n#Testinsertlineintothisfile."elseecho$linefidone#备份/etc目录#
# su - oraclesu: /usr/bin/ksh: No such file or directory根据报错信息:显示无法找到文件 /usr/bin/ksh果然没有该文件,但是发现存在文件/bin/ksh,于是创建了一个软连接,可以规避问题,可以成功切换到用户下,但无法执行系统自带命令。$. .bash_profile-ksh: .: .b
history显示历史指令记录内容,下达历史纪录中的指令主要的使用方法如果你想禁用history,可以将HISTSIZE设置为0:#exportHISTSIZE=0使用HISTIGNORE忽略历史中的特定命令下面的例子,将忽略pwd、ls、ls-ltr等命令:#exportHISTIGNORE=”pwd:ls:ls-ltr:”使用HIS
一.命令历史  1.history环境变量:    HISTSIZE:输出的命令历史条数,如history的记录数    HISTFILESIZE:~/.bash_history保存的命令历史记录数    HISTFILLE:历史记录的文件路径    HISTCONTROL:     ignorespace:忽略以空格开头的命令
之前在网上看到很多师傅们总结的linux反弹shell的一些方法,为了更熟练的去运用这些技术,于是自己花精力查了很多资料去理解这些命令的含义,将研究的成果记录在这里,所谓的反弹shell,指的是我们在自己的机器上开启监听,然后在被攻击者的机器上发送连接请求去连接我们的机器,将被攻击者的she
BashOne-LinersExplained,PartI:Workingwithfileshttps://catonmat.net/bash-one-liners-explained-part-oneBashOne-LinersExplained,PartII:Workingwithstringshttps://catonmat.net/bash-one-liners-explained-part-twoBashOne-LinersExplained,PartII
Shell中变量的作用域:在当前Shell会话中使用,全局变量。在函数内部使用,局部变量。可以在其他Shell会话中使用,环境变量。局部变量:默认情况下函数内的变量也是全局变量#!/bin/bashfunctionfunc(){a=99}funcecho$a输出>>99为了让全局变量变成局部变量
1、多命令顺序执行;  命令1;命令2  多个命令顺序执行,命令之间没有任何逻辑联系&&  命令1&&命令2  逻辑与,当命令1正确执行,才会执行命令2||  命令1||命令2  逻辑或,当命令1执行不正确,才会执行命令2例如:ls;date;cd/home/lsx;pwd;who ddif=输入文件of=输
原博文使用Linux或者unix系统的同学可能都对#!这个符号并不陌生,但是你真的了解它吗?首先,这个符号(#!)的名称,叫做"Shebang"或者"Sha-bang"。Linux执行文件时发现这个格式,会把!后的内容提取出来拼接在脚本文件或路径之前,当作实际执行的命令。 Shebang这个符号通常在Unix系统的脚本
1、历史命令history[选项][历史命令保存文件]选项:-c:  清空历史命令-w:  把缓存中的历史命令写入历史命令保存文件 ~/.bash_historyvim/etc/profile中的Histsize可改存储历史命令数量历史命令的调用使用上、下箭头调用以前的历史命令使用“!n”重复执行第n条历史
目录1.Shell脚本规范2.Shell脚本执行3.Shell脚本变量3.1环境变量3.1.1自定义环境变量3.1.2显示与取消环境变量3.1.3环境变量初始化与对应文件的生效顺序3.2普通变量3.2.1定义本地变量3.2.2shell调用变量3.2.3grep调用变量3.2.4awk调用变量3.3
   http://www.voidcn.com/blog/wszzdanm/article/p-6145895.html命令功能:显示登录用户的信息命令格式:常用选项:举例:w显示已经登录的用户及正在进行的操作[root@localhost~]#w 11:22:01up4days,21:22, 3users, loadaverage:0.00,0.00,0.00USER