语言简介
Bash,Unix shell的一种,在1987年由布莱恩·福克斯为了GNU打算而编写。
1989年公布第一个正式版本,原先是打算用在GNU操作系统上,但能运行于大多数类Unix零碎的操作系统之上,包含Linux与Mac OS X v10.4起至macOS Mojave都将它作为默认shell,
而自macOS Catalina,默认Shell以zsh取代。
— 来自于维基百科
语法与个性
bash的命令语法是Bourne shell命令语法的超集。
数量宏大的Bourne shell脚本大多不经批改即能够在bash中执行,只有那些援用了Bourne非凡变量或应用了Bourne的内置命令的脚本才须要批改。
bash的命令语法很多来自Korn shell(ksh)和C shell(csh),例如命令行编辑,命令历史,目录栈,$RANDOM和$PPID变量,以及POSIX的命令置换语法:$(…)。
作为一个交互式的shell,按下TAB键即可主动补全已局部输出的程序名,文件名,变量名等等。
应用’function’关键字时,Bash的函数申明与Bourne/Korn/POSIX脚本不兼容(Korn shell 有同样的问题)。
不过Bash也承受Bourne/Korn/POSIX的函数申明语法。
因为许多不同,Bash脚本很少能在Bourne或Korn解释器中运行,除非编写脚本时刻意放弃兼容性。
然而,随着Linux的遍及,这种形式正变得越来越少。不过在POSIX模式下,Bash更加合乎POSIX。
语法
变量定义
name="foo"
留神,变量名和等号之间不能有空格,这可能和你相熟的所有编程语言都不一样。
同时,变量名的命名须遵循如下规定:
- 命名只能应用英文字母,数字和下划线,首个字符不能以数字结尾。
- 两头不能有空格,能够应用下划线(\_)。
- 不能应用标点符号。
- 不能应用bash里的关键字(可用help命令查看保留关键字)。
应用变量
应用只须要加上美元符号 $
即可
打印: echo $name
打印后果: foo
如果不加美元符号, 则就是一个字符串:
打印: echo name
打印后果: name
当然变量的两边也能够加上花括号:
name="foo"
echo "I am good at ${name} Script"
echo "I am good at $name Script"
// 这两句是等价的 花括号的劣势在于空格
定义只读变量
url="mo.fish"
readonly url
url="jandan.net"
再次赋值时,即会报错: index.sh: line 14: url: readonly variable
删除变量
name="foo"
url="mo.fish"
unset url
unset name
留神: 只读变量是无奈删除的, 报错: index.sh: line 14: unset: url: cannot unset: readonly variable
一般变量被删除后,打印后果为空
对于字符串
在 shell 中 尽量应用双引号
因为单引号中,变量是有效的, 这是很重要的一点
字符串拼接
通过空格即可拼接:
name="foo"
url="mo.fish"
echo $name $url
字符串长度
加上 #
即可
name="foo"
echo ${#name}
字符串截取
应用冒号:
url="mo.fish"
echo ${url:1:3}
// 打印: o.f
// 从 0 开始 第一位至第三位
数组
数组定义
用括号来示意数组,数组元素用”空格”符号宰割开。
arr=($name $url)
echo ${arr[1]}
// echo ${arr} 等于 echo ${arr[0]}“
打印所有数组
这一点是比拟非凡的
arr=($name $url)
echo ${arr[@]}
获取数组长度
和字符串相似:
length=${#arr[@]}
echo $length
流程管制
if else
if 和 其余语言有些不太雷同:
if [ $name=="foo" ]
then
echo "name 是 foo"
fi
// fi 示意完结 因为不像其余语言 没有 {}
而 else 和 if else 的话 这样写:
if [ $name != "foo" ]
then
echo "name 是 foo"
else
echo "不合乎"
fi
if [ $name == "bar" ] ;then
echo "name 是 bar"
elif [ $name == "foo" ]; then
echo "name 是 foo"
else
echo "不合乎"
fi
这种应用 ; then
的写法 可能更加合乎咱们的直觉
for
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
while
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
for 和 while 都只用一个简略例子
函数
定义
GrewerFn(){
echo "这是我的第一个 shell 函数!"
}
执行
执行是一个简略的操作:
GrewerFn(){
echo "这是我的第一个 shell 函数!"
}
GrewerFn
只需写上函数名称 即可调用
参数
GrewerFn(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "打印所有参数 $@ !"
}
GrewerFn 1 "qwer" "zxc"
通过这样的办法可能传递参数
而外面 $1
, $2
这样的参数解决能够参数上面的表格:
参数解决 | 阐明 |
---|---|
$# | 传递到脚本或函数的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数 |
$$ | 脚本运行的以后过程ID号 |
$! | 后盾运行的最初一个过程的ID号 |
$@ | 与$*雷同,然而应用时加引号,并在引号中返回每个参数。 |
$- | 显示Shell应用的以后选项,与set命令性能雷同。 |
$? | 显示最初命令的退出状态。0示意没有谬误,其余任何值表明有谬误。 |
交互
获取用户输出
read
应用的办法很简略:
read yourName
echo "you name is $yourName"
前面还能加参数, 如
-p 参数,容许在 read 命令行中间接指定一个提醒。
read -p "输出网站名:" website
echo "你输出的网站名是 $website"
限定字符:
read -n1 -p "Do you want to continue [Y/N]?" answer
case $answer in
Y | y)
echo "fine ,continue";;
N | n)
echo "ok,good bye";;
*)
echo "error choice";;
esac
select
PS3='Please enter your choice: '
options=("Option 1" "Option 2" "Option 3" "Quit")
select opt in "${options[@]}"
do
case $opt in
"Option 1")
echo "you chose choice 1"
;;
"Option 2")
echo "you chose choice 2"
;;
"Option 3")
echo "you chose choice $REPLY which is $opt"
;;
"Quit")
break
;;
*) echo "invalid option $REPLY";;
esac
done
小补充
PS1——默认提示符
PS2——再谈提示符
PS3——Shell脚本中应用select时的提示符
PS4——PS4-“set -x”用来批改跟踪输入的前缀
具体参考: https://os.51cto.com/art/2012…
其余
还有一个比拟热门的 expect ,这里就不多说了, 须要下载, 有些嵌入式环境不反对
罕用场景
- Linux 上的主动脚本: 如应用 crontab 执行定时工作, 读取批改文件, 我之前的一篇文章也应用到了他:https://segmentfault.com/a/11…
-
登录脚本等等, 能够省略很多麻烦的过程
当然相较于其余语言, 都是能够这样做, shell 的劣势就在于原生反对
- 初始化环境, 应用脚本一键初始化整个 linux 环境, 如果接触过 cli 的话应该晓得他的作用
结语
shell 作为 linux 官网的语言, 他附带了很多性能, 给咱们提供了很多便当
在没有环境的时候, 也能够间接运行, 学会此语言, 能够帮忙你在服务器畛域大展拳脚
以上局部例子来源于 https://www.runoob.com/linux/…
发表回复