• [行业资讯] shell
    Linux系统中运行的一种特殊程序;在用户和内核之间充当“翻译官”;用户登录Linux系统时,自动加载的一个Shell程序;Bash是Linux系统中默认使用的Shell程序。文件位于/bin/bash(小写)
  • [技术干货] 如何使用shell判断主机存活?
    [root@lzw Desktop]# more ping.sh #!/bin/sh# Ping网段所有IP# 2019/8/14ip="192.168.0."for i in `seq 1 20`do  ping -c 2 $ip$i | grep -q 'ttl=' && echo "$ip$i yes">>yes.txt|| echo "$ip$i no">>no.txt  #yes正常,no主机不存在或不正常done执行脚本结果:[root@lzw Desktop]# lltotal 12-rw-r--r--. 1 root root 296 Aug 21 22:07 no.txt-rwxr-xr-x. 1 root root 222 Aug 21 22:03 ping.sh-rw-r--r--. 1 root root  16 Aug 21 22:03 yes.txt[root@lzw Desktop]# more no.txt 192.168.0.2 no192.168.0.3 no192.168.0.4 no192.168.0.5 no192.168.0.6 no192.168.0.7 no192.168.0.8 no192.168.0.9 no192.168.0.10 no192.168.0.11 no192.168.0.12 no192.168.0.13 no192.168.0.14 no192.168.0.15 no192.168.0.16 no192.168.0.17 no192.168.0.18 no192.168.0.19 no192.168.0.20 no[root@lzw Desktop]# more yes.txt 192.168.0.1 yes注释:脚本采用ICMP协议的ping命令来检查某一网段的主机ip地址是否存活,主要通过for循环语句依次ping192.168.0.1到192.168.0.20地址,每个地址ping两次。并且通过管道符过滤ttl值判断ip地址是存活。如果ip地址存活,则输出地址到yes.txt文件,否则,IP地址则输入no.,txt文件中。优点:可减少工程师批量检查ip的劳动量缺点:执行脚本主机网络不稳定,丢包严重。      检查主机防火墙禁止ICMP。
  • [技术干货] 【转】shell脚本之循环语句(for循环与while循环之详解)
    shell脚本之循环语句(for循环与while循环之详解)一、for循环语句1.1for语句结构for 循环 指定次数循环 遍历:把集合中每一个元素都读取一遍语句结构for 变量名 in 取值列表do 命令序列done1.2for语句示例1.2.1利用文件中的名称列表批量添加用户,并给每个用户设置密码123123创建一个名单文件[root@localhost samba]# vim users.txt jack john kate lucy编辑脚本[root@localhost opt]# vim useradd.sh#!/bin/bash list=$(cat /opt/users.text) for user in $list do useradd $user echo "123123"|passwd --stdin $user &> /dev/null 面交互设置密码, echo "创建$user成功" done ~ 验证[root@localhost opt]# sh useradd.sh 创建john成功 创建lucy成功 创建kateck成功 useradd:用户“john”已存在 创建john成功 创建kate成功 useradd:用户“lucy”已存在 创建lucy成功1.2.2批量删除上面添加的用户#!/bin/bash list=$(cat /opt/users.text) for user in $list do userdel -r $user echo "123123"|passwd --stdin $user &> /dev/null echo "删除$user成功" done 验证[root@localhost opt]# sh useradd.sh 删除john成功 删除lucy成功++ 删除kateck成功 userdel:用户“john”不存在 删除john成功 删除kate成功 userdel:用户“lucy”不存在 删除lucy成功1.2.3 根据IP地址批量检查主机状态检测14.0.0.1 14.0.0.14网段主机 的连通性#!/bin/bash for ((i=1;i<=14;i++)) do ping -c 3 -i 0.2 -w 3 "14.0.0.$i" &> /dev/null if [ $? -eq 0 ] then echo "host 14.0.0.$i is up" else echo "host 14.0.0.$i is down" fi done验证[root@localhost opt]# sh ipchck.sh host 14.0.0.1 is down host 14.0.0.2 is up host 14.0.0.3 is down host 14.0.0.4 is down host 14.0.0.5 is down host 14.0.0.6 is down host 14.0.0.7 is down host 14.0.0.8 is up host 14.0.0.9 is down host 14.0.0.10 is up host 14.0.0.11 is down host 14.0.0.12 is down host 14.0.0.13 is down host 14.0.0.14 is up二、while循环语句2.1while语句结构重复测试某个条件,只要条件成立则反复执行,适用于要求控制循环次数,操作对象按数字编号,按特定条件重复操作等情况。while 条件测试语句 do 命令序列 done2.2while语句示例2.2.1 批量添加以stu开头以数字进行编号的账户名即stu1、stu2、stu3…stu10,初始密码为123123#!/bin/bash i=1 while [ $i -le 10 ] do ​ useradd stu$i ​ echo "123123" | passwd --stdin stu$i &> /dev/null ​ echo "用户stu$i创建成功" ​ let i++ “let i++”(等同于 i=`expr $i + 1`) ​ done验证[root@localhost opt]# vim stu.sh[root@localhost opt]# sh stu.sh 用户stu1创建成功 用户stu2创建成功 用户stu3创建成功 用户stu4创建成功 用户stu5创建成功 用户stu6创建成功 用户stu7创建成功 用户stu8创建成功 用户stu9创建成功 用户stu10创建成功2.2.2检测14.0.0.1 14.0.0.14网段主机 的连通性true与false是两个特殊的条件,true代表条件为真,条件不成立;false代表条件不成立。可以利用true来形成while死循环来不停猜价格。#!/bin/bash PRICE=$(expr $RANDOM % 1000) TIMES=0 echo "商品实际价格范围为 0-999,猜猜看是多少?" while true do read -p "请输入你猜测的价格数目:" a let TIMES++ if [ $a -eq $PRICE ] ; then echo "恭喜你答对了,实际价格是 $PRICE" echo "你总共猜测了 $TIMES 次" exit 0 elif [ $a -gt $PRICE ] ; then echo "太高了!" else echo "太低了!" fi done验证[root@localhost ~]# sh test11.sh 商品实际价格范围为 0-999,猜猜看是多少? 请输入你猜测的价格数目:500 太高了! 请输入你猜测的价格数目:300 太低了! 请输入你猜测的价格数目:400 太高了! 请输入你猜测的价格数目:350 太高了! 请输入你猜测的价格数目:325 太低了! 请输入你猜测的价格数目:335 太低了! 请输入你猜测的价格数目:340 太高了! 请输入你猜测的价格数目:338 太高了! 请输入你猜测的价格数目:337 恭喜你答对了,实际价格是 337 echo 你总共猜测了 9 次转载自:https://blog.csdn.net/m0_46476544/article/details/107590411?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
  • [技术干货] 【转】理解Linux中子shell的概念
    是什么子shell子shell的概念贯穿整个shell,写shell脚本时更是不可不知。所谓子shell,即从当前shell环境新开一个shell环境,这个新开的shell环境就称为子shell(subshell),而开启子shell的环境称为该子shell的父shell。子shell和父shell的关系其实就是子进程和父进程的关系,只不过子shell和父shell是关联的进程是bash进程。子shell会从父shell中继承很多环境,如变量、命令全路径、文件描述符、当前工作目录、陷阱等等,但子shell有很多种类型,不同类型的子shell继承的环境不相同。可以使用$BASH_SUBSHELL变量来查看从当前进程开始的子shell层数,$BASHPID查看当前所处BASH的PID,这不同于特殊变量"KaTeX parse error: Can't use function '\"' in math mode at position 6: "值,因为\̲"̲"会从父进程继承。何时产生子shell要解释清楚子shell以及产生何种类型的子shell,需要搞清楚Linux中如何产生子进程。Linux上创建子进程的方式有三种:一种是fork出来的进程,一种是exec出来的进程,一种是clone出来的进程。此处无需关心clone,因为它用来实现Linux中的线程。(1).fork是复制进程,它会复制当前进程的副本(不考虑写时复制的模式),以适当的方式将这些资源交给子进程。所以子进程掌握的资源和父进程是一样的,包括内存中的内容,所以也包括环境变量和变量。但父子进程是完全独立的,它们是一个程序的两个实例。(2).exec是加载另一个应用程序,替代当前运行的进程,也就是说在不创建新进程的情况下加载一个新程序。exec还有一个动作:在进程执行完毕后,退出exec所在的shell环境。所以为了保证进程安全,若要形成新的且独立的子进程,都会先fork一份当前进程,然后在fork出来的子进程上调用exec来加载新程序替代该子进程。例如在bash下执行cp命令,会先fork出一个bash,然后再exec加载cp程序覆盖子bash进程变成cp进程。再来说明子shell的问题。一般fork出来的子进程,内容和父进程是一样的(包括变量),例如执行cp命令时也能获取到父进程的变量。但是cp命令在哪里执行呢?执行cp命令敲入回车后,当前的bash进程fork出一个子bash,然后子bash通过exec加载cp程序替代子bash。这算是进入了子shell吗?更通用的问题是:什么情况下会进入子shell环境,什么时候不进入子shel环境呢?判断是否进入了子shell的方式非常简单,执行"echo $BASHPID",如果该值和父bash进程的pid值不同,则表示进入了子shell。在shell中是否进入子shell的情况可以分为几种:①.执行bash内置命令时.bash内置命令是非常特殊的,父进程不会创建子进程来执行这些命令,而是直接在当前bash环境中执行。但如果将内置命令放在管道后,则此内置命令将和管道左边的进程同属于一个进程组,所以仍然会创建子shell。[root@linuxidc ~]# echo $BASHPID # 当前BASHPID 65230 [root@linuxidc ~]# let a=$BASHPID # bash内置命令,不进入子shell [root@linuxidc ~]# echo $a 65230 [root@linuxidc ~]# echo $BASHPID 65230 [root@linuxidc ~]# cd | expr $BASHPID # 管道使得任何命令都进入进程组,会进入子shell 65603②.执行bash命令本身时。这是一个很巧合的命令。bash命令本身是bash内置命令,在当前shell环境下执行内置命令本不会创建子shell,也就是说不会有独立的bash进程出现,而实际结果则表现为新的bash是一个子进程。其中一个原因是执行bash命令会加载各种环境配置项,为了父bash的环境得到保护而不被覆盖,所以应该让其以子shell的方式存在。虽然fork出来的bash子进程内容完全继承父shell,但因重新加载了环境配置项,所以子shell没有继承普通变量,更准确的说是覆盖了从父shell中继承的变量。不妨试试在/etc/bashrc文件中定义一个变量,再在父shell中export名称相同值却不同的环境变量,然后到子shell中看看该变量的值为何?[root@linuxidc ~]# echo "var=55" >>/etc/bashrc [root@linuxidc ~]# export var=66 [root@linuxidc ~]# bash [root@linuxidc ~]# echo $var 55由结果55可知,执行bash时加载的/etc/bashrc中的变量覆盖了父bash中的导出的环境变量值66。其实执行bash命令,既可以认为进入了子shell,也可以认为没有进入子shell。从bash是内置命令的角度来考虑,它不会进入子shell,这一点在执行bash命令后从变量$BASH_SUBSHELL的值为0可以验证出来。但从执行bash命令后进入了新的shell环境来看,它有其父bash进程,且$BASHPID值和父shell不同,所以它算是进入了子shell。[root@linuxidc ~]# echo $BASHPID 65230 [root@linuxidc ~]# bash [root@linuxidc ~]# echo $BASHPID 65534③.执行shell脚本时。脚本中第一行总是"#!/bin/bash"或者直接"bash xyz.sh",这和上面的执行bash进入子shell其实是一回事,都是使用bash命令进入子shell。只不过此时的bash命令和情况②中直接执行bash命令所隐含的选项不一样,所以继承和加载的shell环境也不一样。事实也确实如此,它仅只继承父shell的某些环境变量,其余环境一概初始化。另外,执行shell脚本相比于直接执行bash命令,还多了一个动作:脚本执行完毕后自动退出子shell。[root@linuxidc ~]# cat b.sh #!/bin/bash echo $BASHPID [root@linuxidc ~]# echo $BASHPID 65534 [root@linuxidc ~]# ./b.sh 65570④.执行shell函数时。其实shell函数就是命令,它和bash内置命令的情况一样。直接执行时不会进入子shell,但放在管道后会进入子shell。[root@linuxidc ~]# fun_test (){ echo $BASHPID; } # 定义一个函数,输出BASHPID变量的值 [root@linuxidc ~]# echo $BASHPID 65230 [root@linuxidc ~]# fun_test # 说明执行函数不会进入子shell 65230 [root@linuxidc ~]# cd | fun_test # 但放在管道后会进入子shell 65605 <font color="ff0000">⑤.执行非bash内置命令时。</font>例如执行cp命令、grep命令等,它们直接fork一份bash进程,然后使用exec加载程序替代该子bash。此类子进程会继承所有父bash的环境。但严格地说,这已经不是子shell,因为exec加载的程序已经把子bash进程替换掉了,这意味着丢失了很多bash环境。在bash文档中,直接称呼这种环境为"单独的环境",和子shell的概念类似。[root@linuxidc ~]# let a=$BASHPID # let是内置命令 [root@linuxidc ~]# echo $a 65230 [root@linuxidc ~]# echo $BASHPID # echo是非内置命令,结果是不进入子shell 65230⑥.命令替换($())。当命令行中包含了命令替换部分时,将开启一个子shell先执行这部分内容,再将执行结果返回给当前命令。因为这次的子shell不是通过bash命令进入的子shell,所以它会继承父shell的所有变量内容。这也就解释了"echo $(echo)"中的结果是当前bash的pid号,而不是子shell的pid号,但"echo $(echo $BASHPID)"却和父bash进程的pid不同,因为它不是使用bash命令进入的子shell。[root@linuxidc ~]# echo $BASHPID 65230 [root@linuxidc ~]# echo $(echo $BASHPID) # 使用命令替换$()进入子shell 65612⑦.使用括号()组合一系列命令。例如(ls;date;echo haha),独立的括号将会开启一个子shell来执行括号内的命令。这种情况等同于情况⑤。[root@linuxidc ~]# echo $BASHPID 65230 [root@linuxidc ~]# (echo $BASHPID) # 使用括号()的命令组合进入子shell 65613⑧.放入后台运行的任务。它不仅是一个独立的子进程,还是在子shell环境中运行的。例如"echo hahha &"。[root@linuxidc ~]# echo $BASHPID 65230 [root@linuxidc ~]# echo $BASHPID & # 放入后台运行的任务进入子shell [1] 65614 [root@linuxidc ~]# 65614 [1]+ Done echo $BASHPID ⑨.进程替换。既然是新进程了,当然进入子shell执行。例如"cat <(echo haha)"。[root@linuxidc ~]# echo $BASHPID 65230 [root@linuxidc ~]# cat <(echo $BASHPID) # 进程替换"<()"进入子shell 65616需要说明的是,子shell的环境设置不会粘滞到父shell环境,也就是说子shell的变量等不会影响父shell。转载自:https://blog.csdn.net/m0_37556444/article/details/83090602?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162389694016780274175894%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fnavwordall.%2522%257D&request_id=162389694016780274175894&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~navwordall~first_rank_v2~rank_v29-23-83090602.first_rank_v2_pc_rank_v29&utm_term=shell&spm=1018.2226.3001.4187
  • [技术干货] 如何使用shell判断主机存活?
    [root@lzw Desktop]# more ping.sh #!/bin/sh# Ping网段所有IP# 2019/8/14ip="192.168.0."for i in `seq 1 20`do  ping -c 2 $ip$i | grep -q 'ttl=' && echo "$ip$i yes">>yes.txt|| echo "$ip$i no">>no.txt  #yes正常,no主机不存在或不正常done执行脚本结果:[root@lzw Desktop]# lltotal 12-rw-r--r--. 1 root root 296 Aug 21 22:07 no.txt-rwxr-xr-x. 1 root root 222 Aug 21 22:03 ping.sh-rw-r--r--. 1 root root  16 Aug 21 22:03 yes.txt[root@lzw Desktop]# more no.txt 192.168.0.2 no192.168.0.3 no192.168.0.4 no192.168.0.5 no192.168.0.6 no192.168.0.7 no192.168.0.8 no192.168.0.9 no192.168.0.10 no192.168.0.11 no192.168.0.12 no192.168.0.13 no192.168.0.14 no192.168.0.15 no192.168.0.16 no192.168.0.17 no192.168.0.18 no192.168.0.19 no192.168.0.20 no[root@lzw Desktop]# more yes.txt 192.168.0.1 yes注释:脚本采用ICMP协议的ping命令来检查某一网段的主机ip地址是否存活,主要通过for循环语句依次ping192.168.0.1到192.168.0.20地址,每个地址ping两次。并且通过管道符过滤ttl值判断ip地址是存活。如果ip地址存活,则输出地址到yes.txt文件,否则,IP地址则输入no.,txt文件中。优点:可减少工程师批量检查ip的劳动量缺点:执行脚本主机网络不稳定,丢包严重。      检查主机防火墙禁止ICMP。
  • [网络安全] 用友NC BeanShell远程代码执行漏洞预警(CNVD-2021-30167)
    一、概要近日,华为云关注到业界有安全研究人员披露用友NC BeanShell远程代码执行漏洞(CNVD-2021-30167),未授权的攻击者利用漏洞可以构造恶意请求,实现在目标系统上执行任意代码,目前漏洞POC已公开,风险较高。用友NC是一个面向集团企业的管理软件,华为云提醒使用用友NC的用户及时安排自检并做好安全加固以降低安全风险。二、威胁级别威胁级别:【严重】(说明:威胁级别共四级:一般、重要、严重、紧急)三、漏洞影响范围影响版本:用友NC 6.5.0.00201601201350四、漏洞处置目前官方已发布补丁修复了该漏洞,请受影响的用户及时下载补丁进行修复漏洞:http://umc.yonyou.com/ump/querypatchdetailed?PK=18981c7af483007db179a236016f594d37c01f22aa5f5d19华为云WAF具备对该漏洞防御能力。华为云WAF用户将“Web基础防护”状态设置为“拦截”模式,具体方法请参见配置Web基础防护规则。注:修复漏洞前请将资料备份,并进行充分测试。 
  • [云桌面百科] Shell中的算术运算符
    Shell 在使用的过程中经常需要用到算术运算符除了日常使用的+-*/分别代表加减乘除,还有%取余运算符、=赋值运算符、==判断相等运算符、!=判断不等于运算符。接下来就通过实例来学习一下,了解其中的细节吧~1、使用expr算术表达式使用 expr 进行算术运算需要注意两个问题:(1)运算符之间要有空格,如下所示,只有第一个 expr 85 + 23 是计算正确的,所以使用的时候千万不要忘记加空格!wyp@UOS-WYP1:~/Desktop$ expr 85 + 23 108 wyp@UOS-WYP1:~/Desktop$ expr85 + 23 bash: expr85:未找到命令 wyp@UOS-WYP1:~/Desktop$ expr 85+23 85+23 wyp@UOS-WYP1:~/Desktop$ expr 85 +23 expr: syntax error: unexpected argument “+23” wyp@UOS-WYP1:~/Desktop$ expr 85+ 23 expr: syntax error: unexpected argument “23”(2)乘法运算符使用 \*,乘法运算符前需要加 \,如下所示wyp@UOS-WYP1:~/Desktop$ expr 85 \* 23 1955 wyp@UOS-WYP1:~/Desktop$ expr 85 * 23 expr: syntax error2、使用 $(( ))如下可以看到使用这种方法没有格式的限制,是比较方便的。wyp@UOS-WYP1:~/Desktop$ echo $((85+23)) 108 wyp@UOS-WYP1:~/Desktop$ echo $(( 85 + 23)) 108 wyp@UOS-WYP1:~/Desktop$ echo $((85 + 23)) 108 wyp@UOS-WYP1:~/Desktop$ echo $((85+ 23)) 108 wyp@UOS-WYP1:~/Desktop$ echo $(( 85+23)) 108 wyp@UOS-WYP1:~/Desktop$ echo $(( 85+ 23)) 108 wyp@UOS-WYP1:~/Desktop$ echo $((85*23)) 1955 3、使用 $[ ]这种方式和 $((算术表达式))一样,如下所示wyp@UOS-WYP1:~/Desktop$ echo $[85+23] 108 wyp@UOS-WYP1:~/Desktop$ echo $[ 85 + 23 ] 108 wyp@UOS-WYP1:~/Desktop$ echo $[85+ 23] 108 wyp@UOS-WYP1:~/Desktop$ echo $[85* 23] 1955接下来通过赋值方式将上述知识演示一遍哦:a=85,b=23首先是+-*/分别代表加减乘除和%取余运算符wyp@UOS-WYP1:~/Desktop$ a=85 b=23 wyp@UOS-WYP1:~/Desktop$ echo $[$a/$b] 3 wyp@UOS-WYP1:~/Desktop$ echo $[$a%$b] 16 wyp@UOS-WYP1:~/Desktop$ echo $[$a*$b] 1955 wyp@UOS-WYP1:~/Desktop$ echo $[85/3] 28 wyp@UOS-WYP1:~/Desktop$ expr $a \* $b 1955 wyp@UOS-WYP1:~/Desktop$ expr $a / $b 3 wyp@UOS-WYP1:~/Desktop$ expr $a % $b 16 wyp@UOS-WYP1:~/Desktop$ a=85 b=23 wyp@UOS-WYP1:~/Desktop$ echo $(($a+$b)) 108 wyp@UOS-WYP1:~/Desktop$ echo $(($a-$b)) 62 wyp@UOS-WYP1:~/Desktop$ expr $a + $b 108其次是运算符 == 和 != 在等式成立的时候返回1,不成立返回0wyp@UOS-WYP1:~/Desktop$ expr $a == $b 0 wyp@UOS-WYP1:~/Desktop$ expr $a != $b 1 wyp@UOS-WYP1:~/Desktop$ echo $(($a==$b)) 0 wyp@UOS-WYP1:~/Desktop$ echo $(($a!=$b)) 1 wyp@UOS-WYP1:~/Desktop$ echo $[$a==$b] 0 wyp@UOS-WYP1:~/Desktop$ echo $[$a!=$b] 1最后是赋值运算符=就简单了,将赋值运算符右边计算的值赋值到左边的变量中wyp@UOS-WYP1:~/Desktop$ c=$(expr $a - $b) wyp@UOS-WYP1:~/Desktop$ echo $c 62 wyp@UOS-WYP1:~/Desktop$ c=$(($a+$b)) wyp@UOS-WYP1:~/Desktop$ echo $c 108 wyp@UOS-WYP1:~/Desktop$ c=$(($a%$b)) wyp@UOS-WYP1:~/Desktop$ echo $c 16
  • [技术干货] 【转】Shell 必知必会 | 二、你需要的 Shell 特殊字符都在这里!
    在写 Shell 脚本的时候,通常会使用到一些特殊字符,比如:$?、$@等,这篇文章将结合实例介绍所有的 Shell 特殊字符,建议先收藏哦!一、Shell 特殊字符1.1 $N N 代表一个数字,其中,$0 表示当前脚本文件名,$N (N > 0)表示输入到脚本中的第 N 个输入参数,如下所示:[root@localhost ~]# cat shell.sh #!/bin/bash echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} [root@localhost ~]# ./shell.sh 1 2 3 4 5 6 7 8 9 10 ./shell.sh 1 2 3 4 5 6 7 8 9 10 [root@localhost ~]#注意:$0 输出的是 ./shell.sh。1.2 $#传递给脚本或函数的参数个数,如下所示:[root@localhost ~]# cat shell.sh #!/bin/bash echo $# [root@localhost ~]# ./shell.sh 1 2 3 3 [root@localhost ~]# [root@localhost ~]# cat shell.sh #!/bin/bash funcTest() { echo $# } funcTest 1 2 3 4 [root@localhost ~]# ./shell.sh 4 [root@localhost ~]# 1.3 $* 表示传递给脚本或函数的所有参数,如下所示:[root@localhost ~]# cat shell.sh #!/bin/bash echo $* [root@localhost ~]# ./shell.sh 1 2 3 4 5 1 2 3 4 5 [root@localhost ~]# [root@localhost ~]# cat shell.sh #!/bin/bash funcTest() { echo $* } funcTest 1 2 3 4 [root@localhost ~]# ./shell.sh 1 2 3 4 [root@localhost ~]#1.4 $@表示传递给脚本或函数的所有参数,如下所示:[root@localhost ~]# cat shell.sh #!/bin/bash echo $@ [root@localhost ~]# ./shell.sh 1 2 3 4 5 1 2 3 4 5 [root@localhost ~]# [root@localhost ~]# cat shell.sh #!/bin/bash funcTest() { echo $@ } funcTest 1 2 3 4 [root@localhost ~]# ./shell.sh 1 2 3 4 [root@localhost ~]# $@ 与 $* 的区别:当不被双引号包含时,两个符号没区别,都以 $1 $2 $3 ……分开的形式输出;当被双引号包含时,$*会将所有参数作为一个整体输出,例如:"$1 $2 $3 ……",而 $@ 会将各个参数分开,例如:$1 $2 $3 ……;下面通过例子看下:先看下没区别的情况,如下所示:[root@localhost ~]# cat shell.sh #!/bin/bash echo "\$*" for i in $* do echo $i done echo "\$@" for i in $@ do echo $i done [root@localhost ~]# ./shell.sh 1 2 3 4 5 $* 1 2 3 4 5 $@ 1 2 3 4 5 [root@localhost ~]#再看下有区别的情况,如下所示:[root@localhost ~]# cat shell.sh #!/bin/bash echo "\$*" for i in "$*" do echo $i done echo "\$@" for i in "$@" do echo $i done [root@localhost ~]# ./shell.sh 1 2 3 4 5 $* 1 2 3 4 5 $@ 1 2 3 4 5 [root@localhost ~]# 在上面的例子中,被双引号包含的 $* 里包含的所有参数被看做一个整体了,直接输出了 “1 2 3 4 5”,而 $@ 里的参数还是分开的。1.5 $?表示上个命令的退出状态或函数的返回值,如下所示:[root@localhost ~]# cat shell.sh #!/bin/bash pwd echo $? ls -l /root/abc echo $? [root@localhost ~]# ./shell.sh /root 0 ls: 无法访问/root/abc: 没有那个文件或目录 2 [root@localhost ~]#第一处 $? 的值为 0,表示命令 pwd 执行成功;第二处 $? 的值为 2,表示上个命令 ls 执行失败。[root@localhost ~]# cat shell.sh #!/bin/bash funcTest(){ return 6 } funcTest echo $? [root@localhost ~]# ./shell.sh 6 [root@localhost ~]# [root@localhost ~]# cat shell.sh #!/bin/bash funcTest(){ echo "abc" } val=$(funcTest) echo $? [root@localhost ~]# ./shell.sh 0 [root@localhost ~]#当 $? 用在函数上,如果有 return 语句,则获取的是 return 语句返回的值,范围是0~255。如果没有 return 语句,$? 的值表示函数中最后执行的那个命令的返回代码。1.6 $$表示脚本当前进程的 ID 号,如下所示: [root@localhost ~]# cat shell.sh #!/bin/bash echo $$ [root@localhost ~]# ./shell.sh 26033 [root@localhost ~]# 1.7 $!表示后台最后运行的进程的 ID 号,也可以理解为最近运行的进行的 ID 号,不一定是结束的。[root@localhost ~]# top & [2] 31702 [root@localhost ~]# echo $! 31702 [2]+ 已停止 top [root@localhost ~]#1.8 $-显示Shell命令使用的当前选项,与 set 命令功能相同,如下所示:[root@localhost ~]# cat shell.sh #!/bin/bash set -m echo $- set -C echo $- [root@localhost ~]# ./shell.sh hmB hmBC [root@localhost ~]#注意:在第二次输出的时候多了刚刚设置的参数 C。二、总结好了,Shell 特殊字符结合实例讲解完了,感觉不错就一键三连吧,有问题欢迎在评论区留言~转载自:https://blog.csdn.net/nyist_zxp/article/details/112797011
  • [最佳实践] 使用shell脚本创建新用户
    尝试用shell脚本创建用户,但整个过程并不顺利。利用文件中的名称列表批量添加用户,并给每个用户设置密码1231231、创建一个名单文件2、编辑脚本创建一个脚本useradd2.sh并编辑3、回车发现账户是创建成功,但是报错2个,一个是无法锁定useradd  /etc/passwd,一个是psswd:unrecognized option  ‘stdin’4、查询资料,按以下步骤尝试操作1)检查文件属性,发现文件权限是可读可写的:2)检查passwd 文件是否被设置了“i” 属性,该属性会指定当前文件不可被修改。发现未被设置“i”属性。5、怀疑是因为用户权限问题,尝试修改用户wyp权限为读写,修改失败。又尝试切换成为root用户切换成root用户后,现在发现报错只剩下psswd:unrecognized option  ‘stdin’了,看来刚刚的问题就真的是用户权限的问题。6、查询关于psswd:unrecognized option  ‘stdin’的信息,发现passwd的--stdin参数ubuntu不支持,而我所用的UOS操作系统基于Debian,是与Debian和Ubuntu同源的Linux操作系统。看来原因就是这个了,大家可以用centos7试试。
  • [技术干货] 【转】小韩写Shell -- 误删文件后的恢复
    前言      使用脚本删除文件,删除的同时脚本对删除的文件进行了备份。倘若我们是误删除的那么可以到达指定的备份目录下选择恢复。一、脚本内容[root@hya shell]# vim rm.backup.sh #!/bin/bash NAME=$1 now=`date +%Y%m%d%H%M` read -p "你确定要删除当前的文件或者文件夹吗 yes|no:" inpt read -p "请在确定一次 是否删除文件或者文件夹 yes|no:" input if [ $input == "yes" ] ||[ $input == "y" ];then mkdir -p /data/.$now #### 判断rsync是否已经安装 RSYNC=`rpm -qa rsync |wc -l` if [ $RSYNC -ne 0 ];then echo "现在开始备份数据" else #### 如果没有rsync就先安装rsync并启动 yum install xinetd rsync -y useradd -s /sbin/nologin -M rsync mkdir -p /data chown -R rsync.rsync /data/ echo "rsync_backup:123456" >/etc/rsync.password chmod 600 /etc/rsync.password fi rsync --daemon #### 判断要删除的文件是否存在 if [ -f $1 ] || [ -d $1 ];then ### 如果要删除的文件存在则开始备份 rsync -aR $1 /data/.$now/$1/ echo "数据备份成功" else echo "文件不存在,请重新确认文件名字" exit 1 fi echo "开始删除数据" /bin/rm -rf $1 echo "文件删除成功,若需要恢复请到 /data/.$now/路径下恢复" elif [ $input == "no" ] ||[ $input == "n" ] then exit 0 else echo "请输入yes|no" exit fi二、实操营[root@hya shell]# chmod +x rm.backup.sh #授权 (给脚本执行的权限) [root@hya ~]# cd /etc/ [root@hya etc]# sh /usr/local/shell/rm.backup.sh /etc/ 你确定要删除当前的文件或者文件夹吗 yes|no:yes 请在确定一次 是否删除文件或者文件夹 yes|no:yes 现在开始备份数据 数据备份成功 开始删除数据 文件删除成功,若需要恢复请到 /data/.202006291515/路径下恢复 ##查看是否删除 [root@hya etc]# ls -l 总用量 0 恢复 [root@hya etc]# mv /data/.202006291515/etc/* /etc/ [root@hya etc]# ls etc总结      此脚本可用于日常的文件误删除,一般情况下都可以。转载自:https://blog.csdn.net/yeyslspi59/article/details/108702575
  • [新手课堂] 常用的Linux命令后台运行shell脚本
    命令:nohup start.sh > trace.log 2>&1 &语法:nohup Command [arg...][&]操作系统中有三种常用的流:0:标准输入流1:标准输出流2:标准错误流”&“的意思是:即使终端关闭,或者电脑死机脚本依然运行”2>&1“的意思是:把标准输出流和标准错误流都导入到trace.log文件中
  • [云运维] shell脚本切割Nginx日志
    如果任由访问日志写下去,日志文件会变得越来越大,甚至是写满磁盘。所以,我们需要想办法把日志做切割,比如每天生成一个新的日志,旧的日志按规定时间删除即可。实现日志切割可以通过写shell脚本或者系统的日志切割机制实现。shell脚本切割Nginx日志切割脚本内容: #!/bin/bash logdir=/var/log/nginx #定义日志路径 prefix=`date -d "-1 day" +%y%m%d` #定义切割后的日志前缀 cd $logdir for f in `ls access.log` do mv $f $f-$prefix #把日志改名 done /bin/kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid 2>/dev/null) 2>/dev/null #生成新的日志 bzip2 *$prefix #压缩日志 find . -type f -mtime +180 |xargs /bin/rm -f #删除超过180天的老日志
  • [运维管理] 【GWS】【gsql】可以避免超时5分钟退出到shell吗
    【功能模块】【操作步骤&问题现象】退出到提示符都可以啊,这样可以\c 再连接认证一下为什么要退出gsql,回到shell呢?【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [设备专区] HUAWEI_5288_V3 ssh 登陆不能执行命令
    用ssh 连接bmc,可以正常连接,连接上去执行命令正常.用"ssh 命令行"带上"ipmcget  -d health" 或者其它命令,不会直接返回命令结果, 会出现"iBMC:/>",看起来像是 把命令丢掉了.ssh -vvv 如下显示 :debug1: Sending command: ipmcget  -d healthdebug2: channel 0: request exec confirm 1debug3: send packet: type 98debug2: channel_input_open_confirmation: channel 0: callback donedebug2: channel 0: open confirm rwindow 0 rmax 32768debug2: channel 0: rcvd adjust 2097152debug3: receive packet: type 99debug2: channel_input_status_confirm: type 99 id 0debug2: exec request accepted on channel 0iBMC:/->exit   这个是我手动输的debug3: receive packet: type 96debug2: channel 0: rcvd eofdebug2: channel 0: output open -> draindebug2: channel 0: obuf emptydebug2: channel 0: chan_shutdown_write (i0 o1 sock -1 wfd 5 efd 6 [write])debug2: channel 0: output drain -> closeddebug3: receive packet: type 98debug1: client_input_channel_req: channel 0 rtype exit-status reply 0debug3: receive packet: type 98debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0debug2: channel 0: rcvd eowdebug2: channel 0: chan_shutdown_read (i0 o3 sock -1 wfd 4 efd 6 [write])debug2: channel 0: input open -> closeddebug3: receive packet: type 97debug2: channel 0: rcvd closedebug3: channel 0: will not send data after closedebug2: channel 0: almost deaddebug2: channel 0: gc: notify userdebug2: channel 0: gc: user detacheddebug2: channel 0: send closedebug3: send packet: type 97debug2: channel 0: is deaddebug2: channel 0: garbage collectingdebug1: channel 0: free: client-session, nchannels 1debug3: channel 0: status: The following connections are open:  #0 client-session (t4 r0 i3/0 o3/0 e[write]/0 fd -1/-1/6 sock -1 cc -1)debug3: send packet: type 1debug3: fd 1 is not O_NONBLOCKTransferred: sent 2388, received 2612 bytes, in 273.3 secondsBytes per second: sent 8.7, received 9.6debug1: Exit status 0求各位老大帮忙看看. 
  • [技术干货] 更改linux用户登录shell的操作方法
    1、查看机器安装了哪些shell?有两种方法可以查看。第一种:[rocrocket@wupengchong ~]$ chsh -l /bin/sh/bin/bash/sbin/nologin/bin/zsh第二种:[rocrocket@wupengchong ~]$ cat /etc/shells /bin/sh/bin/bash/sbin/nologin/bin/zsh其实chsh -l也是来查看这个文件。2、查看当前正在使用的shell是哪个?[rocrocket@wupengchong ~]$ echo $SHELL/bin/bash注意SHELL一定要是大写。可以看到,我目前使用的shell是/bin/bash3、执行了zsh之后,我查看当前shell类型仍然是/bin/bash呢?请注意,我们虽然执行了zsh,但是所谓“当前的shell”是一个大环境的概念,是针对一个已登录的用户而言的。而我们执行zsh只是启动了一个zsh的解释器程序而已,并没有改变大环境。如果想改变“当前的shell”,那么还是要使用chsh才可以。4、修改我的shell为zsh[rocrocket@wupengchong ~]$ chsh -s /bin/zshChanging shell for rocrocket.Password:Shell changed.[rocrocket@wupengchong ~]$使用chsh加选项-s就可以修改登录的shell了!你会发现你现在执行echo $SHELL后仍然输出为/bin/bash,这是因为你需要重启你的shell才完全投入到zsh怀抱中去。5、chsh -s到底修改了哪里?秘密告诉你吧。chsh -s其实修改的就是/etc/passwd文件里和你的用户名相对应的那一行。现在我来查看下:[rocrocket@wupengchong ~]$ cat /etc/passwd|grep ^rocrocketrocrocket:x:500:500:rocrocket,China:/rocrocket/PSB/home:/bin/zsh看!你可以发现输出内容的最后部分已经变成了/bin/zsh了!下次你重启的时候,linux就会读取这一命令来启动你的shell了!好了,我要恢复正常工作,把shell修改会我熟悉的/bin/bash了![rocrocket@wupengchong ~]$ chsh -s /bin/bashChanging shell for rocrocket.Password:Shell changed.
总条数:136 到第
上滑加载中