#!/bin/bash
##! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。 /bin/php74
# /bin/php test.php 这样不需要在第一行指定解释器信息
#1. 变量定义
myVariable() {
#1. 变量定义
#=前后不能有空格
#定义变量时,变量名不加美元符号($,PHP语言中变量需要)
#使用一个定义过的变量,只要在变量名前面加美元符号即可,加花括号是为了帮助解释器识别变量的边界 echo "I am good at ${skill}Script"
name="name1"
#name
echo name
# 使用美元 ($) 符号
echo $name
# 使用美元 ($) 符号和括号结合,常用于字符串拼接 name1
echo ${name}
# 默认值:如果变量没有声明,使用默认值 ${var=DEFAULT} name1
echo ${name="ok"}
# 默认值:如果变量没有声明,或者为空字符串,使用默认值 ${var:=DEFAULT} ok
name=""
echo ${name:="ok"}
#只读变量
myUrl="https://www.google.com"
readonly myUrl
#删除变量 unset 命令不能删除只读变量
unset variable_name
}
#2. 数值运算 算术运算符
myNumber() {
echo '数值运算'
#2. 数值运算
#Shell 中的数字运算可以采用 $((num1 + num2)) 的方式
#值运算的两个变量必须是 数字 或者 数字字符串, 不然会报错
#Shell 中的变量默认是字符串,使用 result=1+2;echo $result , 输出会是 1+2
a=11
b="3"
#符号前后有空格
echo $(($a + $b))
echo $(($a - $b))
echo $(($a * $b))
#取整 3
echo $(($a / $b))
echo $(($a % $b))
#乘方11^3
echo $(($a ** $b))
echo $(($a + ($a * $b)))
echo 'bash'
#bash
#原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
#expr命令是一个手工命令行计数器,用于在UNIX/LINUX下求表达式变量的值,一般用于整数值,也可用于字符串。
#expr 表达式
#用空格隔开每个项;
#用反斜杠 \ 放在 shell 特定的字符前面;
#对包含空格和其他特殊字符的字符串要用引号括起来
#val=`expr length “this is a test”`
#expr substr “this is a test” 3 5
#expr index "sarasara" a # 2
#expr 14 % 9 expr 10 + 10 expr 30 / 3 / 2 expr 30 \* 3
echo `expr $a + $b`
echo `expr $a - $b`
echo `expr $a \* $b`
echo `expr $a / $b`
echo `expr $a % $b`
echo `expr $a == $b` #0
echo `expr $a != $b` #1
}
#3. 字符串
myString() {
echo '字符串'
#3. 字符串
#字符串可以用单引号,也可以用双引号,也可以不用引号。单双引号的区别跟PHP类似
#Shell 的字符串与 PHP 的字符串相同,分为 单引号字符串 和 双引号字符串
name="hello ok"
#单引号中变量和符号不会被解析
#单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
#引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用
#双引号里可以有变量
#双引号里可以出现转义字符
echo 'my name is ${name}'
echo "my name is ${name}"
#字符串连接
echo $name $name$name
#字符串长度
echo ${#name}
#字符串截取
#substr
#llo ok
echo ${name:2}
#llo o
echo ${name:2:5}
#字符串删除
#${变量名#substring 正则表达式} 从字符串 开头 开始配备 substring, 删除匹配上的表达式。
#${变量名 %substring 正则表达式} 从字符串 结尾 开始配备 substring, 删除匹配上的表达式。
test="/home/work/.vimrc"
#/work/.vimrc
echo ${test#/home}
#/home/work
echo ${test%/.vimrc}
# 快速获取文件名 .vimrc
echo ${test##*/}
# 快速获取路径 /home/work
echo ${test%/*}
#字符串替换
#使用内置的字符串替换,会比 awk, sed, expr 的性能更好,
#${变量 / 查找 / 替换值} 一个"/"表示替换第一个,"//"表示替换所有。
test="/home/work/.vimrc"
echo ${test/.vimrc/.zshrc}
# output: /home/work/.zshrc
echo ${test/w*k/cizel}
# output: /home/cizel/.vimrc
#查找子字符串 哪个字母先出现就计算哪个
echo `expr index "$test" vc` # 13
}
#4. Shell 逻辑运算 关系运算符
myLogic() {
echo 'Shell 逻辑运算'
#Shell 逻辑运算
#逻辑判断结果真返回 0, 假返回 1
#使用 -gt, -lt, -ge, -le, -ne, -eq 替换 >, <, >=, <=, !=, = 做数值比较
#与或非运算符使用 -a, -o, ! 替换 & | !
#数值比较 -gt -lt -ge -le -ne -eq
test 3 -gt 2; echo $?
test 3 -lt 2; echo $?
#字符串比较 = != -z判断字符串长度是否为零 -n判断字符串长度是否大于零 $检测字符串是否为空,不为空返回 true [ $a ]
test "my name is cizel" = "my name is cizel"; echo $?
#文件比较 -e -d -f -L -r -w -x
test -e sh.sh; echo $?
#逻辑连接 -a -o !
test "1" = "1" -a "1" = "2"; echo $?
test ! "1" = "2"; echo $?
#逻辑运算符
# &&
# ||
}
#5. 结构 流程控制
myStruct() {
echo '结构'
#结构 支持 if, if-else, if-elif, if-elif-else, case-esac
#if 条件的左括号 ([) 后必须有一个空格,右括号前 (]) 必须有一个空格。if [空格expression空格]
#if, elif 后面都需要加 then 然后添加语句
#if
var=`uname -s`
if [ $var = "Linux" ]; then
echo "Linux System"
else
echo "Other System"
fi
#11
if [ "1" = "2" ]; then
echo "00"
else
echo "11"
fi
#00
if [ "1" = "1" ]; then
echo "00"
else
echo "11"
fi
#case
var=`uname -s`
case $var in
"Linux")
echo "Linux System"
;;
"FreeBSD")
echo "FreeBSD System"
;;
*)
echo "Other System"
;;
esac
echo "循环"
#for
for ((i=1; i<=10; i++)); do
echo "for"$i
done
#while 循环
count=1
while [ $count -lt 3 ]; do
echo "while"$count
count=$((count + 1))
done
#until 循环
#until1
#until2
count=1
until [ $count -eq 3 ]; do
echo "until"$count
count=$((count + 1))
done
}
#6. 数组
myArray() {
echo '数组'
#bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
#在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开
#array_name=(value0 value1 value2 value3)
#array_name[12]=12
array_name=(
12
131
1412
15123
1612345
)
#读取数组
#${数组名[下标]}
echo ${array_name[3]} #15123
#@ 符号可以获取数组中的所有元素 echo ${array_name[@]}
echo ${array_name[@]} #12 131 1412 15123 1612345
#获取数组的长度 ${#array_name[@]} ${#array_name[*]}
#取得数组单个元素的长度 ${#array_name[n]}
echo ${#array_name[@]} #5
echo ${#array_name[*]} #5
echo ${#array_name[4]} #7
}
echo '函数'
#7. 函数
my_func() {
echo "my function"
echo "params 1: $1"
echo "params 2: $2"
echo "params 3: $3"
#Shell 传递参数
#在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
#./test.sh 1 2 3
#还有几个特殊字符用来处理参数:
echo '传递到脚本的参数个数$# '$#
echo '以一个单字符串显示所有向脚本传递的参数$* '$*
echo '脚本运行的当前进程ID号$$ '$$
echo '后台运行的最后一个进程的ID号$! '$!
#$@ $*只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)
echo '与$*相同,但是使用时加引号,并在引号中返回每个参数$@ '$@
echo '显示Shell使用的当前选项$- '$-
echo '显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误$? '$?
}
my_func 1 2 3
#8. Shell 加载脚本
#Shell 中使用 source 命令可以加载其他文件到当前 Shell 脚本中
source /root/shsource.sh
my_source 123 12 1
#9. echo
myEcho() {
#echo自动换行
echo 'echo显示变量'
#显示变量
read -p 输入字符 name #标准输入等待
echo "标准输入name $name" #输出
}
#10. printf命令
myPrintf() {
#printf不自动换行 手动添加 \n
#printf format-string [arguments...] 为格式控制字符串 参数列表
echo 'printf命令 printf format-string [arguments...]'
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876
}
#11. test命令
myTest() {
#用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
echo 'test命令'
}
#12. 输入/输出重定向
myLoad() {
echo '输入/输出重定向'
echo 'command > file 将输出重定向到 file。'
echo 'command < file 将输入重定向到 file。'
echo 'command >> file 将输出以追加的方式重定向到 file。'
echo 'n > file 将文件描述符为 n 的文件重定向到 file。'
echo 'n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。'
echo 'n >& m 将输出文件 m 和 n 合并。'
echo 'n <& m 将输入文件 m 和 n 合并。'
echo '<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。'
echo '需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。'
#输出重定向
ls > load.txt
ls -l >> load2.txt
#输入重定向
#ls < load.txt
#ls < load2.txt
#每个 Unix/Linux 命令运行时都会打开三个文件
#标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据
#标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据
#标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息
#command > file 2>&1 stdout 和 stderr 合并后重定向到 file
#command < file1 >file2 command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。
#/dev/null 文件 特殊的文件
#如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null
#command > /dev/null
#command > /dev/null 2>&1 屏蔽 stdout 和 stderr
}
myVariable
myNumber
myString
myLogic
myStruct
myArray
myEcho
myPrintf
myLoad
#vi ~/.bashrc
#source ~/.bashrc
#cdls(){
# if [ -n "$1" ]
# then
# if [ ! -d "$1" ]
# then
# echo '不是目录'
# else
# cd $1
# ls
# fi
# fi
#}
#alias cd='cdls'
#参考 https://www.jianshu.com/p/dfa7e06c0308