shell 学习笔记2
shell的常用处理:https://github.com/dylanaraps/pure-bash-bible
-d作为分隔符:read xargs
-t作为分隔符:sort
-F作为分隔符:awk
字符串替换:b=${a/123/321};将${a}里的第一个123替换为321
for循环: #!/usr/bin/env bash for((i=0;i<10;i++)) do echo $i done
全部: ls -a
递归:ls -R
通配符(过滤):ls *.sh
通配符:cp *.sh /home/tst
每个文件或目录都有唯一的inode编号 ,可以给ls命令加入-i参数 查看:ls -i sdf.sh
创建多级目录加-p参数:mkdir -p /tst/aa/bb/cc
用file可以查看文件的编码:
file DayStatistic.py DayStatistic.py: Python script, UTF-8 Unicode text executable
less命令是more的升级版本,支持更多的命令
显示倒数两行: tail -2 log_file
显示正数两行:head -2 log_file
========== top
S:进程的状态(D代表可中断的休眠状态, R代表在运行状态, S代表休眠状态, T代表跟踪状态或停止状态, Z代表僵化状态)
============
pkill 或 killall支持通过进程名而不是PID来结束进程。
mount命令会输出当前系统上挂载的设备列表
mount | head -2 sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel) proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) 媒体的设备文件名 挂载点 文件系统类型 媒体的访问状态
===============
sort -n :-n 告诉sort命令把数字识别成数字而不是字符,并且按值排序
/etc/passwd 内容如下: rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin cat /etc/passwd |sort -t ":" -k 3 -n # 参数来指定字段分隔符,然后用-k参数来指定排序的字段
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync
==============
执行多条命令,命令直接通过 &&连接,前一条命令执行成功,才会执行后面一条,如:cd /temp/log/&&rm -rf *
快速清空一个文件:>filename
复制粘贴:ctrl+insert shift+insert
冻结屏幕:ctrl + s
退出冻结:ctrl+q
在没有vim时,编辑一个空文件:cat >file.txt ,ctrl+d 退出编辑
=================
/etc/passwd 里保存了每个用户默认的shell程序,还保存了用户名和uid的对应关系;root的UID是0
passwd 用来修改密码,不加参数,则修改自己的,加了参数,则修改别人的,但只有root用户可以修改别人的
创建全局环境变量的方法是先创建一个局部环境变量,然后再把它导出到全局环境中;在unset命令中引用环境变量时,记住不要使用$
my_variable="I am Global now" export my_variable
unset my_variable
/etc/profile文件是bash shell默认的的主启动文件。只要你登录了Linux系统, bash就会执行/etc/profile启动文件中的命令
最好是在/etc/profile.d目录中创建一个以.sh结尾的文件。把所有新的或修改过的全局环境变量设置放在这个文件中
在大多数发行版中,存储个人用户永久性bash shell变量的地方是$HOME/.bashrc文件。
有时数组变量会让事情很麻烦,所以在shell脚本编程时并不常用。对其他shell而言,数组变量的可移植性并不好 。
将用户rich加入shared组 :usermod -G shared rich # 如果加了-g选项,指定的组名会替换掉该账户的默认组。 -G选项则将该组添加到用户的属组的列表里,不会影响默认组
==================
查看所有的用户:cat /etc/passwd
查看所有的用户组:cat /etc/group
改用户:chown rpc Dockerfile
改组:chown .centos Dockerfile
改用户和组:chown alauda.alauda Dockerfile
添加免密sudo (免密切换root)
vi /etc/sudoers
user31 ALL=(ALL) NOPASSWD:ALL
==============vim中的操作
G:移到缓冲区的最后一行
num G:移动到缓冲区中的第num行
gg:移到缓冲区的第一行
s/old/new/g:一行命令替换所有old
%s/old/new/g:替换整个文件中的所有old
%s/old/new/gc:替换整个文件中的所有old,但在每次替换时进行确认
===========
赋予文件属主执行文件的权限:chmod u+x test1 # a+x 是给大家都加上执行权限
使用等号将值赋给用户变量。在变量、等号和值之间不能出现空格。
有两种方法可以将命令输出赋给变量: 反引号字符(`) $()格式 例如:tst=`ls -a` aa=$(ls -a)
==============
文件重定向用 <
内联输入重定向:这种方法无需使用文件进行重定向,只需要在命令行中指定用于输入重定向的数据就可以了 。内联输入重定向符号是远小于号(<<)。
除了这个符号,你必须指定一个文本标记来划分输入数据的开始和结尾,常用EOF
wc << EOF > NICE EOF --这里的EOF么用,要单独一行的EOF才管用 > EOF 1 2 9
================
不要以为由管道串起的两个命令会依次执行。 Linux系统实际上会同时运行这两个命令,在系统内部将它们连接起来。在第一个命令产生输出的同时,输出会被立即送给第二个命令。数据传输不会用到任何中间文件或缓冲区
=============== bash shell只能处理整数 ,不能处理浮点型
通过上下键查看大文件:cat /etc/group | less
在bash中,在将一个数学运算结果赋给某个变量时,可以用美元符和方括号($[ operation ])将数学表达式围起来 :var1=$[1 + 5]
进行浮点数计算 bc :variable=$(echo "options; expression" | bc)
var1=$(echo "scale=4;3.51/4" | bc) --scale 指明保留几位小数 echo $var1 .8775
===================
可以通过exit 在适当的位置退出,但要注意,返回值范围是0~255
字符串进行比较时,为了不把> 或< 当作重定向使用,需要进行转义,或者改用双括号,双括号里不用转义,双括号里可以使用高级的数学运算
双方括号支持正则匹配
myfun() { item="sdf1" var="sdf2" if [ $item \> $var ] then echo "have" else echo "not have" fi }
myfun() { item="sdf1" var="sdf2" if (( $item > $var )) then echo "have" else echo "not have" fi }
=================
==============
while命令允许你在while语句行定义多个测试命令。只有最后一个测试命令的退出状态码会被用来决定什么时候结束循环 。若最后一个命令放的不对,可能造成死循环
myfun() { var1=3 while echo $var1 [ $var1 -gt 0 ] do var1=$[ $var1 -1] done }
until命令要求你指定一个通常返回非零退出状态码的测试命令。只有测试命令的退出状态码不为0, bash shell才会执行循环中列出的命令。
myfun() { var1=3 until [ $var1 -eq 0 ] do echo $var1 var1=$[ $var1 -1] done }
==============
break n 跳出循环:默认情况下, n为1,表明跳出的是当前的循环。如果你将n设为2, break命令就会停止下一级的外部循环 【外部循环跳出了,当然内部循环也就结束了】
var1=0 while [ $var1 -lt 3 ] do var1=$[ $var1+1 ] echo "var1:" $var1 for (( a=0;a<2;a++ )) do echo $a if [ $a -eq 1 ] then break 2 fi done done
结果:
var1: 1
0
1
continue 后面也支持加 n
=========================
done 后面可以加重定向,也可加管道符
var1=0 while [ $var1 -lt 3 ] do var1=$[ $var1+1 ] echo "var1:" $var1 done > cc.txt 结果: cat cc.txt var1: 1 var1: 2 var1: 3
for var1 in /home/alauda/temp/* do echo "var1:" $var1 done | sort
====================
向脚本传参数时,每个参数用空格分开
$0是程序名, $1是第一个参数, $2是第二个参数,依次类推,直到第九个参数$9。 如果脚本需要的命令行参数不止9个, 必须在变量数字周围加上花括号,比如${10}
basename命令会返回不包含路径的脚本名
var1=` basename $0 ` echo $var1
判断参数是否存在 -n
if [ -n "$2" ] --要引起来,否则不对 then echo "exists" else echo "not exists" fi
获取最后一个元素:echo ${!#}
$#:传入脚本的参数个数
=========
$*变量会将所有参数当成单个参数,而$@变量会单独处理每个参数
=============
read命令包含了-p选项,允许你直接在read命令行指定提示符。 -t 指定了read命令等待输入的秒数
if read -p "your name :" name then echo $name else echo "too slow" fi
也可以在read命令行中不指定变量。如果是这样, read命令会将它收到的任何数据都放进特殊环境变量REPLY中
read -t 3 -p "your name :" echo "name :"$REPLY
=======================
默认情况下, STDERR文件描述符会和STDOUT文件描述符指向同样的地方(尽管分配给它们
的文件描述符值不同)。也就是说,默认情况下,错误消息也会输出到显示器输出中
============
重定向错误输出:ls zz tst 2>error
将正常输出和错误输出重定向到不同的文件:ls zz tst 1>info 2>error
正常输出和错误输出重定向到一个文件:ls zz tst &> info 【当使用&>符时,命令生成的所有输出都会发送到同一位置,包括数据和错误 】
阻止命令输出:ls > /dev/null
将输出同时发送到显示器和日志文件 :tee 【它将从STDIN过来的数据同时发往两处。一处是STDOUT,另一处是tee命令行所指定的文件名】
date | tee testfile
=============
以后台模式运行shell脚本非常简单。只要在命令后加个&符就行了。 命令作为系统中的一个独立的后台进程运行 :./test1.sh &
退出终端后,后台进程仍运行:nohup ./test1.sh &
=====================
函数的定义要在 函数调用之前
若函数最后一行执行成功,则函数返回值是0,即使函数中前面几句话执行失败
$#来判断传给脚本或函数的参数数目。
===========
函数可以访问脚本中定义的全局变量,但不能访问 $1 $2
============
lst=( 1 2 3 44 55) echo $lst -----lst是一个数组,要想获取数组全部元素需要用${lst[*]},$lst只能获取第一个元素
echo ${lst[*]}
=================
要在sed命令行上执行多个命令时,只要用-e选项就可以了 ,多个命令之间用分号分隔
sed -e 's/brown/green/; s/dog/cat/' data1.txt
sed -ie 's/aaa/111/g;s/bbb/333/g' bb
====================
gawk程序脚本用一对花括号来定义 ;由于gawk命令行假定脚本是单个文本字符串,你还必须将脚本放到单引号中
$0代表整个文本行;
$1代表文本行中的第1个数据字段;
$2代表文本行中的第2个数据字段;
$n代表文本行中的第n个数据字段
gawk中执行多条命令,只要在命令之间放个分号即可 :echo "My name is Rich" | gawk '{$4="Christine"; print $0}'
==================
EOF(End-of-File)
==============
xargs 能够将输入数据转化为特定命令的命令行参数
-I {} 指定替换字符串,这个字符串在xargs扩展时会被替换掉,用于待执行的命令需要多个参数时
将进程的IO情况记入文件
iotop -d 60 -toP > /home/ubuntu/zcy/iotop.log
sort:-n 按数字进行排序 VS -d 按字典序进行排序
消除重复行
sort unsort.txt| uniq
统计各行在文件中出现的次数
sort unsort.txt | uniq -c
找出重复行
sort unsort.txt | uniq -d
统计行数:wc -l file
统计单词数 wc -w file
统计字符数wc -c file
awk脚本结构:
awk ' BEGIN{ statements } statements2 END{ statements } '
1.执行begin中语句块;
2.从文件或stdin中读入一行,然后执行statements2,重复这个过程,直到文件全部被读取完毕;
3.执行end语句块;
echo -e "line1 line2" | awk 'BEGIN{print "start"} {print } END{ print "End" }' #使用不带参数的print时,会打印当前行