a. 使文件有可执行的权限,可以直接运行(./执行,没x,则提示权限不够)
b. 直接调用命令解释器执行程序
c. 使用source执行文件
第一行中声明: #!/bin/bash 或者 #!/usr/bin/python等解释器
一般父进程fork一个子进程,脚本在子进程中执行,不会影响父进程。
但是source (也叫点命令 .)执行的脚本,不会创建子进程,而直接在父进程中执行。
命名规范:以一个字母或下划线开头,后面可以跟任意长字母,数字和下划线。
如:count=0 等号两边不能有空格。
调用时:在名称前加$符, echo $count, 更规范的是: ${count}
a.环境变量(全局变量):可以在创建他的的shell中以及fork出来的子进程中使用。如:PATH
b.局部变量: 只能在父进程fork出来的进程中使用。
profile类文件作用:/etc/profile , /etc/profile.d/*.sh (常用) ,~/.bash_profile
a. 定义环境变量
b. 运行命令和脚本
bashrc类文件作用: /etc/bashrc , ~/.bashrc
a. 定义本地变量,函数
b. 命令别名
加载顺序:
登陆式: /etc/profile > ~/.bash_profile > ~/.bah_login > ~/.profile > ~/.bash_logout
非登陆式shell配置加载顺序: /etc/bash.bashrc > ~/.bashrc
var=1
单引号中的变量不能被解释,' v a r ′ 就 是 var'就是 var′就是var字符串
双引号: "$var"解释为1
如果没有初始化变量,值为Null,打印出来为空,类似js中"",可以做加减运算,等于0
但是可能不可移植。
即便在函数中的变量,如果没有local关键字,那么变量也是全局的。
export变量只能影响这个脚本所在的子进程,需要使用source来改变父进程
export的变量只能影响当前登录操作,当连接关闭后,变量失效。
所以需要把声明的变量写到配置文件(登入和登出文件)中:
a./etc/profile (常用)
b./etc/bashrc
c. H O M E / . b a s h p r o f i l e d . HOME/.bash_profile d. HOME/.bashprofiled.HOME/.bashrc
e.$HOME/.bash_logout
-i:清空父级的继承过来的环境变量。
删除函数时,需要 -f
export 变量
export 变量=value
declare -x 变量=value
(()) 整数运算.也可以进行与或非和比较运算
let 类似(())
bc linux下计算器
awk 整数和小数
在while和if语句中常使用条件表达式进行语句控制
a. test <测试表达式>
b. [<测试表达式>] 可以使用 -a -o -gt -lt等,不能使用&&,<,|等
c. [[<测试表达式>]] 可以使用&&,||,<
d. ((<测试表达式>))
在[]和test (())和[[]]
-eq ==或=
-ne !=
-gt >
-ge >=
-lt <
-le <=
test和[]中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较
在[]和test (())和[[]]
-a &&
-o ||
! !
a. nowTime=date +%F
#反引号的形式
b. nowTime=$(date +%F) #小括号计算的形式
[ -f $file_var ] :如果给定的变量包含正常的文件路径或文件名,则返回真。
[ -x $var ] :如果给定的变量包含的文件可执行,则返回真。
[ -d $var ] :如果给定的变量包含的是目录,则返回真。
[ -e $var ] :如果给定的变量包含的文件存在,则返回真。
[ -c $var ] :如果给定的变量包含的是一个字符设备文件的路径,则返回真。
[ -b $var ] :如果给定的变量包含的是一个块设备文件的路径,则返回真。
[ -w $var ] :如果给定的变量包含的文件可写,则返回真。
[ -r $var ] :如果给定的变量包含的文件可读,则返回真。
[ -L $var ] :如果给定的变量包含的是一个符号链接,则返回真。
如执行脚本:sh test.sh a b c
脚本中:$#表示参数个数,上面是3个
$@表示所有参数内容,a b c (常用)
如果参数中包含空格,使用双引号,或单引号(两个区别同变量时区别一样)
sh test “my name is joker”
除此之外还有如下:
0,1,2,...: 0表示程序名,1表示第一个参数,以此类推,如果大于10 ,则使用 ${10}
* :以一个单字符串显示所有参数,可以超过9个参数
$: 当前进程ID
!:后台运行的最后一个进程的ID号
?:显示最后命令的退出状态,0表示没有后错误,其他任何值都表明有错误。
常见的状态值含义:
0 :表示运行成功
2 :权限拒绝
1-125: 命令或者参数传递错误
126: 找到命令,但是无法执行
127: 未找到命令
128之后: 命令被系统强制结束
-:显示shell使用的当前选项,与set命令功能一样。
a.stdin: 代码为0 ,使用<或<<
b.stdout:代码为1,使用>或>>
c.stderr:代码为2,使用2>或2>>
如: find /home -name .bashrc >right_msg 2>error_msg
黑洞: /dev/null
常见的将错误和标准都输入一个文件中:
list_doc 2>&1
或 &>list_doc
标准输入:
a.
cat > newfile < oldfile
b.
cat > newfile << “eof”
this is a test
ok new stop
eof
cat file | grep ‘test’
~ `(反引号) # $ & * ( [ ] ) {} ; ’ " < > \ ? !
a=1
a+=1
echo $a;结果为11,字符串拼接。
${varname:-word} , ${varname:=word}, v a r n a m e : ? m e s s a g e , {varname:?message}, varname:?message,{varname:+word}
${varname#pattern} 删去匹配最短的
${varname##pattern}删除最长的匹配
${varname%pattern} 从右侧开始匹配,删除最短的匹配
${varname%%pattern} 从右侧开始匹配,删除最长的匹配。
${varname/pattern/string}
type ls , type cat … 显示命令是内建命令还是外部命令,还是aliase
count=“1234g”
echo ${#count}
function funName()
{
代码块
}
或者:
funName()
{
}
function关键字的函数,可以省略(),但是不建议
花括号必须在函数名下面。
函数调用时,fun 1 2 使用类似命令
通过$@或$1, 2... 等 获 取 传 递 给 函 数 的 参 数 通 过 r e t u r n 返 回 一 个 值 , 这 个 值 通 过 2...等获取传递给函数的参数 通过return 返回一个值,这个值通过 2...等获取传递给函数的参数通过return返回一个值,这个值通过?获取。
有个注意点就是: 在脚本里面定义的变量(只要不是在函数中添加local定义的),那么函数中是可见的。
还有: $1,$2这些脚本的外部传递进来的参数是对于函数是不可见的。所有必须函数传参方式。
if condition
then
statement
[elif condition
then statement]
[else
statement]
fi
if语句使用test进行内容测试
if test "2>3"等同 if [ “2>3” ],中括号里面前后都需要有空格。
if语句可以使用如下代替:
[条件1] && {
命令1
命令2
。。。
}
! && ||
[ -f “ f i l e n a m e " ] [ ! − f " filename" ] [ ! -f " filename"][!−f"filename” ]
类型检查:
-b(块设备)
-c(字符设备)
-d(目录)
-f(一般文件)
-h 、-L(符号链接)
-p 管道文件
-S (大写,套接字文件)
其他检查:
-e 文件是否存在
-g 是否设置了setgid
-u setuid
-r 是否可读
-w 可写
-x可执行
-s 内容非空
-O 大写,是否是文件拥有者
-G 文件的Gid匹配你的id
file1 -nt file2 文件1是否比文件2新 new then
file1 -ot file2 文件1是否比文件2旧 old then
case expression in
pattern1)
statement;;
pattern2)
statement;;
pattern3 | pattern4)
statement;;
*)
statement;; 类似default
esac
任何pattern之间都可以使用管道进行分割处理。
for n in list
do
…
done
如果in list 被省略,那么默认是 in “$@”
for name
do
case $name in
f) …
d) …
esac
done
常见迭代:
a){a…z}, {1…50}等
for i in {a…z}
do
echo $i
done
b.)seq
for i in $(seq 1 6);do echo $i;done
c.) c语言形式
for((i=0;i<20;i++)) {
echo $i
}
while condition
do
statement
done
类似的:
until condition
do
statement
done
-n “字符串” :若字符串长度>0,true;反之false,理解成not zero
-z “字符串” :若字符串长度为0, true;反之false (用这个)
“字符串1” = “字符串2” :判断是是否相同,可以使用==替代
“字符串1” != “字符串2”
^ 开头锚定
$ 结尾锚定
. 任意一个字符
* 匹配0到任意多个先前字符
[] 方括号中的字符匹配任意一个
\ 转移元字符
上面的都是支持egrep和grep
\(\) 类似js的组,如'\(app\).*\1'匹配两个app之间的任意数目字符。g
\n 重复再\(和\)内的第n个模式,n为1-9 .g
x\{m,n\} 匹配x字符m-n次 g
x{m,n} 同上 eg
+ 匹配前一个表达式最少一次 eg
? 匹配前一个表达式0-1次 eg
| 匹配 | 前面或后面的正则表达式 eg
() 匹配括号括起来的正则表达式群 eg
grep支持的附加
\< 匹配指定单词开头的行
\> 匹配指定单词结尾的行
\w 字母和数字
\b 单词分界符
arr=(v1 v2 v3)
echo ${arr[*]} 所有元素 或使用@
arr=([1]=a [2]=b [3]=c)
arr[1]=aa
arr=($(命令))
arr=(命令
)
echo $(#arr[@])
v=(1 2 3);v[9]=9;echo ${!v[*]}
必须声明: declare -A arr
其他使用同上
arr=([apple]=12 [banana]=23)
echo ${!arr[*]}
cat /proc/$PID/environ #这里pid是一个整数
也有些程序是有多进程的,也就是多个pid
cat testfile |tr a-z A-Z
\0此字符也作为string 的结束符。
cat /proc/12501/environ | tr ‘\0’ ‘\n’
chars=$(seq -s " " 100 )
a. echo ${#chars}
b. echo ( e x p r l e n g t h " (expr length " (exprlength"chars")
c. echo ${chars} | wc -m #该结果会变上面多一,它包含了字符串结束符(\0)
a.计算某条命令或某个脚本执行时间
time 命令
b.计算shell脚本中某个函数执行时间,可以使用前后时间差统计。
start= ( d a t e − − d a t e = " (date --date=" (date−−date="s" +%s)
配合%N能计算纳秒,当然也可计算毫秒了
date +%s.%N
配合bc计算器:
result=$(printf “%.2f” $(echo “scale=2;1.23-1.11”|bc)) #scale是小数位数,printf保证前置零不丢失。
a. (())常用,但是只能计算整数
常见的一些运算符都可以在其中使用
v=4;((v++));echo $v; #结果5
((v=1*5+2));echo $v; #结果为7
b. let 赋值表达式,效率没有双括号高
i=2;let i=i+8 ;echo $i ;#结果为10
c. expr:除了数值计算,它内部提供了一些函数
expr 2 * 2 ;特殊字符需要转义。
expr 2 + 2
d. bc计算器 ,可以指定小数位数。
v=1;echo v + 1.2 ∣ b c ; 2.1 ; r e s u l t = v+1.2 |bc ; 2.1; result= v+1.2∣bc;2.1;result=(printf “%.2f” $(echo “scale=2;1.23-1.11”|bc))
e. [ ] v = 1 ; a = 2 ; r e s u l t = [] v=1;a=2;result= []v=1;a=2;result=[ v+a ]
[ ] 里 面 也 可 使 用 []里面也可使用 []里面也可使用, v=1;a=3;result=$[ $v+a ]
-p: prompt设置提示信息b
-t: timeout 设置输入的等待时间
-s: 静默模式,不会回显
-a 后跟一个变量,该变量会被认为是个数组,然后给其赋值,默认是以空格为分割符
read -t 3 -p “请输入两个数:” v1 v2
date -s “2019-06-28 09:00:00” #设置系统时间,shell登出退出后仍能起作用。
/etc/security/limits.conf 中nproc来限制可生产的最大进程数
echo ( c a t 1. t x t ) 不 会 保 留 换 行 符 需 要 : e c h o " (cat 1.txt)不会保留换行符 需要: echo " (cat1.txt)不会保留换行符需要:echo"(cat 1.txt)"
没有任何效果,什么都不做。类似python中的pass,永远成功,退出状态0
所以常用他来替代true,资源利用率比true好。
repeat() {
while :
do
echo 1
sleep 2
done
}
#!/bin/bash
data=“name,gender,age,location”
oldIFS=$IFS
IFS=,
for item in $data
do
echo item: i t e m d o n e I F S = item done IFS= itemdoneIFS=oldIFS
输出:
item: name
item: gender
item: age
item: location
a.)单文件
cat filename
b.) 多文件
cat file1 file2
c.) 管道
echo 1 | cat
而且还可以合并文件和标准输出
echo “test” | cat - file.txt
-s:去掉多余空白行(tr命令也可以)
-T:将制表符显示为 ^I
-n:显示行号,配合-b可以跳过空白行,行号不会重排。
a) -name:指定文件名的形式 , -iname忽略大小写。
find / -name ".js" -print
b) -a -and , -o -or ,可以使用逻辑操作
find / (-name '.js’ -o -name ‘*.html’ ) -print
c) -path限制所匹配文件的路径
find / -path ‘/web/’ -name ‘*.html’ -print; 这样路径中必须包含/web/了
d) -regex ,-iregex使用正则表达式 (2.4.31)
e)排除模式: !
find / !-name “*.txt” 匹配以非txt结尾的。
f) -maxdepth , -mindepth指定目录深度
他们应该及早出现在find命令中出现,如果作为靠后的选项可能会影响find的效率。
g) 根据文件类型
find / -type d
常见的:f , l , d,c,b,s,p(FIFO)
h)重要的,按照文件的时间进行搜索
atime: access time,用户最近一次访问文件时间
mtime: modify time ,用户最近一次修改文件内容时间
ctime: change time , 文件元数据(如权限和所有权变更)最后一次变化时间
+表示大于,-表示小于。
find . -maxdepth 1 -type f -atime -1 ;访问时间小于一天的(一天之内),
find . -maxdepth 1 -type f -atime +1 ;一天前访问过的。
同时find命令还支持以分钟为计时单位,
-amin: 访问时间
-mmin: 修改时间
-cmin: 改变时间
和上面三个对应,只不过计时单位不同。
i) 基于文件大小的搜索
find . -type f -size +2k #大于2k
find . -type f -size -2k #小于2k
find . -type f -size 2k #等于2k的文件
还有其他单位:
b: 512字节,块
c: 字节
w: 字,2个字节
k: 千字节
M: 1024k
G: 1024M
o) 基于文件权限和所有权的匹配
find . -type f -perm 644; 权限是644的
同时可以设置反向过滤
find . -type f ! -perm 644; 权限不是644的
同时还有-user,-group等指定用户组,用户的。
p) 删除文件,find查找到文件,还可以删除
find . -type f -name “*.swp” -delete;他会删除匹配到的文件。
q) 匹配的文件可以执行其他命令
find . -type f -name “*.sh” -exec chown 755 {} ;
后面的{} ;是固定格式。;是命令结束的意思,\做转义。
find命令会将{}替换成相应的文件名。
-exec 后只能跟一条命令,所以为了实现多命令
可以吧命令写在脚本中, 然后: -exec ./youscript.sh {} ;
r) 让find跳过特定的目录或文件:在截取的时候,-print不能忽略,否则结果可能不正确。
find . -name ‘.git’ -prune -o -type f -print;忽略.git目录
find /root/myscripts -name ‘1.txt’ -prune -o -name “1*” -print
将从sdtin中读取的数据作为指定命令的参数并执行。
a.)多行可以转一行
cat 1.txt | xargs
b.)多行转指定行
cat 1.txt | xargs -n 3
c.)切割
echo “splitXsplitXsplitXsplitX” | xargs -d X
split split split split
tr [options] set1 set2
来自 stdin 的输入字符会按照位置从 set1 映射到 set2 ( set1 中的第一个字符映射到 set2
中的第一个字符,以此类推),然后将输出写入 stdout (标准输出)。 set1 和 set2 是字符类或字符组
echo ‘hello world’ | tr ‘a-z’ ‘A-Z’ ;结果HELLO WORLD
a)使用 -d删除字符
cat file | tr -d “0-9” ;从管道里面传进来的文本删除数字。
-q 不显示任何信息,只显示结果
-c 总次数,发几次包
-i 时间间隔
-W 大写的w,超时时间 秒。
ping -W 2 -c 3 -q www.baidu.com
while read line
do
{
command 1
} &
done
command 2
使用 {}&并发,使结果快多了,但是同时cpu在短时间也会飙升。
chkconfig 服务名 on
chkconfig mysqld on
在家目录下配置my.cnf文件里面填写password字段
给该文件chmod 400 权限。只有该用户有权限读。
表达式 说明
p a r a m e t e r 返 回 变 量 {parameter} 返回变量 parameter返回变量parameter的内容
KaTeX parse error: Expected '}', got '#' at position 2: {#̲parameter} …parameter内容的长度(按字符),也使用与特殊变量
p a r a m e t e r : o f f s e t 返 回 变 量 {parameter:offset} 返回变量 parameter:offset返回变量{parameter}中,从位置offset之后开始提取子串
${parameter:offset:length} 从offset开始,提取长度length的子串
${parameter#word} 从开始删除最短匹配的word子串
${parameter##word} 从开头开始删除最长匹配的word子串
${parameter%word} 从结尾开始删除最短匹配的word子串
${parameter%%word} 从结尾开始删除最长匹配的word子串
${parameter/pattern/string} 使用string代替第一个匹配的pattern
${parameter//pattern/string} 使用string代替所有匹配的pattern
${parameter:-word}
如果parameter变量值为空或未赋值,则返回word字符串作为返回值
${parameter:=word}
如果parameter的变量值为空或未赋值,则设置该变量值为word,并返回该值
${parameter:?word}
如果parameter的变量值为空或未赋值,那么word字符串将为作为标准错误输出,否则输出变量的值。
${parameter:+word}
如果parameter的变量值为空或未赋值,则什么都不做,否则word字符串将替代变量的值。