图片连接html
1.进入命令行,CLI(command line interface),也叫Linux控制台
- 经过Linux控制台终端访问CLI
- Ctrl+Alt+F1~F7
注:tty:teletypewriter,指一台用于发送消息的机器
控制台的外观设置命令:setterm2.经过图形化的终端访问CLI
1. bash手册
1.1 熟悉DESCRIPTION部分的前两段能够学到不少技术行话
1.2 空格键:翻页
1.3 回车键:逐行查看node2. Linux手册页的内容区域
- 1.可执行文件或shell命令
- 2.系统调用
- 3.库调用
- 4.特殊文件
- 5.文格式约定
- 6.游戏
- 7.概览、约定及杂项
- 8.超级用户和系统管理员命令
- 9.内核例程
- 查看所需的页面:man section# topic
- 查看内容简介:man 1 intro
- 另外一个参考信息:info info
3.Linux文件系统
3.1 常见的目录名称
- / :虚拟目录的根目录
- /bin :二进制目录,存放许多用户级的GNU工具
- /boot:启动目录,存放启动文件
- /dev :设备目录,Linux在这里建立设备节点
- /etc :系统配置文件目录
- /home:主目录,Linux在这里建立用户目录
- /lib :库目录,存放系统和应用程序的库文件
- /media:媒体目录,可移动媒体设备的经常使用挂载点
- /mnt :挂载目录,另外一个可移动媒体设备的经常使用挂载点
- /opt :可选目录,经常使用于存放第三方软件包和数据文件
- /proc:进程目录,存放现有硬件及当前进程的相关信息
- /root:root用户的主目录
- /sbin:系统二进制目录,存放许多GNU管理员级工具
- /run :运行目录,存放系统运做时的运行时数据
- /srv :服务目录,存放本地服务的相关文件
- /sys :系统目录,存放系统硬件信息的相关文件
- /tmp :临时目录,能够在该目录中建立和删除临时工做文件
- /usr :用户二进制目录,大量用户级的GNU工具和数据文件都存储在这里
- /var :可变目录,用以存放常常变化的文件,好比日志文件
3.2 文件和目录列表
- ls -F :区分文件和目录
- ls -a :显示隐藏目录
- ls -F -R :递归列出当前目录下包含的子目录中的文件
- ls -l :长列表格式输出,每行都包含了下述信息
文件类型,好比目录( d )、文件( - )、字符型文件( c )或块设备( b );
文件的权限(参见第6章);
文件的硬连接总数;
文件属主的用户名;
文件属组的组名;
文件的大小(以字节为单位);
文件的上次修改时间;
文件名或目录名;3.3 使用元字符通配符过滤文件
- ls -l scr[ai]pt :a或i
- ls -l f[a-i]ll :指定字符范围
- ls -l f[!a]ll :除了a
3.4 建立文件
- touch test_one :建立一个空文件,若是已经存在,则修改文件的建立时间
- touch -a test_one :改变文件建立时间
- ls -l –time=atime test_one :加粗文件建立时间
3.5 连接文件:指向文件真实位置的占位符
3.5.1 符号连接:指向虚拟结构目录中某个地方的另外一个文件,彼此内容不一样
- ln -s data_file s1_data_file :给data_file建立一个符号连接
- ls -l *data_file :查看该连接文件,能够看到大小不同
- ls -i *data_file :查看两个文件的inode节点编号,能够看到不同
3.5.2硬连接:会建立独立的虚拟文件,包含原始文件的信息和位置,本质上是同一个文件(必须在同一个媒体)
- ln code_file h1_code_file :建立一个硬连接
- ls -li *code_file :查看两个文件
3.6.删除文件
- rm -i fall :带提示的删除
- rm -f fall :强制删除
- rm -ri my_diir:删除目录中的文件,再删除目录自己
- rm -ri my_diir:递归删除目录中的文件,再删除目录自己
3.7 建立目录
- mkdir -p New_dir/Sub_dir/under_ir :同时建立多个目录及子目录用 -p参数
- tree New_dir :以树的形式查看目录结构
3.8 查看文件内容
- file my_file :查看文件或者目录类型
- cat -n test1 :显示文本文件数据,并加上行号
- cat -b test1 :只给有文本的加上行号
- cat -T test1 :不让制表符出现
- more test1 :显示文件内容,不过会在每一页后停下来
- less test1 :跟more差很少,可是更高级,支持方向键上下翻页
- tail -n 2 test1 :只显示最后两行的内容
- head -n 2 test1 :显示文件开头两行内容
1.监测程序
- ps :显示运行在当前控制台下的属于当前用户的进程
- ps -ef :显示全部进程的完整信息
其余参数- -A 显示全部进程
- -N 显示与指定参数不符的全部进程
- -a 显示除控制进程(session leader ① )和无终端进程外的全部进程
- -d 显示除控制进程外的全部进程
- -e 显示全部进程
- -C cmdlist 显示包含在 cmdlist 列表中的进程
- -G grplist 显示组ID在 grplist 列表中的进程
- -U userlist 显示属主的用户ID在 userlist 列表中的进程
- -g grplist 显示会话或组ID在 grplist 列表中的进程 ②
- -p pidlist 显示PID在 pidlist 列表中的进程
- -s sesslist 显示会话ID在 sesslist 列表中的进程
- -t ttylist 显示终端ID在 ttylist 列表中的进程
- -u userlist 显示有效用户ID在 userlist 列表中的进程
- -O format 显示默认的输出列以及 format 列表指定的特定列
- -o format 仅显示由 format 指定的列
- -n namelist 定义了 WCHAN 列显示的值
- -F 显示更多额外输出(相对 -f 参数而言)
- -M 显示进程的安全信息
- -c 显示进程的额外调度器信息
- -f 显示完整格式的输出
- -j 显示任务信息
- -l 显示长列表
F:内核分配给进程的系统标记
S:进程状态(O表示正在运行,S表示正在休眠,R表示可运行,正在等待运行,Z表示僵尸进程)- -y 不要显示进程标记(process flag,代表进程状态的标记)
- -Z 显示安全标签(security context) ① 信息
- -H 用层级格式来显示进程(树状,用来显示父进程)
- -w 采用宽输出模式,不限宽度显示
- -L 显示进程中的线程
- -V 显示 ps 命令的版本号
top :跟ps类似,不过它显示的是实时的
2.结束进程
- kill 3904 :给进程ID是3904的进程发送TERM(尽量终止)信号
- kill -s HUP 3940 :给进程ID是3904的进程发送HUP(挂起)信号
- killall http* :结束以http开头的进程
3.检测磁盘空间
- mount :列出当前系统上挂载的设备列表
- mount -t vfat /dev/sdb1 /media/disk :手动将U盘/dev/sdb1挂载到/media/disk目录下
- umount /home/rich/mnt :卸载设备
- df -h :查看全部已挂载设备的的磁盘使用状况,-h用易读的方式显示
- du /mnt/hgfs :查看特定目录下的磁盘使用状况,不加参数表示当前目录
4.处理数据文件
- sort -n file :排序file文件,并把数字识别成数字
- sort -M file3 :按月份(3个字母)排序,经常使用于日志文件
- sort -t ‘:’ -k 3 -n /etc/passwd :对密码文件根据用户ID排序,-t指定区分键位置字符,-k排序其实位置
- grep three file :在file中搜索three文本
- grep -v three filre :在file文件中反向搜索three文本,即不包含three的行
- grep -C three filre :在file文件中反向搜索three文本,只输出有多少个行含有匹配模式
- grep -n three filre :在file文件中反向搜索three文本,仅输出行号
- grep -e t -e f file :若是要指定多个模式,-e指定每一个模式
- grep [tf] file :使用正则表达式搜索包含字符t或者f的匹配
- gzip my* :经过通配符一次性批量压缩文件
- gzcat myprog.c.gz :查看压缩过的文本文件的内容
- gunzip myprog.c.gz :解压文件
- tar -cvf test.tar test/ test2/ :归档文件
- tar -tf test.tar :列出test.tar的内容
- tar -zxvf file.tgz :解压用gzip压缩过的文件
shell不仅仅是一种CLI,它是一个时刻都在运行的交互式程序linux
/bin/sh:用于那些在系统启动时使用的系统shell脚本
ps –forest:展现进程间的嵌套结构git5.1 可经过命令行参数修改shell的启动方式
- -c string 从 string 中读取命令并进行处理
- -i 启动一个可以接收用户输入的交互shell
- -l 以登陆shell的形式启动
- -r 启动一个受限shell,用户会被限制在默认目录中
- -s 从标准输入中读取命令
5.2 经常使用命令
- echo $BASH_SUBSHELL :查看子shell的个数
- sleep 10 :会话暂停10秒钟
- sleep 10& :sleep命令睡眠10秒钟放到后台运行
- jobs :显示当前运行在后台模式的全部用户进程(做业)
- coproc sleep 10 :在后天生成一个子shell,并把命令放到后台运行
- coproc My_job { sleep 10; } :给协程命名
5.3 理解shell的内建命令
5.3.1 外部命令:也叫文件系统命令,一般位于/bin、/usr/bin、/sbin或者/usr/sbin中
- which ps :用which命令找到外部ps命令
- type ps :跟上面同样
5.3.2内部命令:不须要使用子进程来执行,做为shell的组成部分存在
- type cd :查看cd是否是内部命令
- history :跟踪使用过的命令,保存在隐藏文件.bash_history中,位于用户主目录
!! :唤回并重用历史命令中最近的命令
history -a :强制将历史记录写入.bash_history
!20 :唤回历史命令中的第20条命令- alias :查看可用的别名
- alias ll=’ls -alF’ :设置别名,不过仅在被定义的shell中才有效
bash shell用一个叫作环境变量的(enviroment variable)的特性来存储有关 shell会话 和 工做环境 的信息
6.1 全局/局部 环境变量
—-全局环境变量对于shell会话和全部生成的字shell都是可见的
—-局部变量则只对建立他们的shell可见
+ printenv :查看全部全局变量
+ printenv HOME :查看单个环境变量
+ env HOME :查看单个全局变量
+ echo
HOME :经过"$”引用HOME的值
+ set :显示全部全局、局部和用户自定义的环境变量github
6.2设置用户定义变量
+ my_variable=hello :变量名、等号和值之间没有空格,在子shell中不能用,退出shell后也会被清除
+ echo
PATH:. #修改环境变量,持续到退出或重启系统正则表达式
6.3 定位系统环境变量
当登入Linux系统启动一个bash shell时,默认状况下bash会在几个文件中查找命令,这些文件叫 启动文件 或 环境文件shell
- 查看、/etc目录下通用的bashrc文件
- 为用户提供一个定制本身的命令别名和私有脚本函数的地方
7.3 理解文件权限express
- 表明文件
d 表明目录
l 表明连接
c 表明字符型设备
b 表明块设备
n 表明网络设备编程
r 表明对象是可读的
w 表明对象是可写的
x 表明对象是可执行的vim
对象的属主
对象的属组
系统其余用户
+ umask 026 :用 umask 命令为默认 umask 设置指定一个新值,一样会做用在建立目录上,见/etc/login.defs或/etc/profile
7.4 改变安全性设置
+ chmod 760 newfile :八进制模式设置
+ chmod o+r newfile :符号模式,[ugoa…][[+-=][rwxXstugo…]
u 表明用户
g 表明组
o 表明其余
a 表明上述全部
X :若是对象是目录或者它已有执行权限,赋予执行权限。
s :运行时从新设置UID或GID。
t :保留文件或目录。
u :将权限设置为跟属主同样。
g :将权限设置为跟属组同样。
o :将权限设置为跟其余用户同样。
+ chown hzq.shared newdir -R:可用登陆名或UID来指定文件的新属主.属组,递归地改变子目录和文件的所
属关系
+ chown hzq. newfile :若是你的Linux系统采用和用户登陆名匹配的组名,能够只用一个条目就改变两者。
+ chgrp shared newfile :更改文件或目录的默认属组
7.5 共享文件
+ chmod g+s testdir :使目录里的新文件都能沿用目录的属组,只需将该目录的SGID位置位,等效于:chmod 2776 testdir
+ Linux还为每一个文件和目录存储了3个额外的信息位。
粘着位:进程结束后文件还驻留(粘着)在内存中。
设置组ID(SGID):对文件来讲,程序会以文件属组的权限运行;对目录来讲,目录中建立的新文件会以目录的默认属组做为默认属组。
设置用户ID(SUID):当文件被用户使用时,程序会以文件属主的权限运行。
h :左移一个字符。
j :下移一行(文本中的下一行)。
k :上移一行(文本中的上一行)。
l :右移一个字符。
PageDown (或Ctrl+F):下翻一屏。
PageUp (或Ctrl+B):上翻一屏。
G :移到缓冲区的最后一行。
num G :移动到缓冲区中的第 num 行。
gg :移到缓冲区的第一行。
w filename :将文件保存到另外一个文件中
删除:x(取叉、错的意思):删除当前光标所在位置的字符
删除:dd(delete ):删除当前光标所在行,至关于剪切
删除:dw(delete word):删除当前光标所在位置的单词
删除:d ) 删除当前光标所在位置至行尾的内容
拼接行:J(join ),删除当前光标所在行行尾的换行符
撤销:u(unsure)
追加数据 :a(add),相似于 “i”
行尾追加 : A(Add)
insert:r char(char表示一个字符):用 char 替换当前光标所在位置的单个字符
insert:R text(至关于insert)直到按下ESC键
复制:v—->移动光标—->y—->p
查找:/+string—–>n(next)
替换:s/old/new/
:s/old/new/g :一行命令替换全部 old 。
:n,ms/old/new/g :替换行号 n 和 m 之间全部 old 。
:%s/old/new/g :替换整个文件中的全部 old 。
:%s/old/new/gc :替换整个文件中的全部 old ,但在每次出现时提示。
#!/bin/bash # This script displays the date and who's logged on echo -n The time and date are: #注意-n选项不换行 date echo "Let's see who's logged into the system:" #全部的引号均可以正常输出了 who #能够将 echo 语句添加到shell脚本中任何须要显示额外信息的地方
#!/bin/bash # display user information from the system. echo "User info for userid: $USER" echo UID: $UID #1.环境变量名称以前加上美圆符"$"来使用这些环境变量 echo HOME: "$HOME" #2.加上双引号也没有问题 echo "The cost of the item is \$15" #3.想显示"$"符号须要在前面加上反斜杠 # testing variables days=10 #4.shell脚本会自动决定变量值的数据类型 guest="Katie" #5.变量名区分大小写 echo "$guest checked in $days days ago" days=5 #6.赋值时不用$,可是引用必须用$符号 guest="Jessica" echo "$guest checked in $days days ago" #7.在shell脚本结束时变量会被删除掉 #有两种方法能够将命令输出赋给变量: #1. 反引号字符( ` ) :注意不是单引号(') #2. $() 格式 one=`date` #8.shell命令的输出赋给变量方法1 two=$(date) #9.赋值等号和命令替换字符之间没有空格 echo "The date and time are: " $one # #下面这个例子很常见,它在脚本中经过命令替换得到当前日期并用它来生成惟一文件名。 # copy the /usr/bin directory listing to a log file today=$(date +%y%m%d) #today存储日期 ls /usr/bin -al > log.$today #ls的输出重定向到log.180515文件中,若是输出文件已经存在了,重定向操做符会用新的文件数据覆盖已有文件(默认的 umask 设置)
在shell脚本中有两种途径来进行数学运算
+ expr 1 + 5 :计算加法表达式
+ expr 5 * 2 :计算乘法表达式
ARG1 | ARG2
若是 ARG1 既不是null也不是零值,返回 ARG1 ;不然返回 ARG2
ARG1 & ARG2
若是没有参数是null或零值,返回 ARG1 ;不然返回 0
ARG1 < ARG2
若是 ARG1 小于 ARG2 ,返回 1 ;不然返回 0
ARG1 <= ARG2
若是 ARG1 小于或等于 ARG2 ,返回 1 ;不然返回 0
ARG1 = ARG2
若是 ARG1 等于 ARG2 ,返回 1 ;不然返回 0
ARG1 != ARG2
若是 ARG1 不等于 ARG2 ,返回 1 ;不然返回 0
ARG1 >= ARG2
若是 ARG1 大于或等于 ARG2 ,返回 1 ;不然返回 0
ARG1 > ARG2
若是 ARG1 大于 ARG2 ,返回 1 ;不然返回 0
ARG1 + ARG2
返回 ARG1 和 ARG2 的算术运算和
ARG1 - ARG2
返回 ARG1 和 ARG2 的算术运算差
ARG1 * ARG2
返回 ARG1 和 ARG2 的算术乘积
ARG1 / ARG2
返回 ARG1 被 ARG2 除的算术商
ARG1 % ARG2
返回 ARG1 被 ARG2 除的算术余数
STRING : REGEXP
若是 REGEXP 匹配到了 STRING 中的某个模式,返回该模式匹配
match STRING REGEXP
若是 REGEXP 匹配到了 STRING 中的某个模式,返回该模式匹配
substr STRING POS LENGTH
返回起始位置为 POS (从 1 开始计数)、长度为 LENGTH 个字符的子字符串
index STRING CHARS
返回在 STRING 中找到 CHARS 字符串的位置;不然,返回 0
length STRING
返回字符串 STRING 的数值长度
_ + TOKEN :将 TOKEN 解释成字符串,即便是个关键字
(EXPRESSION) : 返回 EXPRESSION 的值
#!/bin/bash
var1=100
var2=45
var3=$(echo "scale=4; $var1 / $var2" | bc)#将 scale 变量设置成了四位小数,并在 expression 部分指定了特定的运算
echo The answer for this is $var3
注意下面的注释:不能加Tab
#!/bin/bash
var1=10.23
var2=43.12
var3=33.2
var4=31
var5=$(bc<<EOF
scale = 4 #注意不能加tab键
a1 = ($var1 * $var2)
b1 = ($var3 * $var4)
a1 + b1
EOF
)
echo The final answer for this mess is $var5
Linux退出状态码
0命令成功结束
1 通常性未知错误
2 不适合的shell命令
126 命令不可执行
127 没找到命令
128 无效的退出参数
128+x 与Linux信号x相关的严重错误
130 经过Ctrl+C终止的命令
255 正常范围以外的退出状态码
exit 命令:容许你在脚本结束时指定一个退出状态码
如:exit 5
#!/bin/bash
#shell中运行的每一个命令都使用退出状态码(exit status)告诉shell它已经运行完毕
var1=10
var2=30
var3=$[$var1 + $var2]
exit $var3 #exit 命令的参数中使用变量
#若是值大于255,返回模256后获得的余数
才会
被执行#!/bin/bash
# 这个脚本在 if 行采用了 pwd 命令。若是命令成功结束, echo 语句就会显示该文本字符串
if pwd
then
echo "It worked"
fi
if IamNotaCommand #因为这是个错误的命令,因此它会产生一个非零的退出状态码
then
echo "It "
echo "worked" #这里能够放多条明令
else
echo "It not worked!"
fi
#!/bin/bash
# 甚至能够更进一步,让脚本检查拥有目录的不存在用户以及没有拥有目录的不存在用户。这
# 能够经过在嵌套 elif 中加入一个 else 语句来实现。
testuser=NoSuchUser
#
if grep $testuser /etc/passwd
then
echo "The user $testuser exists on this system."
#
elif ls -d /home/$testuser #每块命令都会根据命令是否会返回退出状态码 0 来执行。记住,bash shell会依次执行 if 语句,
#只有第一个返回退出状态码 0 的语句中的 then 部分会被执行
then
echo "The user $testuser does not exist on this system."
echo "However, $testuser has a directory."
#
else
echo "The user $testuser does not exist on this system."
echo "And, $testuser does not have a directory."
fi
n1 -eq n2
检查 n1 是否与 n2 相等
n1 -ge n2
检查 n1 是否大于或等于 n2
n1 -gt n2
检查 n1 是否大于 n2
n1 -le n2
检查 n1 是否小于或等于 n2
n1 -lt n2
检查 n1 是否小于 n2
n1 -ne n2
检查 n1 是否不等于 n2
#!/bin/bash
# Using numeric test evaluations
#使用中括号进行数值测试
value1=10
value2=11
#
if [ $value1 -gt 5 ] #可是只能测试整数
then
echo "The test value $value1 is greater than 5"
fi
#
if [ $value1 -eq $value2 ]
then
echo "The values are equal"
else
echo "The values are different"
fi
12.3.2 字符串比较
str1 = str2
检查 str1 是否和 str2 相同
str1 != str2
检查 str1 是否和 str2 不一样
str1 < str2
检查 str1 是否比 str2 小
str1 > str2
检查 str1 是否比 str2 大
-n str1
检查 str1 的长度是否非0
-z str1
检查 str1 的长度是否为0
在比较测试中,大写字母被认为是小于小写字母的。但 sort 命令刚好相反,由于sort使用的是系统的本地化语言设置中定义的排序顺序,而比较测试中使用的是标准的ASCII顺序
#!/bin/bash
# mis-using string comparisons
#
val1=baseball
val2=hockey
#
if [ $val1 \> $val2 ] #注意,必须加斜杠,不然会被当成重定向符
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi
# testing string length
val1=testing
val2=''
#
if [ -n $val1 ]
then
echo "The string '$val1' is not empty"
else
echo "The string '$val1' is empty"
fi
#
if [ -z $val2 ]
then
echo "The string '$val2' is empty"
else
echo "The string '$val2' is not empty"
fi
#
if [ -z $val3 ]
then
echo "The string '$val3' is empty"
else
echo "The string '$val3' is not empty"
fi
检查 file 是否存在并是一个目录 | -d file |
---|---|
检查 file 是否存在 | -e file |
检查 file 是否存在并是一个文件 | -f file |
检查 file 是否存在并可读 | -r file |
检查 file 是否存在并不是空 | -s file |
检查 file 是否存在并可写 | -w file |
检查 file 是否存在并可执行 | -x file |
检查 file 是否存在并属当前用户全部 | -O file |
检查 file 是否存在而且默认组与当前用户相同 | -G file |
检查 file1 是否比 file2 新 ,必须先确认文件是存在的 | file1 -nt file2 |
检查 file1 是否比 file2 旧 | file1 -ot file2 |
#!/bin/bash
# Look before you leap
# 文件测试
jump_directory=/home/hzq
#
if [ -d $jump_directory ]
then
echo "The $jump_directory directory exists"
cd $jump_directory
ls
else
echo "The $jump_directory directory does not exist"
fi
if-then 语句容许你使用布尔逻辑来组合测试。有两种布尔运算符可用:
+ [ condition1 ] && [ condition2 ]
+ [ condition1 ] || [ condition2 ]
#!/bin/bash
# using double parenthesis
#
val1=10
#
if (( $val1 ** 2 > 90 ))
then
(( val2 = $val1 ** 2 ))
echo "The square of $val1 is $val2"
fi
# val++ 后增
# val-- 后减
# ++val 先增
# --val 先减
# ! 逻辑求反
# ~ 位求反
# ** 幂运算
# << 左位移
# >> 右位移
# & 位布尔和
# | 位布尔或
# && 逻辑和
# || 逻辑或
#!/bin/bash
# using pattern matching
# 使用模式匹配
if [[ $USER == r* ]]
then
echo "Hello $USER"
else
echo "Sorry, I do not know you"
fi
#!/bin/bash
# using the case command
# 使用case命令
case $USER in
rich | barbara)
echo "Welcome, $USER"
echo "Please enjoy your visit";;
testing)
echo "Special testing account";;
jessica) #")"至关于C语言中的":"
echo "Do not forget to log off when you're done";;
*) #*通配符即匹配全部状况
echo "Sorry, you are not allowed here";;
esac #case语句结束
#!/bin/bash
# another example of how not to use the for command
for test in I don\'t know if "this'll" work #不添加反斜杠会被视做一个字符串 do #若是一个词语中有空格,须要用双引号圈起来 echo "word:$test" done
#!/bin/bash
# reading values from a file
file="states"
for state in $(cat $file)
do
echo "Visit beautiful $state"
done
for语句中的list中,环境变量 IFS(内部字段分隔符)默认会用空格、制表符、换行符做为分隔符
+ IFS.OLD=
’\n’:;” :使用换行、冒号、分号做为分隔符
<在代码中使用新的IFS值>
IFS=$IFS.OLD :修改使只识别换行符
#!/bin/bash
# testing the C-style for loop
for (( i=1; i <= 10; i++ )) #1.变量赋值能够有空格
do #2.条件中的变量不以美圆符开头
echo "The next number is $i" #3.迭代过程的算式未用 expr 命令格式
done
##############################
# multiple variables
for (( a=1, b=10; a <= 10; a++, b-- ))
do
echo "$a - $b"
done
##############################
#!/bin/bash
# testing a multicommand while loop
var1=10
while echo $var1 #检查 var1 是否大于等于 0
[ $var1 -ge 0 ] #只有最后一个测试命令的退出状态码会被用来决定何时结束循环
do #每次迭代中全部的测试命令都会被执行,区别于C语言的 ||
echo "This is inside the loop"
var1=$[ $var1 - 1 ]
done
#!/bin/bash
# using the until command
var1=100
until echo $var1 #shell会执行指定的多个测试命令,只有在最后一个命令成立时中止
[ $var1 -eq 0 ] #退出状态码不为0,才执行循环中列出的命令
do # -eq :检查是否相等
echo Inside the loop: $var1
var1=$[ $var1 - 25 ]
done
$ cat test14
#!/bin/bash
# nesting for loops
for (( a = 1; a <= 3; a++ ))
do
echo "Starting loop $a:"
for (( b = 1; b <= 3; b++ ))
do
echo " Inside loop: $b"
done
done
#!/bin/bash
# changing the IFS value
# 经过改变IFS的值处理 /etc/passwd文件
IFS.OLD=$IFS
IFS=$'\n' #先按行处理文件数据
for entry in $(cat /etc/passwd)
do
echo "Values in $entry –"
IFS=: #再把每一行用空格分开
for value in $entry
do
echo " $value"
done
done
#!/bin/bash
# breaking out of an outer loop
for (( a = 1; a < 4; a++ ))
do
echo "Outer loop: $a"
for (( b = 1; b < 100; b++ ))
do
if [ $b -gt 4 ]
then
break 2 #1.注意,加上参数这里能够跳出两层循环
fi
echo " Inner loop: $b"
done
done
#!/bin/bash
# continuing an outer loop
for (( a = 1; a <= 5; a++ ))
do
echo "Iteration $a:"
for (( b = 1; b < 3; b++ ))
do
if [ $a -gt 2 ] && [ $a -lt 4 ]
then
continue 2 #1.加上参数指定要继续执行哪一级循环
fi
var3=$[ $a * $b ]
echo " The result of $a * $b is $var3"
done
done
#!/bin/bash
for file in /home/hzq/*
do
if [ -d "$file" ]
then
echo "$file is a directory"
elif [ -f "$file" ]
then
echo "$file is a file"
fi
done
#!/bin/bash
# finding files in the PATH
IFS=:
for folder in $PATH #1.遍历每个PATH目录中的路径
do
echo "$folder:" #2. 打印这些路径
echo "$IFS"
for file in $folder/* #为何IFS是":",可是这里仍是能分开
do
echo "$IFS"
if [ -x $file ]
then
echo " $file"
fi
done
done
#!/bin/bash
# using one command line parameter
#
factorial=1
for (( number = 1; number <= $1 ; number++ ))
do
factorial=$[ $factorial * $number ]
done
echo The factorial of $1 is $factorial
if [ -n "$1" ]&&[ -n "$2" ] #0.注意:这里必须加引号
then
total=$[ $1 * $2 ] #1.一个参数乘以第二个参数
echo The first parameter is $1. #2.参数也能够是字符串,以空格分隔
echo The second parameter is $2. #3.若是参数不止9个,能够用花括号:${10}
echo The total value is $total.
else
echo "please input two number"
fi
echo "$0 is run in the end" #4.$0保存的是脚本的名字
#潜在问题:若是使用另外一个命令来运行shell脚本,命令会和脚本名混在一块儿,出如今 $0 参数中。
echo "$(basename $0)is run in the end " #不过能够这样解决
#!/bin/bash
# testing $* and $@
#
echo
count=1
#
for param in "$*" #$* :全部的参数
do
echo "\$* Parameter #$count = $param"
count=$[ $count + 1 ]
done
#
echo
count=1
#
for param in "$@"
do #$@ :将参数视做单独的单词
echo "\$@ Parameter #$count = $param"
count=$[ $count + 1 ]
done
#!/bin/bash
# demonstrating the shift command
echo
count=1
while [ -n "$1" ]
do
echo "Parameter #$count = $1"
count=$[ $count + 1 ]
shift 2 #向左移动参数,可是$0不变,加上参数表示一次移动两个
done
set -- $(getopt -q ab:cd "$@")
#!/bin/bash
# Extract command line options & values with getopt
#
set -- $(getopt -q ab:cd "$@")
#
echo
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) param="$2"
echo "Found the -b option, with parameter value $param"
shift ;;
-c) echo "Found the -c option" ;;
--) shift
break ;;
*) echo "$1 is not an option";;
esac
shift
done
#
count=1
for param in "$@"
do
echo "Parameter #$count: $param"
count=$[ $count + 1 ]
done
#须要注意的是:getopt 命令并不擅长处理带空格和引号的参数值,以下面这种状况
#$ ./32_getopt.sh -a -b test1 -cd "test2 test3" test4
#!/bin/bash
# Processing options & parameters with getopts
#
echo
while getopts :ab:cd opt #指明要查找哪些命令行选项,以及每次迭代中存储它们的变量名(opt)
do
case "$opt" in
a) echo "Found the -a option" ;; #注意这里没有单破折号,已经移除了
b) echo "Found the -b option, with value $OPTARG" ;;
c) echo "Found the -c option" ;;
d) echo "Found the -d option" ;;
*) echo "Unknown option: $opt" ;;
esac
done
#
shift $[ $OPTIND - 1 ]
#
echo
count=1
for param in "$@"
do
echo "Parameter $count: $param"
count=$[ $count + 1 ]
done
#./32_getopt.sh -b "test1 test2" -a :如今能够正常解析空格了
#./32_getopt.sh -abtest1 :将选项字母和参数值放在一块儿使用,而不用加空格
#./32_getopt.sh -acde :将命令行上找到的全部未定义的选项统一输出成问号
#!/bin/bash
# testing the read -p option
#
#
echo -n "Enter your name: " # -n 参数使不换行
read name
echo "Hello $name, welcome to my program. "
# -t 指定等待的秒数
read -t 5 -p "Enter your name: " # 不指定变量,数据会放入特殊环境变量REPLY中
echo Hello $REPLY, welcome to my program.
read -p "Please enter your age: " age # -p 命令直接指定提示字符串
days=$[ $age * 365 ]
echo "That makes you over $days days old! "
read -n1 -p "Do you want to continue [Y/N]? " answer
case $answer in # -n 参数指定接收的输入个数
Y | y) echo
echo "fine, continue on…";;
N | n) echo
echo OK, goodbye
exit;;
esac
# -s 参数避免在命令中输入的数据出如今显示器上
read -s -p "Enter your password: " pass #事实是会显示,只是跟背景色同样
echo "Is your password really $pass? "
#!/bin/bash
# reading data from a file
count=1
test="34_read_input.sh"
cat $test | while read line #1.每次读取一行
do #2.
echo "Line $count: $line"
count=$[ $count + 1]
done
echo "Finished processing the file"
shell自动赋予了错误消息更高的优先级
echo "This is an error" >&2
:有意生成一条错误信息exec 1>testout
:用 exec 命令告诉shell在脚本执行期间重定向某个特定文件描述符exec 0< testfile
: exec 命令容许你将 STDIN 重定向到Linux系统上的文件中#!/bin/bash
# using an alternative file descriptor
exec 3>test13out #能够用 exec 命令来给输出分配文件描述符
#exec 3>>test13out #也可使用 exec 命令来将输出追加到现有文件中
echo "This should display on the monitor"
echo "and this should be stored in the file" >&3
echo "Then this should be back on the monitor"
#!/bin/bash
# storing STDOUT, then coming back to it
exec 3>&1 #1.文件描述符3重定向到标准输出
exec 1>test14out #2.标准输出重定向到文件
echo "This should store in the output file"
echo "along with this line."
exec 1>&3 #3.利用该文件描述符3重定向回 STDOUT
echo "Now things should be back to normal" #+.这句输出到屏幕
#!/bin/bash
# redirecting input file descriptors
exec 6<&0 #1.先用文件描述符 6 用来保存 STDIN 的位置
exec 0< testfile #2.将 STDIN 重定向到一个文件
count=1
while read line #3.read命令的全部输入都来自重定向后的 STDIN
do
echo "Line #$count: $line"
count=$[ $count + 1 ]
done
exec 0<&6 #4.将 STDIN 恢复到原先的位置
read -p "Are you done now? " answer
case $answer in
Y|y) echo "Goodbye";;
N|n) echo "Sorry, this is the end.";;
esac
#!/bin/bash
# testing input/output file descriptor
exec 3<> testfile #1.用exec命令将文件描述符 3 分配给文件 testfile 以进行文件读写
read line <&3 #2.用 read 命令读取文件中的第一行
echo "Read: $line" #3.须要注意:写入文件中的数据会覆盖已有的数据
echo "This is a test line" >&3
#!/bin/bash
# testing closing file descriptors
exec 3> test17file
echo "This is a test line of data" >&3
exec 3>&- #1.要关闭文件描述符,将它重定向到特殊符号 &-
echo "This won't work" >&3 #2.这里shell会生成错误消息
cat test17file #3.打开了同一个输出文件,shell会用一个新文件来替换已有文件
exec 3> test17file
echo "This'll be bad" >&3 #4.因此意味着这几句话会覆盖已有文件
/usr/sbin/lsof -a -p $$ -d 0,1,2
#!/bin/bash
#creating and using a temp file
tempfile=$(mktemp test19.XXXXXX) #生产一个临时文件
exec 3>$tempfile #输出重定向到该文件
echo "This script writes to temp file $tempfile"
echo "This is the first line" >&3
echo "This is the second line." >&3
echo "This is the last line." >&3
exec 3>&- #关闭文件描述符
echo "Done creating temp file. The contents are:"
cat $tempfile
rm -i $tempfile 2> /dev/null #删除文件,并把删除的提示信息输出到/dev/null,即不显示
#!/bin/bash
# using a temporary directory
tempdir=$(mktemp -d dir.XXXXXX) #建立临时文件夹
cd $tempdir
tempfile1=$(mktemp temp.XXXXXX)
tempfile2=$(mktemp temp.XXXXXX)
exec 7> $tempfile1 #重定向文件描述符到文件
exec 8> $tempfile2
echo "Sending data to directory $tempdir"
echo "This is a test line of data for $tempfile1" >&7
echo "This is a test line of data for $tempfile2" >&8
#!/bin/bash
# Modifying a set trap
#
trap "echo ' Sorry... Ctrl-C is trapped.'" SIGINT
#捕获"终止进程"信号
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
#
trap "echo ' I modified the trap!'" SIGINT
#到这里处理信号的方式已经变了
count=1
while [ $count -le 5 ]
do
echo "Second Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
trap -- SIGINT #删除设置好的捕获,单破折号也能起做用
echo "Ctrl-C can use le"
count=1
while [ $count -le 5 ]
echo "Second Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
./test4.sh &
:只须要像这样,在命令后面加一个&,可是这样仍是会有输出,不要奇怪nohup ./test1.sh &
:能够用nohup命令,阻断全部发送给该进程的SIGHUP信号,输出会被保存到nohup.out文件中jobs -l
bg
:之后台模式重启一个做业,若是有多个就得加做业号fg 2
:之前台模式重启做业,可用带有做业号的 fg 命令从-20(最高优先级)到+19(最低优先级),默认以0优先级启动,能够记作”好人难作”
+ nice -n 10 ./test4.sh > test4.out &
:nice命令指定运行的优先级
+ ps -p 4973 -o pid,ppid,ni,cmd,能够用这个命令验证
+ -n 选线不是必须的,只须要指定优先级就好了
+ 可是像下降优先级必须得有root权限
+ renice -n 10 -p 5055
+ renice命令容许改变已经运行进程的优先级
+ 只能对属于你的进程执行 renice
+ 只能经过 renice 下降进程的优先级
+ root用户能够经过 renice 来任意调整进程的优先级
at [-f filename] time
:指定Linux系统什么时候运行脚本 atq
:查看系统中有哪些做业在等待atrm 18
:根据做业号删除指定做业date +%d -d tomorrow
= 01 ] ; then ; command :每月的最后一天执行的命令period delay identifier command
function divem { echo $[ $1 / $2 ]; }
:采用单行方式定义函数 function doubleit { read -p "Enter value: " value; echo $[$value * 2 ]; }
:须要注意的是得加分号,这样才知道起止位置 [ 2 ]
}
- 也能够像这样采用多行定义的方式
. /home/rich/libraries/myfuncs
:能够在bashrc文件末尾加上你本身的函数库
sed options script file
echo "This is a test" | sed 's/test/big test/'
sed 's/dog/cat/' data1.txt
:不过不会修改文本文件的数据,只是显示到STDOUTsed -e 's/brown/green/; s/dog/cat/' data1.txt
:使用多个命令须要用-e参数sed -e '
:而后把命令一条一条输进去sed -f script1.sed data1.txt
:也能够把上述三条命令放进一个文件,经过-f参数指定这个文件,去处理data1.txtgawk options program file
gawk '{print "Hello World!"}'
:对每行文本执行脚本gawk '{print $1}' data2.txt
:打印date2.txt文件中每行的第一个单词,默认是空白字符或者制表符做为分隔符gawk -F: '{print $1}' /etc/passwd
:-F指定字段分隔符echo "My name is Rich" | gawk '{$4="Christine"; print $0}'
:要执行多个命令,只须要用”;”分隔gawk '{
:也能够用此提示符一行一行的输入gawk -F: -f script2.gawk /etc/passwd
:能够把命令放到script.gawk文件中,经过-f参数运行sed '2,$s/test/trial/' data4.txt 3gpw data4s.txt
:转义字符前加”\” sed '/Samantha/s/bash/csh/' /etc/passwd
:Samantha这里能够替换成正则表达式,因此整句只查找正则表达式匹配到的行sed '3d' data6.txt
:删除第三行sed '2,3d' data6.txt
:删除2~3行sed '3,$d' data6.txt
:删除第三行开始之后的全部行sed '/number 1/d' data6.txt
:删除出现number 1的行sed '/1/,/3/d' data6.txt
:第一个模式打开删除功能,第二个模式关闭删除功能,sed编辑器会删除两个指定行之间的全部内容,若是后面又匹配到1,又会打开删除模式echo "Test Line 2" | sed 'i\Test Line 1'
:-i参数在指定行前面插入一行echo "Test Line 2" | sed 'a\Test Line 1'
:-a参数在指定行后面添加一行sed '3i\> This is an inserted line.' data6.txt
:这是一个将新行插入到第三行前面的例子sed '$a\> This is a new line of text.' data6.txt
附加到末尾sed '3c\ This is a changed line of text.' data6.txt
:-c参数指定修改模式,这里修改第三行sed '/number 3/c\ This is a changed line of text.' data6.txt
:也能够经过模式匹配的方式修改sed '2,3c\ This is a new line of text.' data6.txt
:也可使用区间地址,可是这一行会覆盖二、3两行sed 'y/123/789/' data8.txt
:1替换成9,2替换成8,3替换成9,直到替换完全部的字符sed -n '/number 3/p' data6.txt
:-p参数表打印模式,-n参数用来禁止输出其余行sed '=' data1.txt
:”=”打印的会输出行号sed -n 'l' data9.txt
:打印数据流中的文本和不可打印的ASCII字符sed '1,2w test.txt' data6.txt
:将数据流中的前两行打印到文件中sed '3r data12.txt' data6.txt
:将data12.txt中的数据插入到data6.txt的第三行后面sed '/number 2/r data12.txt' data6.txt
:将data12中的数据插入到匹配行的后面sed '$r data12.txt' data6.txt
:插入到末尾echo "This is a test 1" | sed -n '/test 1/p'
:p命令输出匹配到的行,注意空格和其余字符并无什么区别echo "This is a test" | gawk '/tes/{print $0}'
:print命令输出匹配到的行,注意两种写法都区分大小写,不用写出完整单词.*[]^${}\+?|()
sed -n '/\$/p' data2
:使用特殊字符必须转义echo "3 / 2" | sed -n '/\//p'
:注意,使用正斜线也必须转义echo "Books are great" | sed -n '/^ Book/p'
:Book必须出如今行首才能匹配到echo "This ^ is a test" | sed -n '/s ^ /p'
:脱字符放在其余地方就变成普通字符了echo "This is a good book" | sed -n '/book$/p'
:字符”$”指明数据行必须以该文本结尾sed -n '/^ this is a test$/p' data4
:会忽略那些不仅仅只包含这些文本的行sed '/^ $/d' data5
:删除文本中的空白行sed -n '/.at/p' data6
:”.”匹配任意一个字符,若是没有(如行首)则匹配失败sed -n '/[ch]at/p' data6
:[ch]字符组取代”.”使通配符精确一点,不过必须有一个字符组中的字符被匹配到sed -n ' /^ [0123456789][0123456789]$/p ' data8
:匹配只出现两个数字的一行sed -n '/[^ ch]at/p' data6
:在字符组的开头加上脱字符,就成了了排除型字符组sed -n '/^[0-9][c-h][a-ch-m]$/p' data8
:单破折号表示linux字符集中得字符,即这样能够表示区间,最后一个区间表示a~c,h~m特殊字符
echo "ieeeek" | sed -n '/ie*k/p'
:字符后面放*,表示该字符要出现一次或屡次
echo "this is a regular pattern expression" | sed -n '/regular.*expression/p'
:.*
的组合表示若干字符echo "bt" | gawk '/b[ae]?t/{print $0}'
:?表示字符组出现了一次或零次,另外,注意sed不支持扩展的正则表达式echo "beeet" | gawk '/be+t/{print $0}'
:加号表示+前面的字符至少出现一次echo "bet" | gawk --re-interval '/be{1}t/{print $0}'
:{}中的1表示e恰好出现了一次echo "bt" | gawk --re-interval '/be{1,2}t/{print $0}'
:{}中的1,2表示至少出现一次,最多出现两次echo "The cat is asleep" | gawk '/cat|dog/{print $0}'
:管道容许匹配两个模式中的任何一个echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
:()能对字符进行分组,即表示urday是一个总体