Shebang
计算机程序中,shebang
指的是出现在文本文件的第一行前两个字符#!
在Unix系统中,程序会分析shebang
后面的内容,作为解释器的指令,例如
- 以
#!/bin/sh
开头的文件,程序在执行的时候会调用/bin/sh
,也就是bash解释器 - 以
#!/user/bin/python
开头的文件,代表指定python解释器去执行 - 以
#!/user/bin/env
开头的文件,是一种在不同平台上都能正确找到解释器的办法
注意事项:
- 如果脚本未指定
shebang
,脚本执行的时候,默认用当前shell去解释脚本,即$SHELL
- 如果
shebang
指定了可执行的解释器,如/bin/bash
、/usr/bin/python
,脚本在执行时,文件名会作为参数传递给解释器 - 如果
#!
指定的解释程序没有可执行权限,则会报错"bad interpreter:Permission denied" - 如果
#!
指定的解释程序不是一个可执行文件,那么指定的解释程序会被忽略,转而交给当前的SHELL去执行这个脚本。 - 如果
#!
指定的解释程序不存在,那么会报错"bad interpreter:No such file or directory" #!
之后的解释程序,需要写其绝对路径(如:#!/bin/bash),它是不会自动到$PATH中寻找解释器的。- 如果你使用"bash test.sh"这样的命令来执行脚本,那么
#!
这一行将会被忽略掉,解释器当然是用命令行中显示指定的bash。
shell变量
- 变量定义与赋值,注意变量与值之间不得有空格
name="超哥"
变量名
变量类型,bash默认把所有变量都认为是字符串
bash变量是弱类型,无需事先声明类型,是将声明和赋值同时进行
- 变量替换/引用
# name="超哥"
# echo ${name}
超哥
# echo $name # 可以省略花括号
超哥
- 变量名规则
- 名称定义要做到见名知意,切按照规则来,切不得引用保留关键字(help检查保留字)
- 只能包含数字、字母、下划线
- 不能以数字开头
- 不能用标点符号
- 变量名严格区分大小写
- 变量的作用域
- 本地变量,只针对当前的shell进程
- 环境变量,也称为全局变量,针对当前shell以及其任意子进程,环境变量也分
自定义
、内置
两种环境变量 - 局部变量,针对在
shell函数
或是shell脚本
中定义
- 位置参数变量:用于
shell脚本
中传递的参数 - 特殊变量:shell内置的特殊功效变量
- $?
- 0:成功
- 1-255:错误码
- $?
- 自定义变量
- 变量赋值:
varName=value
- 变量引用:
${varName}
、$varNam
- 双引号,变量名会替换为变量值
- 单引号,识别为普通字符串
- 变量赋值:
环境变量设置
环境变量一般指的是export内置命令导出的变量,用于定义shell的运行环境、保证shell命令的正确执行。
shell通过环境变量确定登录的用户名、PATH路径、文件系统等各种应用。
环境变量可以在命令行中临时创建,但是用户退出shell终端,变量即丢失,如要永久生效,需要修改环境变量配置文件
- 用户个人配置文件
~/.bash_profile
、~/.bashrc
远程登录用户特有文件 - 全局配置文件
/etc/profile
、/etc/bashrc
,且系统建议最好创建在/etc/profile.d
,而非直接修改主文件,修改全局配置文件,影响所有登录系统的用户。
检查系统环境变量的命令
- set,输出所有变量,包括全局变量、局部变量
- env,只显示全局变量
- declare,输出所有的变量,如同set
- export,显示和设置环境变量值
撤销环境变量
- unset 变量名,删除变量或函数
设置只读变量
- readonly,只有shell结束,只读变量失效
系统保留环境变量关键字
bash内嵌了诸多环境变量,用于定义bash的工作环境
# export | awk -F '[ :=]' 'print $3'
bash多命令执行
# ls /data;cd /tmp/;cd /home;cd /data
shell特殊参数变量
取出变量值
- 单引号,所见即所得,强引用
- 双引号,输出引号里所有内容,识别特殊符号,弱引用
- 无引号,连续的符号可以不加引号,有空格则有歧义,最好使用双引号
- 反引号,引用命令执行结果,等于
$()
用法
特殊变量
shell的特殊变量,用在如脚本,函数传递参数使用,有如下特殊的,位置参数变量
$0 获取shell脚本文件名,以及脚本路径
$n 获取shell脚本的第n个参数,n在1~9之间,如$1,$2,$9,大于9则需要写,${10},参数空格隔开
$# 获取执行的shell脚本后面的参数总个数
$* 获取shell脚本所有参数,不加引号等同于$@作用,加上引号"$*"作用是接收所有参数为单个字符串,"$1 $2 ..."
$@ 不加引号,效果同上,加引号,是接收所有参数为独立字符串,如"$1" "$2" "$3" ...,空格保留
$*和$@ 的区别
$*和$@都表示传递给函数或脚本的所有参数
当$*和$@不被双引号" "包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。
但是当它们被双引号" "包含时,就会有区别了:
"$*"会将所有的参数整体上看做一份数据,而不是把每个参数都看做一份数据。
"$@"仍然将每个参数都看作一份数据,彼此之间是独立的。
比如传递了5个参数,那么对于"$*"来说,这5个参数会合并到一起形成一份数据,它们之间是无法分隔的;而对于"$@"来说,这5个参数是互相独立的,它们是5份数据。
如果使用echo直接输出$*和$@做对比,是看不出区别的;但如果使用for循环来逐个输出数据,立即就能看出区别来。
shell特殊状态变量
$? 上一次命令执行状态返回值,0正确,非0失败
$$ 当前shell脚本的进程号
$! 上一次后台进程的PID
$_ 再次之前执行的命令,最后一个参数
查找方式man bash
搜索Special Parmeters
bash一些基础的内置命令
echo
-n 不换行输出
-e 解析字符串中的特殊符号
\n 换行
\r 回车
\t 制表符 四个空格
\b 退格
printf
打印命令,后加字符串
eval
执行多个命令
exec
不创建子进程,执行后续命令,且执行完毕,自动exit
shell子串
${变量} 返回变量值
${#变量} 返回变量长度,字符长度
${变量:start} 返回start索引之后的字符
${变量:start:length} 返回start索引之后的length长度的字符
${变量#word} 从变量开头删除最短匹配的word子串
${变量##word} 从变量开头删除最长匹配的word
${变量%word} 从变量结尾删除最短匹配的word
${变量%%word} 从变量结尾删除最长匹配的word
${变量/pattern/string} 用string代替第一个匹配的pattern
${变量//pattern/string} 用string代替所有匹配的pattern
特殊shell扩展变量
如果parameter变量值为空,返回word字符串
${parameter:-word}
如果parameter变量值为空,则word替代变量值,且返回其值
${parameter:=word}
如果parameter变量值为空,word当做stderr输出,否则输出变量值
用于设置变量为空导致错误时,返回的错误信息
${parameter:?word}
如果parameter变量值为空,什么都不错,否则word返回
${parameter:+word}
循环
for循环
# 数组
ARR=("70.182.58.148" "70.182.58.149" "70.182.58.150")
# 循环
for i in "${ARR[@]}"; do
echo $i
done
for循环+索引
# 数组
ARR=("70.182.58.148" "70.182.58.149" "70.182.58.150")
# 循环
for index in $(seq 0 $((${#ARR[@]}-1))); do
echo $index
echo ${ARR[$index]}
done