shell变量、参数传递($)、脚本执⾏等常见操作总结
⽂章⽬录
shell脚本⼀般以 *.sh 的⽅式进⾏命名,第⼀⾏为#!/bin/bash。
⼀般情况下,⼈们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为#!/bin/bash。
#!告诉系统其后路径所指定的程序即是解释此脚本⽂件的Shell程序。
shell脚本扩展名为sh(sh代表shell),扩展名并不影响脚本执⾏,见名知意就好。
1. 脚本执⾏
作为可执⾏程序(直接使⽤⽂件执⾏) ,以执⾏ test.sh 为例
./test.sh:⼀定要写成./test.sh,⽽不是test.sh,运⾏其它⼆进制的程序也⼀样,直接写test.sh,linux系统会去PATH⾥寻有没有叫test.sh的,⽽只有/bin, /sbin, /usr/bin,/usr/sbin等在PATH⾥,你的当前⽬录通常不在PATH⾥,所以写成test.sh是不到命令的,要⽤./test.sh告诉系统说,就在当前⽬录。
sh test.sh:如果在当前路径下执⾏,可以使⽤sh test.sh 执⾏ test.sh脚本
作为解释器参数执⾏
直接执⾏解释器,后⾯添加shell脚本作为解释器参数。eg:/bin/zsh 1_hello.sh,这么指定后不需要在第⼀⾏中指定解释器信息了(#!字段),写了也不会执⾏。
2. 变量
shell变量
- 区分⼤⼩写
- 给变量赋值时不能有空格,如下图中的18⾏的空格就不能正常识别。
shell脚本返回执行结果- 定义变量时,变量名不加$符号,使⽤的时候加上$符号,使⽤的时候加不加{}都可以,不过为了上⾯这种给变量赋值的情况也不⽤
加$。推荐给所有变量加上花括号,这是个好的编程习惯。
```shell
Name="orig max"
echo $Name
name="orig"
echo $name
echo ${name}
name="changed"
echo $name
echo ${name}
echo '$namewhere'
echo '${name}where'
echo "$namewhere" #输出空,因为没有这个变量,此时需要加{}才能正常识别    echo "${name}where"
```
字符串
字符串可以⽤单、双引号,也可以不⽤引号。单双引号的区别跟PHP类似。
单引号字符串的限制:
单引号中的任何字符都将原样输出,包括其中的变量
单引号中不能再出现单引号,即使使⽤转义字符也不⾏
双引号的优点:
双引号中可以有变量
可以出现转义字符
字符串拼接
greet="hello, "${name}"!"
echo$greet
获取字符串长度:使⽤#,eg:echo ${#greet}
提取⼦字符串:eg:sub=${greet:5:10}
数组
在Shell中,⽤括号来表⽰数组,数组元素⽤"空格"符号分割开。如果使⽤,,将会赋值给第⼀个元素。array2=(1 2 3 4 5 6 )才能正常输出。
使⽤**@符号**可以获取数组中的所有元素,eg:echo ${array2[@]}
# 数组
echo"array"
array=(1,2,3,4,5)
for i in{0..5}
do
echo${array[i]}
done
echo"array2"
array2=(123456)
for i in{0..5}
do
echo${array2[i]}
done
获取数组的长度的⽅法和字符串的⼀样,使⽤#,只不过这⾥需要⾜以使⽤的是哪种。
echo${#array[@]}#1 获得数组元素个数
echo${#array[0]}#9 数组中第⼀个元素的长度,等价于echo ${#array}
echo${#array}#9
通过上⾯的输出结果,可以获知,数组中使⽤,,shell将会把,当成变量的⼀部分,指导遇到空格或者结束符)
Shell 注释:shell中只能通过#添加注释,没有多⾏注释,每⾏⼀个。如果要注释多⾏,使⽤编辑器或者定义成⼀个函数,这样就只⽤注释调⽤函数的地⽅。
获取当前时间并格式化
time=$(date"+%Y.%m.%d-%H%M%S")
echo${time}
# logs⽂件根据时间重命名
mv logs logs_${time}
date后⾯有⼀个空格,否则⽆法识别命令,shell对空格还是很严格的。
参数含义:
Y显⽰4位年份,如:2018;
y显⽰2位年份,如:18。
m表⽰⽉份;M表⽰分钟;
d表⽰⽇期(⼏号);⽽D则表⽰当前⽇期,如:1/18/18(也就是2018.1.18)
H表⽰⼩时;⽽h显⽰⽉份的英⽂,如Oct表⽰ 10⽉
S显⽰当前秒钟,单位为秒。
s显⽰当前秒钟,单位为毫秒;
refer:
3. 传递参数- $
在执⾏ Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表⼀个数字,1 为执⾏脚本的第⼀个参数,2 为执⾏脚本的第⼆个参数,$0为shell脚本名称。其中不受执⾏⽅式的影响,即,/bin/sh 3_transf_param.sh 和 ./3_transf_param.sh的效果⼀样,其中para 0还是⽂件名。
还有⼏个特殊字符⽤来处理参数:
echo'$# = '$##传递到脚本的参数个数,不包括⽂件名
echo'$* = '$*#以⼀个单字符串显⽰所有向脚本传递的参数。
echo'$@ = '"$@"#与$*相同,但是使⽤时加引号,并在引号中返回每个参数。
echo'$$ = '"$$"#脚本运⾏的当前进程ID
echo'$? = '"$?"#显⽰最后命令的退出状态。0表⽰没有错误,其他任何值表明有错误。
echo`$n`#n 代表⼀个数字,1 为执⾏脚本的第⼀个参数,2 为执⾏脚本的第⼆个参数,`$0`为shell脚本名称。
$* 与 $@ 区别:
相同点:都是引⽤所有参数。
不同点:只有在双引号中体现出来。假设在脚本运⾏时写了三个参数 1、2、3,,则 " * " 等价于 “1 2 3”(传递了⼀个参数),⽽“@” 等价于 “1” “2” “3”(传递了三个参数)。
如下代码:
for i in"$*";do
echo'$*'$i
done
for i in"$@";do
echo'$@'$i
done
./3_transf_param.sh 123 456 sdf输出结果为:
4. 表达式
脚本 5_operation.sh
注意点
乘号(*)前边必须加反斜杠()才能实现乘法运算;
表达式和运算符之间要有空格
if和[之间也要有空格,for循环⼀定有空格
但是变量定义的时候变量和=之前不能有空格
疑问
下⾯的shell中${val6}不输出任何东西?
# ${val6}在这⾥不输出任何东西?
val6=`expr5==6`
echo'expr 5 == 6 ?'${val6}
以下语句导致溢出?
# 应该使⽤单反引号,以下语句导致栈溢出?
val2='expr 5 * 6'
echo'error: expr 5 * 6 = '${val2}
var=0
# bash ⾥⾯可以⽤ (( )) 执⾏ C 风格的算术表达式。
# 如果你接下来还会读 if 那⼀段的话,你还会知道这玩意的返回和 C 的⾮零真假判断⼀致。
(( var +=1))# 这是⼀种,现在 var 是 1
(( var++))# 这也是⼀种⾃增,2
(( var = var * var ))# 怎么来乘法了!var 现在是 4。
let'var = var / 3'# 还是只有 bash 才能⽤的拓展。除法是整数除法,向 0 舍⼊,1。
# 来⼀点不⼀定要 bash 的⽅法吧,毕竟 sh 还有很多种,总不能全报错了吧。
# $(( )) 会展开成为这个 C 表达式求值的结果。以前 bash 有个 $[ ] ⼀样,但是别去⽤。
echo$((var +=2))# echo 出 3,var 现在是 3。
var=$((var-1))# 展开成 var=2,var 现在是……还⽤说吗,2。
shell调试模式:sh -x strangescript
shell只检查语法,不执⾏脚本:sh -n your_script
在计算领域中,Shebang(也称为 Hashbang )是⼀个由井号和叹号构成的字符序列 #! ,其出现在⽂本⽂件的第⼀⾏的前两个字符。 在⽂件中存在 Shebang 的情况下,类 Unix 操作系统的程序加载器会分析 Shebang 后的内容,将这些内容作为解释器指令,并调⽤该指令,并将载有 Shebang 的⽂件路径作
为该解释器的参数[1]。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。