shell编程二


博主名: 李常明


博文地址: http://keep88.blog.51cto.com

此笔记出自老男孩书籍:跟老男孩学linux运维shell编程实战

shell变量知识进阶与实践

1、shell中的特殊位置参数变量:


位置变量 作用说明
$0 获取当前执行的shell脚本的文件名,如果执行脚本包含了路径,会输出脚本路径
$n n=1..9 获取当前执行的shell脚本的第n个参数值,n为0时,输出脚本文件名,n>9 时,必须用大括号括起来,如${10}
$# 获取当前执行的shell脚本后面接的参数的总个数
$* 获取当前shell脚本所有传参的参数,如果给$*加上双引号,例:"$*"则会将所有的参数视为单个字符串,如 "$1 $2 $3....."
$@ 获取当前shell脚本所有传参的参数,如果给$@加上双引号,例:"$@"则会将所有的参数视为不同的独立字符串,如“$1” "$2" "$3" ...



例如:

1)、$n的使用:n为{1..15}

小技巧:
[root@localhosttest]#echo\${1..15}
$1$2$3$4$5$6$7$8$9$10$11$12$13$14$15

[root@localhosttest]#echo\a{1..10}
a1a2a3a4a5a6a7a8a9a10#>==利用此技巧可以快速输出有规律的字符串


[root@localhosttest]#pwd
/root/test
[root@localhosttest]#vimt1.sh
[root@localhosttest]#catt1.sh
echo$1
[root@localhosttest]#sht1.shtest
test
[root@localhosttest]#sht1.shzhangsanlisi
zhangsan

[root@localhosttest]#vimt1.sh
[root@localhosttest]#catt1.sh
echo$1$2$3
[root@localhosttest]#sht1.shzhangsanwangwulisi
zhangsanwangwulisi

需注意:

当参数大于9时,必须用${10} ${11} ${12}.....${15} 使用大括号括起来

2)、$0的使用:

[root@localhosttest]#vimt2.sh
[root@localhosttest]#catt2.sh
echo$0
[root@localhosttest]#sht2.sh
t2.sh
[root@localhosttest]#sht2.shzhangsan
t2.sh

注:
列举两个命令的使用
1)、dirname和basename
dirname:获取路径
basename:获取文件名
[root@localhosttest]#dirname/root/test/t1.sh
/root/test
[root@localhosttest]#basename/root/test/t1.sh
t1.sh

3)、$#的使用:

[root@localhosttest]#vimt2.sh
[root@localhosttest]#catt2.sh
echo$#
[root@localhosttest]#sht2.shzhangsanlisiwangwutest1test2
5

4)、$* $@ "$*" "$@"的区别:

结合上述概念,举例分析这四个区别:

1)、使用set设置位置参数(同命令行脚本的传参)
[root@localhost~]#set--"Iam"smartboy.
[root@localhost~]#echo$#
3
[root@localhost~]#echo$1
Iam
[root@localhost~]#echo$2
smart
[root@localhost~]#echo$3
boy.
2)、测试$*和$@,没有带双引号
[root@localhost~]#echo$*
Iamsmartboy.
[root@localhost~]#echo$@
Iamsmartboy.
使用for循环输出所有参数:
[root@localhost~]#foriin$*;doecho$i;done
I
am
smart
boy.
[root@localhost~]#foriin$@;doecho$i;done
I
am
smart
boy.
3)、测试"$*"和"$@",注意使用了双引号
[root@localhost~]#echo"$*"
Iamsmartboy.
[root@localhost~]#echo"$@"
Iamsmartboy.
使用for输出所有参数:
[root@localhost~]#foriin"$*";doecho$i;done
Iamsmartboy.
[root@localhost~]#foriin"$@";doecho$i;done
Iam
smart
boy.

小结:
回顾开头我们写的概念分析:
$*和$@不加引号,输出所有参数,在for语句中,如果有空格分隔的字符串,会拆分输出
$*和$@都加上引号,例"$*""$@",此时区别:
$*会将所有参数,作为完整的字符串输出,如上所示
$@会将所有参数,作为独立的单个字符输出,如果有空格分隔的字符串,不会拆分输出,作为独立的单个字符输出.

注释:
set和eval命令的使用详解:
set可以同命令行一样,可以传参
eval命令:首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量。该命令对变量进行两次扫描。这些需要进行两次扫描的变量有时被称为复杂变量
例如:
[root@localhost~]#A="catt1.sh"
[root@localhost~]#echo$A
catt1.sh
[root@localhost~]#eval$A#>==此时eval命令对变量进行置换,还执行了其中的命令
Iamsmartboy.

set与eval的使用,在编写脚本会用到的例子:
例1)、
[root@localhost~]#Number=$(set--$(catt4.sh);eval"echo\$$#")
注释:set设置传入的参数,eval进行两次扫描,$#:输出所有的位置参数总数,
$$#:将总数,也就是最后一个位置参数的值,赋值给Number
[root@localhost~]#echo$Number
5
例2)、
[root@localhost~]#runlevel
N5
[root@localhost~]#Runlevel=$(set--$(runlevel);eval"echo\$$#")
[root@localhost~]#echo$Runlevel
5

2、shell进程中的特殊状态变量:

$?获取执行上一个指令的执行状态返回值(0为成功,非0表示失败)

3、bash Shell内置变量命令:

1)、echo参数
echo参数选项 说明
-n 不换行输出内容
-e

解析转义字符

转移字符:
\n 换行
\t 制表符
\r 回车
\b 退格
\v 纵向制表符


2)、eval命令使用

[root@localhost~]#catt1.sh
echo\$$#

[root@localhost~]#sht1.sharg1arg2
$2#>==$#:输出位置参数总数2$$#:$2echo输出$2
[root@localhost~]#catt1.sh
evalecho\$$##>==加入eval命令,将echo$5以命令输出结果
[root@localhost~]#sht1.sharg1arg2arg3arg4
arg4

3)、shift

shift命令的主要作用是将位置参数$1,$2等进行左移,即如果位置参数是$3,$2,$1,那么执行一次shift后,$3 就变成了$2,$2就变成了$1,$1,就消失了。

例如:

[root@localhost~]#catt4.sh
echo$1$2
if[$#-eq2];then
shift
echo$1;
fi
[root@localhost~]#sht4.sharg1arg2
arg1arg2
arg2#>==执行shift命令后,arg1被左移掉了,剩下了新的$1,即arg2

4、Shell变量字串知识及实践

表达式 说明
${parameter} 返回变量$parameter的内容
${#parameter} 返回变量$parameter内容的长度
${parameter:offset} 在变量${parameter}中,从位置offset之后开始提取字串到结尾
${parameter:offset:length} 在变量${parameter}中,从位置offset之后开始提取长度为length的字串
${parameter#word} 从变量${parameter}开头删除最短匹配的word字串
${parameter##word} 从变量${parameter}开头删除最长匹配的word字串
${parameter%word} 从变量${parameter}结尾开始删除最短匹配的word字串
${parameter%%word} 从变量${parameter}结尾开始删除最长匹配的word字串
${parameter/pattern/string} 使用string代替第一个匹配的pattern
${parameter//pattern/string} 使用string代替所有匹配的pattern

举例说明各内置变量的使用:

1)、${#parameter} :计算长度

[root@localhost~]#name="lichangming"
[root@localhost~]#echo${#name}
11#>==正好11个字符”lichangming“

2)、${parameter:offset}: 指定位置之后提取内容到结尾,同python中的切片类似

[root@localhost~]#name="lichangming"
[root@localhost~]#echo${name:3}
hangming
[root@localhost~]#echo${name:2}
changming

3)、${parameter:offset:length} :从位置offset之后开始提取长度为length的字串

[root@localhost~]#name="lichangming"
[root@localhost~]#echo${name:2:7}
changmi#>==输出第2个位置之后到第7个位置的内容

注:

此上的截取内容方法,同cut -c命令的功能

例如:

[root@localhost~]#echo$name
lichangming
[root@localhost~]#echo${name}|cut-c2-7
ichang#>==cut命令,后接的数字表示:截取2~7个位置的字符

注意和内置变量的区别,内置变量的第一个offset,起始位置为offset之后的内容

4)、${parameter#word} :从开头开始删除最短匹配word字串

[root@localhost~]#echo$name
lichangming
[root@localhost~]#echo${name#l*g}
ming#>==匹配了l至g范围的字串,将其删除,注意一定是从头开始匹配,最短匹配

[root@localhost~]#echo${name#c*g}
lichangming#>==c不是从开头匹配的,所以没有找到匹配项,未删除,输出所有

5)、${parameter##word} :删除从头开始最长匹配

[root@localhost~]#name="lichangmingcming"
[root@localhost~]#echo$name
lichangmingcming
[root@localhost~]#echo${name##l*c}
ming#>==最长匹配,匹配了lichangmingc,将其删除,剩下ming

看看最短匹配删除的结果:
[root@localhost~]#echo${name#l*c}
hangmingcming#>==最短匹配,匹配了lic,删除

以上匹配删除,都是从头开始删除。

6)、${parameter%word}:从末尾删除最短匹配

7)、${parameter%%word}: 从末尾删除最长匹配

例如:

[root@localhost~]#echo$name
lichangmingcming
[root@localhost~]#echo${name%i*g}
lichangmingcm
[root@localhost~]#echo${name%%i*g}
l
[root@localhost~]#echo${name%%c*m}
lichangmingcming
[root@localhost~]#echo${name%%m*g}
lichang

注意:

从末尾匹配,指第一个值与末尾g 范围的字串,在上述例子中,c*m,开头为c,中间为任意值,末尾为m,则未找到匹配结果,输出了所有,所以,一定谨记是第一个值与末尾匹配。

8)、${parameter/pattern/string} :将string替换第一匹配到的模式pattern

[root@localhost~]#name="li2chang3ming4hehe8"
[root@localhost~]#echo$name
li2chang3ming4hehe8
[root@localhost~]#echo${name/3*4/test}
li2changtesthehe8

9)、${parameter//pattern/string} :将string替换所有匹配到的模式pattern

[root@localhost~]#name="zhangsanlisiwangwuzhangsanliming"
[root@localhost~]#echo$name
zhangsanlisiwangwuzhangsanliming
[root@localhost~]#echo${name//zhangsan/someone}
someonelisiwangwusomeoneliming

注:

使用以上的方法,批量修改文件名

1)、生成测试文件:

[root@localhosttest]#pwd
/root/test
[root@localhosttest]#ls
[root@localhosttest]#touch\smart_t{1..9}.sh
[root@localhosttest]#ls
smart_t1.shsmart_t3.shsmart_t5.shsmart_t7.shsmart_t9.sh
smart_t2.shsmart_t4.shsmart_t6.shsmart_t8.sh

批量改名: 将smart_t*.sh改为silly_t*.sh

[root@localhosttest]#ls
smart_t1.shsmart_t3.shsmart_t5.shsmart_t7.shsmart_t9.sh
smart_t2.shsmart_t4.shsmart_t6.shsmart_t8.sh

[root@localhosttest]#foriin`ls*.sh`;domv$i`echo${i//smart/silly}`;done
[root@localhosttest]#ls
silly_t1.shsilly_t3.shsilly_t5.shsilly_t7.shsilly_t9.sh
silly_t2.shsilly_t4.shsilly_t6.shsilly_t8.sh

此方法为使用变量的字串替换 来实现的改名方法。


2)、使用rename命令改名:

[root@localhosttest]#rename"smart""silly"/root/test/*.sh
[root@localhosttest]#ls
silly_t1.shsilly_t3.shsilly_t5.shsilly_t7.shsilly_t9.sh
silly_t2.shsilly_t4.shsilly_t6.shsilly_t8.sh


3)、for循环结合sed实现批量改名:

[root@localhosttest]#ls
silly_t1.shsilly_t3.shsilly_t5.shsilly_t7.shsilly_t9.sh
silly_t2.shsilly_t4.shsilly_t6.shsilly_t8.sh

[root@localhosttest]#foriin`ls*.sh`;domv$i`echo$i|seds/silly/smart/g`;done
[root@localhosttest]#ls
smart_t1.shsmart_t3.shsmart_t5.shsmart_t7.shsmart_t9.sh
smart_t2.shsmart_t4.shsmart_t6.shsmart_t8.sh

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 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