[TOC]
变量
-
显示变量
echo $PATH echo $variable echo ${HOME}
-
设置变量,注意单引双引的区别
name=luca name="luca use $LANG" name=luca\ use\ $LANG #使用\转义空格 version=$(uname -r) version=`uname -r` PATH=${PATH}":/home/bin" name=${name}ly
-
如果变量需要在子进程使用,需要export来使变量变成环境变量
export PATH
-
查看当前shell环境中的环境变量
env export
-
查看环境变量和自定义变量的所有变量
set
-
$本身是个变量,代表当前shell线程代号,echo $$
-
$?代表上个执行命令的回传码,exit 0 #脚本返回0为成功
-
declare来实现更改变量类型、属性等
declare -i sum=1+2+3 #将变量定义为整数,不申明会当做字符串输出 sum=$((1+2+3)) #这样也能计算 sum=$[1+2+3] #这样也能计算 declare -a ary #将ary定义为数组类型 declare -x sum #将sum定义为环境变量 declare +x sum #将sum从环境变量移除 declare -r sum #将sum定义为只读 delcare -p sum #列出sum的类型
-
变量内容的替换和删除
删除
${variable#a*b} variable代表变量不加$,#代表从前面开始删,且去最少匹配,*为0到多个匹配,ab代表从a字符删到b字符,包括ab在内都删 ${variable##a*b} ##代表按最多的删 ${variable%a*b} %代表从后面开始删,ab的次序和变量中的次序不变,从a删到b ${variable%%a*b} %%表示按最多的删,删到最后用a*
替换
${variable/old/new} 在variable变量中,找到old替换成new,替换一个 ${variable//old/new} 替换所有
测试和替换
${variable-content} 如果variable被设置了,则不变,否则给variable变量设为值content ${variable:-content} 同上,但是若variable已设置但是为空也会被设置为值content ${variable+content} 当variable被设置了,则替换成值content,否则仍然为空 ${variable:+content} 同上,但是若variable已被设置但为空,仍然为空 var=${variable=content} 简单理解就是,当variable没被设置,var=variable,且都等于content;当variable已被设置,var=variable,且他们都等于variable原来的值 var=${variable:=content} 简单理解就是和上面一样,但是当variable虽然被设置了但是为空时,variable和var相等,且都被赋值为content var=${str?expr} 当str没被设置时,expr输出到stderr标准错误输出,否则var=str var=${str:?expr} 和上面一样,但是当str为空时也会输出到stderr
-
变量长度
len=${#variable}
-
变量作用范围
**全局环境变量:**对所有shell可见,使用env查看。系统环境变量一律使用大写来区别用户创建的环境变量。
**局部变量:**只对创建他的shell可见在某个shell进程中创建的局部变量,进程内可见。
脚本中定义的变量后面的函数可见
函数中定义的变量后面可见
函数中local var=1函数内可见
函数内外local且同名,互不影响
变量需要export才能被子进程看到,export PATH后,PATH则相当于$_GET,任何脚本都能直接得到。unset一个全局环境变量的时候,只会在当前shell进程中有效。
数组
-
设置数组
var[1]=one var[2]=two echo ${var[1]} #one echo $var
-
同时设置
var=(one two three four six) echo $var #one echo $var[2] #three echo ${var[*]} #one two three four six unset var[2] echo $var[2] # echo ${var[*]} #one two four six unset var echo ${var[*]} #
MISC
-
#! /usr/bin/bash
指明解释器的名称,这儿是bash,同理还能是#! /usr/bin/python,#! /bin/awk等
#!用来指明脚本交给哪个解释器执行
-
exit 0用来将程序中断,并回传一个数值给系统
-
bash a.sh在子进程中进行,等效于sh a.sh,或者直接调用脚本./script.sh
source a.sh在父进程中进行,等效于. a.sh -
bash启动的时候会默认处理如下文件
/etc/profile
$HOME/.bash_profile
$HOME/.bash_login
$HOME/.profile
第一个是bash一般都会执行的,后面三个是用户专有,可以定制。
.bash_profile会去执行.bashrc的内容,当是交互式shell的时候不会去访问/etc/profile,而是去访问这个文件
-
ps命令 ps命令有三种风格,第一种Unix风格带一个-,BSD风格不带-,GUN风格带全参数,比如–deselect
Unix风格主要记住几个参数
-e显示所有进程
-f显示完整格式
-H显示层级格式,能显示父进程
ps -efH
BSD风格主要记住
a和任意终端相关的所有进程
x显示所有进程,包括未分配终端的进程
u基于用户的格式显示
f按照分层格式显示进程
ps auxf
-
echo
echo -e “asas” #-e是为了转义,当其中出现的时候会使用转义来实现文字效果等
echo -n “test” #-n是清除结尾换行
-
find
find . -mtime -1 #查找当前目录下最后修改日期在一天内的文件或目录,-n是n天内,+n是n天以前
-
/dev/null 2>&1
1是默认标准输出,所以>/dev/null等同于1>/dev/null,&相当于等同于的意思,2>&1就是错误输出等同于1的处理的意思
判断符号和判断式
判断句子返回true或者false,用在任何需要判断是否的地方
-
test命令
test -e /file && echo "exist" || echo "Not exist"
判断文件
-e exist,文件是否存在 -f file,是否为文件 -d dir,是否为目录 -b block device,是否为一个block device设备 -c character device -S Socket文件 -p pipe,是否为一个FIFO(pipe)文件 -L link,是否为一个连接文件
判断文件权限
-r read,是否为可读 -w write,是否为可写 -x 是否可执行 -u SUID属性 -g SGID属性 -k 是否具有Sticky bit属性 -s 检测该文件是否存在且为非空白文件 -O ownership,检查运行脚本的是否为属主
判断两个文件 test file -nt file1
-nt newer than -ot older than -ef 是否为同一文件,hard link的判定上
两个整数间的比较 test n1 -eq n2
-eq equal,== -ne not equal,!= -gt greater than,> -lt less than,< -ge greater than or equal,>= -le less than or equal,<=
判断字符串
test -z string 判定字符串是否为0,若为空返回true,只要不是空都返回false test -n string 和上面相反,为空返回false,默认省略-n test str1=str2 判定两字符串是否相等,判断式中=和==等效。两个字符串都要用双引号括起来,免得变量中间有空格的情况出现出现错误 test str1!=str2 判定两字符串是否不等于
多重条件判定 test -r file -a -x file
-a 等效&& and -o 等效|| or ! 反向,test ! -x file
-
[]判断符号
格式:[ -z “$HOME” ],必须注意每个关键字左右都得有空格
[ -e ./file ] && echo "exist" || echo "Not exist"
其余语法和上面一致
结构化命令
-
if语法
if command then commands fi if command then commands else commands fi if command then commands elif command then commands fi
-
if-then高级性质
(( expression ))可用于判断计算数值计算后的true、false以及数值计算的赋值
if (( $val ** 2 > 90 )) then (( val2 = $val ** 2 )) fi
[[ expression ]]可用于字符串比较,除了标准的字符串比较嗨提供了模式匹配
if [[ $USER == r* ]] then echo "yes" else echo "no" fi
-
case语法
case variable in pattern1 | pattern2) commands1;; pattern3) commands2;; *) default commands;; esac
-
for命令,这儿的list可以是字符串(用空格分开或自定义分隔符),
cat file
,/home/*等for var in list do commands done
-
C风格for命令
for (( variable assignment; condition; iteration process )) do commands done
-
while命令
while test command do other commands done
-
until命令
-
break跳出循环,continue跳出本次循环
-
done后可以处理重定向,done>a.text
函数
-
定义,同名函数会覆盖上面的
function name { commands }
-
使用
name arg1 arg2
-
返回值
首先,默认情况下是由函数内最后一条命令返回作为回传码。
其次可以使用return返回一个整数值来定义退出状态码。退出码在0-255之间
还有一种方法能把字符串或者整数等输出给别的变量。这样会将值传给return,函数中所有echo都会传给return
function db1{ echo $[$1*2] } return=`db1`
-
参数
$0 函数名
$n 第n个参数
$# 参数个数
$@全部参数
这些定义和脚本运行的传参不同,虽然代表的意义一样
-
定义域
函数内外的变量都是全局的,任意修改影响全局。是很危险的。
所以一般建议函数内部的变量设置为局部变量,添加关键词
local temp
-
数组当做函数的参数
db1 ${var[*]}
-
函数返回数组
function db1{ var=(`echo $@`) echo ${var[*]} } ary=(a b c d e) arg=`echo ${ary[*]}` return=(`db1 $arg`)
-
递归
-
库函数使用source来被加载到新脚本中
../funcs