大括号{}出现在shell脚本的各个角落,其用法也各有不同。同音多义字在汉语中最容易让人混淆,而大括号也正是bash语言中的“同音多义字”。下面我就为大家介绍c语言大括号的用法。 {}第一种用法,符号扩展 #!/bin/bash echo \"{hello,world}\" ####################### # 输出为:"hello" "world" ####################### echo {ac} #只能是 ###################### # 输出为: a b c ###################### {}第二种用法,代码块表示法,与c语言中的作用相似,c语言中,有了{}的代码块,其变量作用域就改变了;bash中,却不存在这个功能,在{}中的内容,仍然与外部变量名相通。此外,{}代码块表示法还有一个作用,就是将代码块内所有的输入输出信息重定向。 #脚本1 #!/bin/bash a=123 { a=321; } #大括号两边内部变量与大括号之间一定要用空格隔开 echo "a = $a " #输出 a=321 #脚本2 #!/bin/bash File="`pwd`/fas" #fas是由自己在当前目录创建的文件 { read line1 read line2 } < $File #此处进行重定向,将fas文件的内容读入到line1和line2 echo "First line in $File is: " echo "$line1" echo echo "second line in $File is :" echo "$line2" exit 0 与大括号{}有些相似的符号是圆括号()。但圆括号()内的代码将启动一个子shell来运行,{}不会这样。 #!/bin/bash a=123 ( a=321; ) echo "a = $a" #a=123 附注: 1如果想让你的脚本像ls等命令一样通用,那么需要将命令复制到/usr/local/bin,并使用chmod 777 filename修改其执行权限。 2/bin目录、/sbin目录、/usr/local/bin/目录、/usr/local/sbin目录、/usr/bin目录、/usr/sbin目录的区别与联系 最需要注意的一点,usr不是user的意思,而是unix system resource的简称,也就是unix系统资源。在/usr这个目录下,放了一些系统 相同之处:都是一些命令; 不同之处: /bin:基本命令 /sbin:基本系统命令 /usr/bin:与/bin类似,包括此后安装软件的命令 /usr/sbin:与/sbin类似,包括此后增加的系统管理的一些命令 /usr/local/bin:与/bin,/usr/bin类似,但是局部(local)范围,linux是多用户系统,有分级的权限,有些软件内容必须添加在/usr/local/bin,而不是/usr /usr/local/sbin:同上 3好脚本需要珍藏,以备不时之需。
1、man
manual 是类 UNIX 系统的标准手册工具,共 9 卷,用 man man 可以看到 9 卷分别是什么内容:
如果只有一个含义,直接查询即可,比如 man ls ,但有很多是一词多义的: chmod, chown, chmod, stat, exit, info, socket, flock, open, write, printf, passwd 等等。
man 1 printf 表示 shell 命令,
man 3 printf 表示 C 语言标准库函数,
可以用 -a 选项显示全部,比如 man -a printf ,按 q 退出之后,可以按回车键表示继续看下一卷,或按 Ctrl-C 直接退出。
2、#!/bin/bash
#!/bin/bash 放在 shell 脚本开头,是指此脚本使用 /bin/bash 来解释执行。
#!/usr/bin/python 也是类似的, 表示用 /usr/bin/python 来解释执行 python 脚本,加了这行就可以用 /xxpy 的方式来运行了。
#!/usr/bin/env python 会去环境变量路径中寻找 python 目录。
3、shell 运行方式
(1) bash 1sh
创建子进程运行 1sh,需要有 r 权限。
(2) /1sh
创建子进程运行 1sh,需要有 r 和 x 权限。
(3) source 1sh
当前进程运行 1sh,需要有 r 权限,
(4) 1sh
点命令是 source 命令的另一种写法。
如何证明是在当前进程运行,还是创建子进程运行呢,下面用 2 种简单的方法:
(1) 创建一个子目录,然后用 cd 命令
使用 bash 执行结束后,可以看左边的提示符,当前的工作目录没有改变, cd 命令只对子进程产生影响:
使用 source 执行结束后,当前目录变成了 child 目录,因为 cd 命令对当前进程产生了影响:
(2) 变量赋值
bash 是创建子进程来执行脚本,所以子进程的变量,在父进不能访问;
而 source 在当前进程执行,所以脚本中对变量的赋值,当前进程能访问:
4、内部命令,外部命令
通过 type 命令可以查询某个命令是内部命令、外部命令,还是别名( alias ):
如果用 bash shell,可以通过 help 命令列出所有内部命令列表。
区别:
(1)内部命令不创建子进程,对当前进程有影响,执行速度快;
外部命令不在shell中,保存在一个独立的文件中,会创建新的进程来执行。
(2)内部命令查询帮助信息用:help 内部命令,比如 help cd ,
外部命令查询帮助信息用:外部命令 --help,比如 ls --help 。
当然除了 man 、 help 之外, info 也可以用于查询帮助信息。
5、重定向
(1) 输入重定向 <
(2) 输出重定向
① > 先清空该文件,再追加内容。
② >> 文件的内容不变,在文件末尾追加内容。
③ 2> 错误重定向
④ &> 表示无论是正确还是错误,都输出重定向。
(3) 输入、输出重定向的组合使用
将开始标记 和结束标记之间的内容作为 cat 的输入, cat 的输出重定向到文件 1txt:
这里的 EOF 只是开始和结尾的 tag,也可以换成其他的,比如ABCD:
6、变量
(1) 赋值, = 的两边不能有空格,否则被解释为命令:
(2) 算数运算用 let ,否则默认是字符串
(3) 把命令赋值给变量,意义不大:
(4) 把命令的结果赋值给变量:
(5) 作用范围
变量只在当前 shell 生效,子shell、父shell 都不能共用。
使用 export 命令之后,子shell 可以获取 父shell 的变量。其他终端不可以。
(6)变量不用了之后,可以删除: unset 变量名。
7、环境变量
(1) env 命令可以列出所有环境变量,一般是大写。
PATH 指定命令搜索路径,
PS1 可以使当前终端显示更友好,
UID 用户ID,
USER 用户名。
PWD 当前路径,
LD_LIBRARY_PATH 、 LD_PRELOAD 程序运行时,搜索动态库路径。
(2) set 命令可以列出系统中已经存在的 shell 变量,比 env 命令列出的变量更多。
(3) 预定义变量
$$ :当前进程的PID号
$0 :当前程序或脚本的名称
$ :用于返回上一条命令是否成功执行。如果成功执行,将返回数字0,否则返回非零数字(通常情况下都返回数字1)。
$ 或 $@ :保存传递给脚本或进程的所有参数
$# :脚本参数的个数,(类似C语言的 argc)
$1 、 $2 、 ${10} 等等 :位置变量,从命令行给脚本传参(类似C语言的argv[]),还有函数传参时会使用。
(4) 环境变量的配置文件
/etc/profile 是所有用户共用的。
~/bashrc 是某一个用户特有的。
如果存在重复定义的变量, /etc/profile 先执行,会被后执行的 ~/bashrc 覆盖。万一有变量被重复定义了,执行顺序很重要,可以在这 2 个文件中添加 echo 输出重定向到文件,来判断谁先被执行。
另外:
su root 是 non-login shell,不会加载所有的配置文件,不建议使用;
su - root 是 login shell,会加载所有配置文件,推荐使用这种方式。
8、数组
定义数组用小括号,例如: a=(1 2) ,
访问所有元素 ${a[@]} ,
数组元素的个数 ${#a[@]} ,
访问单个元素 ${a[0]} ,负号表示倒数第几个 ${a[-1]} 。
9、特殊字符
# 注释
; 分号用来分隔两条命令。
` 反引号 与 $() 都是用来执行命令的。
" 双引号(不完全引用)会对变量解释,
' 单引号(完全引用)不解释变量。
10、整数运算
默认会解释为字符串,所以需要用 expr ,注意空格:
除了 + 还有 - / % > < 等等,注意转义字符:
不支持小数运算:
另外 length 可以计算字符串长度:
表示乘方, expr 没有乘方功能:
let 简写为双圆括号:
11、园括号 () 里面的赋值,不会影响外面。
是圆括号()创建了一个子进程吗,还是其他原因呢?
可以做一个小实验,先打开 2 个终端:
先查看有几个 bash 进程,可以看到是 5 个:
把圆括号睡眠一下,趁这个时间再次查看 bash 数量,比刚才多了 1 个,等 sleep 结束之后再看 bash 数量又恢复 5个,说明圆括号()确实创建了子进程:
另外也可以再通过 cd 命令来看,圆括号中改变了工作目录,并不影响父进程:
12、 test 命令
test 命令是通过设置 $ 的值, 来让我们可以判断是否正常退出,或者条件是否为真,0 为 真,非 0 为假。
test 通常有三类测试:字符串、数字、文件,可以通过 man 查询具体用法:
man test|grep INTEGER
man test|grep STRING
man test|grep FILE
通过 man test 可以看到 test EXPRESSION 和 [ EXPRESSION ] 两种写法,
有时为了程序美观,可以把 test 换成方括号 [ ] 的写法。
(1) 字符串
字符串是否相等,会区分大小写:
(2) 整数
[] 扩展为 [[]] ,可以支持更多运算符。
(3) 文件
文件是否存在:
目录存在:
文件或目录存在:
13、大括号
(1) 表示某个范围内的值,主要是给 for 循环使用的
(2) 减少重复书写
cp -v /etc/passwd{,bak} 相当于 cp -v /etc/passwd /etc/passwdbak
14、if
(1)if-then-fi
(2)if-then-else-fi
(3)if-then-elif-then-else-fi
15、case-esac
case 语句的例子在很多文件都有,比如 grep -n case ~/bashrc
16、for
下面是 C 语言风格的写法:
17、while
用冒号表示条件为真,写一个死循环:
18、until
until 循环与 while 语法一致,只是条件为假才执行循环:
19、break 与 continue
20、字符串截取命令
basename 命令,可以用来删掉后缀名:
dirname 用于获取目录
其实它们不在乎这个目录是否真实存在,只是简单的处理一下字符串而已:
21、函数
函数定义的格式:
函数名(){ }
避免函数内部的变量影响到外面,使用 local 关键字限定作用域为该函数。
一、小括号,园括号()
1、单小括号 ()
①命令组。括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。
②命令替换。等同于`cmd`,shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。有些shell不支持,如tcsh。
③用于初始化数组。如:array=(a b c d)
2、双小括号 (( ))
①整数扩展。这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为1,或者 是"假",而一个非零值的表达式所返回的退出状态码将为0,或者是"true"。若是逻辑判断,表达式exp为真则为1,假则为0。
②只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。如:echo $((16#5f)) 结果为95 (16进位转十进制)
③单纯用 (( )) 也可重定义变量值,比如 a=5; ((a++)) 可将 $a 重定义为6
④双括号中的变量可以不使用$符号前缀。括号内支持多个表达式用逗号分开。
if ($i<5)if [ $i -lt 5 ]
if [ $a -ne 1 -a $a != 2 ]
if [ $a -ne 1] && [ $a != 2 ]
if [[ $a != 1 && $a != 2 ]]
for i in $(seq 0 4);do echo $i;done
for i in `seq 0 4`;do echo $i;done
for ((i=0;i<5;i++));do echo $i;done
for i in {04};do echo $i;done
二)中括号,方括号[]
1、单中括号 []
①bash 的内部命令,[和test是等同的。如果我们不用绝对路径指明,通常我们用的都是bash自带的命令。if/test结构中的左中括号是调用test的命令标识,右中括号是关闭条件判断的。这个命令把它的参数作为比较表达式或者作为文件测试,并且根据比较的结果来返回一个退出状态码。if/test结构中并不是必须右中括号,但是新版的Bash中要求必须这样。
②Test和[]中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq,-gt这种形式。无论是字符串比较还是整数比较都不支持大于号小于号。如果实在想用,对于字符串比较可以使用转义形式,如果比较"ab"和"bc":[ ab \< bc ],结果为真,也就是返回状态为0。[ ]中的逻辑与和逻辑或使用-a 和-o 表示。
③字符范围。用作正则表达式的一部分,描述一个匹配的字符范围。作为test用途的中括号内不能使用正则。
④在一个array 结构的上下文中,中括号用来引用数组中每个元素的编号。
2、双中括号[[ ]]
①[[是 bash 程序语言的关键字。并不是一个命令,[[ ]] 结构比[ ]结构更加通用。在[[和]]之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换。
②支持字符串的模式匹配,使用=~ *** 作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell ]],结果为真。[[ ]] 中匹配字符串或通配符,不需要引号。
③使用[[ ]]条件判断结构,而不是[ ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> *** 作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。
④bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。
三)大括号、花括号 {}
1、常规用法。
①大括号拓展。(通配(globbing))将对大括号中的文件名做扩展。在大括号中,不允许有空白,除非这个空白被引用或转义。第一种:对大括号中的以逗号分割的文件列表进行拓展。如 touch {a,b}txt 结果为atxt btxt。第二种:对大括号中以点点()分割的顺序文件列表起拓展作用,如:touch {ad}txt 结果为atxt btxt ctxt dtxt
bogon:/home/bash # ls {ex1,ex2}shex1sh ex2sh
bogon:/home/bash # ls {ex{13},ex4}sh
ex1sh ex2sh ex3sh ex4sh
bogon:/home/bash # ls {ex[1-3],ex4}sh
ex1sh ex2sh ex3sh ex4sh
②代码块,又被称为内部组,这个结构事实上创建了一个匿名函数 。与小括号中的命令不同,大括号内的命令不会新开一个子shell运行,即脚本余下部分仍可使用括号内变量。括号内的命令间用分号隔开,最后一个也必须有分号。{}的第一个命令和左括号之间必须要有一个空格。
2)几种特殊的替换结构:${var:-string},${var:+string},${var:=string},${var:string}
A,${var:-string}和${var:=string}:若变量var为空,则用在命令行中用string来替换${var:-string},否则变量var不为空时,则用变量var的值来替换${var:-string};对于${var:=string}的替换规则和${var:-string}是一样的,所不同之处是${var:=string}若var为空时,用string替换${var:=string}的同时,把string赋给变量var: ${var:=string}很常用的一种用法是,判断某个变量是否赋值,没有的话则给它赋上一个默认值。
B ${var:+string}的替换规则和上面的相反,即只有当var不是空的时候才替换成string,若var为空时则不替换或者说是替换成变量 var的值,即空值。(因为变量var此时为空,所以这两种说法是等价的)
C,${var:string}替换规则为:若变量var不为空,则用变量var的值来替换${var:string};若变量var为空,则把string输出到标准错误中,并从脚本中退出。我们可利用此特性来检查是否设置了变量的值。
补充扩展:在上面这五种替换结构中string不一定是常值的,可用另外一个变量的值或是一种命令的输出。
3)四种模式匹配替换结构:${var%pattern},${var%%pattern},${var#pattern},${var##pattern}
第一种模式:${variable%pattern},这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最短的匹配模式
第二种模式: ${variable%%pattern},这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最长的匹配模式
第三种模式:${variable#pattern} 这种模式时,shell在variable中查找,看它是否一给的模式pattern开始,如果是,就从命令行把variable中的内容去掉左边最短的匹配模式
第四种模式: ${variable##pattern} 这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最长的匹配模式
这四种模式中都不会改变variable的值,其中,只有在pattern中使用了匹配符号时,%和%%,#和##才有区别。结构中的pattern支持通配符,表示零个或多个任意字符,表示零个或一个任意字符,[]表示匹配中括号里面的字符,[!]表示不匹配中括号里面的字符
bogon:/home/bash # var=testcasebogon:/home/bash # echo $var
testcase
bogon:/home/bash # echo ${var%se}
testca
bogon:/home/bash # echo $var
testcase
bogon:/home/bash # echo ${var%%se}
te
bogon:/home/bash # echo ${var#e}
stcase
bogon:/home/bash # echo ${var##e}
stcase
bogon:/home/bash # echo ${var##e}
bogon:/home/bash # echo ${var##s}
e
bogon:/home/bash # echo ${var##test}
case
con=`cat profile|awk '{printf $0}' `
profile是你的配置文件名,这个是把所有内容存到con中。如果要加分隔符号的话,在printf中加就行,不过要注意用双引号引起来
其实,并不是你想的那样,因为testpy,也不是实时输出,只有在每次输出,清空一下stdout才能看到你想看到的效果。
testpy
import sysimport timefor i in range(1,10): print i sysstdoutflush() timesleep(1)
import subprocesssubp=subprocessPopen('python testpy',shell=True,stdout=subprocessPIPE)c=subpstdoutreadline()while c: print c c=subpstdoutreadline() print subpreturncode
这样,你观察很明显,如果你将sysstdoutflush(),删除,你会发现都是最后一刻才输出,因为print时代缓冲的。
之所以用到命令行参数,关键在于shell脚本需要与运行脚本的人员进行交互。
bash shell提供了命令行参数添加在命令后面的数据值)、命令行选项修改命令行为的单字符值)和直接读取键盘输入。
1、命令行参数
向shell脚本传递数据的最基本方式是使用命令行参数。
1)读取参数
读取输入的参数的变量为位置参数,位置参数通过标准数字表示,
其中$0为程序名称,$1为第一个参数,$2为第二个参数,依次类推,直到$9为第九个参数。
shell脚本自动将命令行参数赋值给各个位置变量。
同时输入多个参数可以是数值也可以是字符串)时,必须使用空格分隔要想在参数值中包含空格,就必须使用单引号或双引号)
当参数多于9个后,必须在shell脚本内使用大括号将变量括起来,如${10}。从而可以使用任意个参数。
2)读取程序名称
传递给变量$0的字符串实际上是程序的路径根据调用方法决定是相对还是绝对路径)。
使用basename命令可以去掉路径前缀,只获得程序名称名字中不 可以有空格)。
3)测试脚本
当脚本认为应该包含参数,却实际上没有数据时,就会出错。
好的方法是对参数进行检查来保证使用参数前确实存在数据,可以使用-n参数来检查。
例子:if [ –n “$1” ] then else fi
2、特殊的参数变量
用于跟踪命令行参数
1)参数计数
使用特殊变量$#测试执行脚本时包含的命令行参数个数。脚本中任何位置都可以 使用$#
例子:if [ $# –ne 2 ] 即可测试参数个数
可以使用${!#}来返回最后一个命令行参数当无参数时,$#为0,而${!#}为程序名)
2)获取所有数据
变量$将命令行中提供的所有参数作为一个单词处理,它将多个参数看成 一个参数。
变量$@将命令行中提供的所有参数作为同一个字符串中的多个单词处理。 允许对其中的值进行迭代一般使用for),分隔开不同参数
3、移位
shift命令能够改变命令行参数的相对位置。默 认将每个参数变量左移一个位置变量$0不变,把$1丢弃,注意不可以恢复了!)
在不清楚参数数目情况下,这是一个迭代参数的好办法。
可以为shift提供一个参数,来实现多位移变化。
4、处理选项
选项是由破折号引导的单个字母,用于更改命令的行为。
1,找出选项
1)处理简单选项
可以使用处理命令行参数相同的方法处理选项,抽取时使用case语句进行判断是否符合选项格式。
2)从参数中分离选项
同时使用选项和参数时,可以使用--指示选项列表的结束。发现--后,shell就知道后面的是普通参数了,停止使用case处理选项。
3)处理带值的选项
选项后紧跟参数值,一种方法是在case中对应选项后使用shift和读后一位参数的方法处理。更好的方法如 下:
2,使用getopt命令
getopt命令在处理选项和参数时非常方便。它对参数进行重新组 织,以便于解析
1)命令格式
getopt可以接受任意形式的选项和参数列表,并自动将它们转换为适当的格式。
命令格式为: getopt options optstring parameters
选项字符串(opstring)用于定义命令行中的有效选项字母,以及哪些选项字母需要参数值。
2)脚本中使用getopt
需要使用set命令将现有的命令行选项和参数替换为getopt命令生成的 格式化形式。
需要将原始脚本命令行参数送给getopt命令,然后将getopt命令输出送给set命令,如下:set – `getopts –q ab:cd “$@”`
但是getopt命令不能很好的处理带有空格的参数值,它将空格解析为参数分隔符,而不是将双引号引起来的两个 值合并成一个参数。解决办法如下:
3)更高级的getopts命令
getopts命令顺序的对现有的shell参数变量进行处理,每调用一次,只处理命令中检测到的参数中的一个。处理完所有参数后,以大于0的退出 状态退出。
非常适宜于在循环中解析所有命令行参数
格式为: getopts optstring variable
$optarg包含需要参数值的选项要使用的值,$optind包含getopts停止处理时在参数列表中的位置。
注意:当getopts处理时,会将选项前的-去掉,所以对应的case中不需要破折号。
好的特性:
1)可以在参数值中包含空格
2)选项字母和参数值中间可以没有空格
3)将在命令行中找到的未定义的选项都绑定为单一的输出——问号
5、标准化选项
有一些字母选项具有标准含义。最好按照标准含义定义选项意义
-a –c –d –e –f –h –i –l –n –o –q –r –s –v- x –y
6、获取用户输入
当需要在执行过程中获得执行脚本人员的输入,使用read命令
1)基本读取
read命令接受标准输入或其他文件描述符输入。读入后将数据放入 一个标准变量中。
-p 允许在read命令行中直接指定一个提示。
可以指定多个变量,也可以不指定将放置在reply环境变量中)
2)计时
使用-t指定一个计时器,计时数满还未输入,read返回一个非0的退出状态。
使用-n指定输入的字符个数,输入达到预定数目时,就自动结束输入
3)默读
使用-s使输入不显示在终端例如输入密码)
4)读取文件
最常用的方法是使用cat命令,并通过管道传给包含read的while语句。
做 Java 的肯定都接触过 Linux 系统,那么很多时候我们在开发的过程中都是把我们项目打成一个jar包,或者是war包的形式,然后通过 XFTP 上传到我们服务器的指定目录,然后运行一端启动脚本,让我们的项目变得可以访问 就像 /sh servicesh start 然后启动我们写好的 sh 的shell脚本。接下来我们就来学习一下关于 Shell 脚本是如何写出来的。
Shell 脚本是什么?Shell是一个命令解释器,它的作用是解释执行用户输入的命令及程序等,也就是说,我们用户每输入一条命令,Shell 就会相对应的执行一条命令。当命令或程序语句不在命令行下执行,而是通过一个程序文件来执行时,该程序文件就被称为Shell脚本。
在我们的 Shell 脚本中,会有各种各样的内容,赋值,计算,循环等一系列的 *** 作,接下来我们就来看看这个 Shell 脚本怎么写吧
1查看自己当前系统默认的 Shell
echo $SHELL
输出:/bin/bash
2查看系统支持的Shell
cat /etc/shells
输出:
/bin/sh /bin/bash /usr/bin/sh /usr/bin/bash
也就是说,我们的云服务器是支持我们在这里给他安排 Shell 脚本的
我们这时候先来安排一下 sh 的文件,创建一个文件夹,然后在其中创建一个 sh 的文件。
mkdir /usr/local/shelltest
touch testsh
创建完成我们编辑一下内容
vim testsh
然后我们出来运行一下我们的 Shell 的第一个脚本
bash testsh
出来的结果是 Hello World Shell
一个及其简单的脚本出现了,接下我们就分析一波我们写了点啥?
#!/bin/bash
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell
我们在之前也使用了 echo $SHELL 来查看了自己系统默认的是哪一种 sh 解析器,之前看到的是/bin/bash,所以我们在写 Shell 脚本的时候,我们在开头默认的约定中,我们写了这个是用 /bin/bash 来进行解释的,
那么我们如何像之前调用我们的当前目录中的 Shell 脚本一样去调用他呢?就像这个样子的 /sh servicesh start
1授权,
我们先不授权试一下看看能通过 /testsh 进行调用么
bash: /testsh: Permission denied 会提示这个,也就是没有授权定义,
授权命令:chmod +x testsh
2执行 /testsh
然后调用就能正常输出了,就是说,在当前的目录下执行这个脚本命令。
变量命名实际上很简单,我们先来试一下
name=zhiyikeji
这时候我们怎么使用变量呢?实际上只要在前面加上一个符号就可以 $
echo $name
上面的两种写法都是可以的,外面的大括号加和不加区别不大,可以省略,直接就 $name 就可以使用你定义的变量
使用括号的意义一般在于区别某些变量,比如你写了一串的内容,可能写的是 echo $nameismyfriend ,如果连在一起,是不是有点尴尬,这时候就可以使用括号区别一下, echo ${name}ismyfriend 不使用括号的时候,他就去找nameismyfriend这个变量了,就无法出来我们要的效果。
unset name
这时候我们就把我们刚才定义的 name=zhiyikeji 这个变量给去掉了,我们可以调用一下我们的变量看是什么?
echo $name
这是不是就证明我们自己定义的变量已经删除了
那么我们需要一个关键字,大家肯定能想到是什么关键字 readonly
我们先给name赋值,然后使用 readonly 设置只读,然后再改变一下试试,
竟然是真的,如果不设置只读,是不是会重新可以进行赋值,我们测试个年龄,
所以我们就可以肯定,readonly就是设置只读的关键词,记住了么?
那么设置只读的变量可以删除么?毕竟总有杠精的面试官会提问这个棘手的问题,但是,阿粉试过的所有方式好像都是不行的,阿粉就直接重启了自己的服务器,这样临时的变量就不存在了!
说真的,Shell脚本的流程控制数一般才是yyds,为什么这么说,因为你在写大部分的脚本的时候,流程控制的地方永远是最多的,判断,选择,等等一系列的函数,当时熟练使用的时候,就发现这东西确实很有意思。
我们先说最简单的 if else 这也是我们最经常使用的判断,在写 Shell 脚本的时候,就不像我们的 Java 中直接写
Xshell 中的语法就不是这个样子的, Xshell 语法:
末尾的 fi 就是 if 倒过来拼写,我们可以写一个 if 的脚本试一下这个流程能否理解。
这里申明一下,
我们在上面这段脚本中写就是内容就是,我们给脚本传入一个值,然后比对这个值和2的大小关系,然后输出我们指定的内容。
运行后就能看到
$1 表示我们给 Shell 脚本输入的第一个参数, $0 就是你写的shell脚本本身的名字,$2 是我们给 Shell 脚本传的第二个参数
大家在部署某些项目的时候,是不是启动命令就很简洁,就是 sh servicesh start 类似这种的,那我们来看看一般这种是怎么写的,这就用到了另外一块的内容,和 if 类似,在 Java 中也有,那就是 Case
我们先来看看 Case 的语法,
case esac 实际上就和 Java 中的 Case 是非常相似的,case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令 esac 是一个结束的标志。
光说不练,假把式,我们来搞一下试试写一个脚本来搞一下。就用我们刚才说的 sh servicsh start 来进行测试。
我们来看看运行结果
那么这段 Shell 脚本是什么意思呢?其实很简单,匹配我们传入的第一个字符,和 start 还有 stop 进行比较,如果匹配上之后,输出命令,最后退出即可。
是不是感觉没有那么复杂了呢?
说到流程控制,那么肯定不能不说 for , 毕竟 for 循环在 Java 中那可是重头戏。
我们先看他的格式
那么我们有没有说像是 Java 中那种 for 循环一样的方式呢?比如说这个 for ((i=1; i<=j; i++))
实际上也是支持这种的,我们来写一个试试。
执行一下看看
既然有 for 那是不是就有 while 呢?是的,没错,确实是有 while ,也是循环的意思,但是写法有略微不一样的地方
我们来举个尝试打印九九乘法表来看一下
是不是也挺简单的?
其实 Shell 脚本的编写一般都是在实际应用中提升,单纯的写测试脚本,也是可以让自己对知识的掌握比较充分,而我们一般都是写一些比较简单的脚本,复杂的不是还有运维么?
以上就是关于c语言大括号的用法全部的内容,包括:c语言大括号的用法、shell 随笔、求助shell编程高手等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)