文章目录
编译为可执行文件?
CFLAGS+=-static shc -r -f script.sh # 生成script.sh.x二进制文件
basic
-x
: 显示脚本执行的顺序-n
: 不运行,只检查语法
#!/bin/sh
#!/bin/bash
#!/usr/bin/make
# variable
# 注意: 默认的变量类型都是字符串!单引号中的变量不会扩展!
# 变量只能字母开头,若中间有空格需使用引号! 注意: 两边不能有空格!
set -e # 后面的脚本语句有任何一个错误(不返回0)就直接退出!
declare -i sum=1+2+3 # -a:数组;-x:将变量设为环境变量,+x:取消;-r:readonly
age=22; age=${age}+1 # 结果为'22+1'
unset age # 清除变量,unset b[2]删除第3个元素
# array
a=() # 定义一个空数组
a=(${a[@]} 'newitem') # 追加元素,单引号双引号都行
a[1]=2 # 修改第2个元素为2
a[5]=3 # 若下标5越界则自动追加到最后一个索引.但在此使用a[5]操作时仍然操作的是最后一个追加的元素而不是继续追加!
unset a[5] # 删除元素
a=($(seq 100)) # 1~100; 'echo $a'会显示1,即类似于C的数组!
a=((${a} 101)) # 追加元素
b=("tom" john) # 1个数组,里面存放3个字符串
echo ${b[*]} # 显示所有,访问整个数组则为: ${b[@]}
echo ${#a[@]} # 100,数组的元素个数(#a[2]表第3个元素占几个字符),也可吧'@'换成'*'!
echo ${16#1a} # 26,十六进制1a转化为10进制
c=(${a[@]:98:2}) # '99 100',:索引:个数,不指定个数表后面所有!不指定起始则0开始!索引也可是负数表示倒数第几个!
c=(${a[@]:value:newvalue}) # 模式替换
string
operation | function |
---|---|
${var=str} | 若var未定义,则返回str并将var赋值为str.其他情况返回$var. |
${var:=str} | 若var未定义或为空,则返回str并将var赋值为str.其他情况返回$var. |
${var?str} | 若var未定义,则将str写入stderr,本语句失败!其他情况返回$var. |
${var:?str} | 若var未定义或为空,则将str写入stderr,本语句失败!其他情况返回$var. |
${var-str} | 若var未定义,则返回str.否则返回$var. |
${var:-str} | 若var未定义或为空,则返回str.否则返回$var. |
${var+str} | 若var已定义(也可为空),则返回str.未定义时则返回空,如空字符串! |
${var:+str} | 若var已定义且非空,则返回str.空值或未定义则返回空,如空字符串! |
${var:0:2} | 索引+个数,此处是提取最左边的2个字符! |
以下操作符的#、% 来配合通配符!! 表示仅操作通配符所匹配的文本! | |
${var#*str} | 从左到右搜索,删除该最短匹配,返回删除后的子串! |
${var##s*r} | 从左到右搜索,删除该最长匹配,返回删除后的子串! extension="${filepath##*.}" |
${var%str*} | 从右到左搜索,删除该最短匹配,返回删除后的子串! filename="${filepath%.*}" |
${var%%s*r} | 从右到左搜索,删除该最长匹配,返回删除后的子串! |
${var/s/r} | 从左至右搜索str替换所有str为r,返回替换后的整体结果!不写r即是删除! |
${var/s/r} | 从右到左搜索最短匹配s替换为r,返回替换后的整体结果! |
${var//s/r} | 从右到左搜索最长匹配s替换为r,返回替换后的整体结果!请类比其他 |
case
- break
类似于C
中的break
比C的switch更复杂: 条件分支支持字符串
每个分支还可以有三个选项:break
、无条件继续(;&
)、有条件继续(;;&
)
其中后两者需要bash4.1
以上的版本($BASH_VERSION
)! - 分支条件
必须以右括号结尾,可以使用方括号等正则表达式的形式:*
(任意字串)?
(任意字符)[abc]
(abc中的任意一个)[a-n]
(a-n任意一个)|
(或)
最后一分支条件类似于default
(没有匹配项)使用*)
表示 - 分支命令
必须以双分号结尾,但最后一个可以不加;;
case "$var" in
[yY]|[Yy][Ee][Ss])
echo "Good Morning";;
*)
echo "Sorry,not recognized!"
exit 1
esac
function
- 函数的退出码
为最后一条命令的退出状态码.因此无法知道其他语句是否成功!
可以使用return命令来指定退出码,此时$?返回的就是该值.但注意,其范围在[0,255]
- 函数的输出
可以使用echo来定制函数输出,然后`var=``funame param1..```来接收输出.
注意与退出状态的区分!退出状态是函数return的或最后一条语句的执行状态,且其值有范围. - 函数库文件
定义一个里面全是函数脚本共其他脚本使用,不是看起来那么简单,因为shell本质是启动一个进程来执行脚本文件.
如果不想另起进程,应该使用source
命令(可用.来替代)exec
也不会产生新的,但它会关闭当前的shell的进程.. ../funcs.sh
: 读取并执行上层目录中的脚本,以便导入其中的变量和函数!
# '$#'表参数个数; '$1'表示参数1...注意与脚本变量区分,这些跳到函数外就变成了脚本的变量!
# 默认情况下,函数内可以尽情访问函数外的变量,但一般不这么做.使用local定义局部最好!
# 注意: 向函数传递数组变量只会传递第一个元素,应该把数组解开当作所有参数传递(在函数内部再把所有参数构造起来)
function factorial { # 也可以直接'factorial() {}'定义
local newarray
newarray=(`echo "$@"`) # $@就是解包元素组后的所有元素
echo ${newarray[*]} # 返回数组的方式
# 函数是可以调用自己的`fractorial $tmp`
}
function finish {
# 类比于finally
# 收尾代码,比如要删除的一些临时目录
# 或者是一些必须执行的代码,如无论后面如何,都启动服务
sudo service xxx start
}
trap finish EXIT
sudo service xxx stop
sleep
# 默认以秒为单位,支持小数
# usleep以微秒为单位即10^-6
sleep 0.8s # 可不加s
sleep 0.8m # 分钟
sleep 0.8h # 小时
sleep 0.8d # 天
read
# 读取以空格为分割的两个输入,分别赋值给var1,var2;若输入多余2个,则余下的所有均赋值给var2
read var1 var2
# 提示用户输入;30内有效的输入会赋给变量var,否则略过该语句;可以加上-s参数,用户输入将不可见!
read -p "please input your name" -t 30 var
# 限定只取一个字符,不用用户回车了
read -n 1 var
# -e:会对\n等字符做转换而不是当成纯字符.-n:不要换行了(默认会给字符串加上换行)
echo -en '1.\tFirst'
# 下面颜色echo+read来生成选择菜单!
function menu {
clear;echo
echo -e "\t\t\tSys Admin Menu\n"
echo -e "\t1. Display disk space\n"
echo -e "\t2. Display memory usage\n"
echo -en "\t\tEnter option: "
read -n 1 option
}
case $option in
1) diskspace;; # 调用某个函数
2) memoryusage;;
*) echo "Sorry,wrong option";;
esac
getopts
- bash内部命令
不同于getopt
; 注意getopts
解析后会移除选项前的-
号!
如果选项值要包含空格请使用双引号括起来! - $OPTIND
表正在处理第几个选项(从1开始),每处理完一个该值就会+1
所以可以在循环处理后shift $[ $OPTIND-1 ]
来移动到第1个参数(注意区别于选项) - $OPTARG
如果一个选项需要选项值并且传递了,则表示该选项的选项值.
如果一个选项需要选项值却没给,且optstring前端有冒号,则getopts将解析出’:’,OPTARG表该选项的选项名! 如果未识别该选项,则getopts将解析出?
,$OPTARG表该选项的选项名!
getopts optstring parameter
if [ $# -lt 1 ]; then
echo "there is no option";
else
while getopts ":Iti:s:v" opt; do
case $opt in
I) echo "option is I ";;
t) echo "option is t ";;
i) echo "option is i,the value is $OPTARG";;
s) echo "option is s,the value is $OPTARG";;
v) echo "option is v\n";;
:) echo "Error: '-$OPTARG' requires an argument";;
?) echo "Error: '-$OPTARG' not supported!";;
esac
done
fi
select
将in后的列表列成一个表单,提示用户选择
用户选择后,var便具有值,并执行statements
select option in "Display disk space" "Display memory usage"; do
case $option in
"Display disk space") diskspace;;
"Display memory usage") memoryusage;;
*) clear
esac
done
dialog
其输出一般使用退出码$?或STDERR; dialog [--option] --widget parameter
# --default-item string: 指定一些选单控件的默认选项
# --insecure: 在passwordbox控件键入时显示星号.
# --tab-len n: 指定一个tab占用的空格数,默认是8.
# --output-fd fd: 指定输出,而不是STDERR.
# --title title: 指定对话框的文本!
# widgets: calendar checklist form fselect gauge infobox inputbox inputmenu menu msgbox pause passwordbox passwordform radiobox tailbox tailboxbg textbox timebox yesno
# menu :20x10维度,窗口中显示8个item.选定菜单的文本会被发送到STDERR.
dialog --menu "title msg" 10 20 8 1 "first-item" "" 2 "second-item" 2>select.txt
# msgbox :最下方只有1个OK按钮,上方就是一个Edit.如果要显示文件的内容应使用textbox.
dialog --msgbox hello 10 20 #height,width
dialog --yesno "hello world" 10 20 #--defaultno可以将默认答案设为no
# textbox :与msgbox一样,只有1个Exit按钮,上方就是一个大的RichEdit.
dialog --textbox /etc/passwd 10 20
# inputbox :提示文本的下方会出现输入框
dialog --inputbox "Enter your age:" 10 20 2>age.txt
# filedialog :文件选择对话框,一次只能选定1个.
dialog --fselect $HOME/ 10 20 2>file.txt
tr
translate or delete characters
用来去除或替换重复的字符,相当于sed的y命令!
- 注意: 并不是字符串整体替换而是单个字符一一对应替换!
- 如果set1个数多,则将多出的字符全部替换为set2最后一个字符!
tr [a-z] [A-Z]
: 将每个字符大写.[0-9]
表数字.[a*2]
: 表匹配aa字符串
-d
: 删除出现在序列中的每一个字符!如删除文件中所有出现h,e,l,o的字符: -d "hello"
-s
: 替换出现在source字符序列中的每一个字符为replace中对应的字符.source中多出的则均映射到replace中最后一个字符! 注意如果某个字符重复出现则只替换成1个!如删除多余的空行: sed -s "\n" <file
-t
: 与-s
类似,但source中多出的字符会被忽略!-c
: 将source之外的所有字符都替换为replace中对应的字符,source多出的则均映射到replace的最后一个字符.tr [options] source replace < file
gnome
KDE
提供了Kdialog
包,gnome
提供了Gdialog
与zenity
.- 它们会将结果返回到STDOUT中,如calendar选择的日期、file-selection选择的路径…
zenity --wiget --option1 optval --option2 optval
# --file-selection: 文件或路径选择对话框
# --notification: 通知图标
# --text-info: 含有文本的文本框.
# --question: yesno对话框
# --progress: 进度条对话框
# --calendar: 日历
# --scale: 显示可调大小的窗口
# --entry: 文本输入对话框
# --error: 错误对话框
# --list: 列表对话框
zenity --info --title 'title' --text 'content'