读后摘记
最近在看一本书叫 《linux命令行和shell脚本编程大全》于是又开始了黑白机的各种玩弄:内容杂乱,只适合自己,要找东西Control +F
Linux
1:指令
陈述目录中文件 ls *
软连接 In A B
移动 mv a b
删除 rm -I xxxx -i命令参数提示你是不是要真的删除该文件
cat -n a.txt 显示行数
kill -s HUP 3940. -s参数支持指定其他信号(用信号名或信号值)
mount -t vfat /dev/sdb1 /media/disk. 挂载指令
df -h 磁盘使用大小
du -h
sort xxxx. 按字符排序
sort -n xxxx. 里面按值的大小排序
Sort -M 。。。。按月份排序
如果要显示匹配模式的行所在的行号,可加-n参数。
grep -n t file1
gzip:用来压缩文件。
gzcat:用来查看压缩过的文本文件的内容。
gunzip:用来解压文件。
tar zcvf etcbak.tar.gz etc/ 打包压缩一个 tar
tar zxvf etcbak.tar.gz 解压一个tar
!! 重新执行指令
!20 history的后续指令
alias li='ls -li' 取别名(常用)
Shell 脚本
#!/bin/bash
在通常的shell脚本中,井号(#)用作注释行。shell并不会处理shell脚本中的注释行。然而, shell脚本文件的第一行是个例外,#后面的惊叹号会告诉shell用哪个shell来运行脚本(是的,你 可以使用bash shell,同时还可以使用另一个shell来运行你的脚本)。
echo -n "The time and date are: "
你需要在字符串的两侧使用引号,保证要显示的字符串尾部有一个空格。命令输出将会在紧接着字符串结束的地方出现。现在的输出会是这样:
注意,赋值等号和命令 替换字符之间没有空格
date +%y%m%d 固定显示时间
输出:
重定向 : 覆盖输出 >
追加 : >>
输入:一个简单的记忆方法就是:在命令行上,命令总是在左侧,而重定向符号“指向”数据流动 的方向。小于号说明数据正在从输入文件流向命令
整数
expr 表达式指令
或者用中括号括起来
Ex1:
var1=10
var2=20
echo var3 is value of $var2/$var1
echo var3 = $(expr $var2 / $var1)
Ex2:
$ cat test7
#!/bin/bash
var1=100
var2=50
var3=45
var4=$[$var1 * ($var2 - $var3)]
echo The final result is $var4
小数
#!/bin/bash
var1=$(echo "scale=4; 3.44 / 5" | bc)
echo The answer is $var1
最好的办法是使用内联输入重定向,它允许你直接在命令行中重定向数据。在shell脚本中, 你可以将输出赋给一个变量。
variable=$(bc << EOF
options
statements
expressions
EOF )
EOF文本字符串标识了内联重定向数据的起止。记住,仍然需要命令替换符号将bc命令的输 出赋给变量。 14
Ex1
#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=$(bc << EOF
scale = 4
a1 = ( $var1 * $var2)
b1 = ( $var3 * $var4)
a1 + b1
EOF
)
echo The final answer for this mess is $var5
$? 会返回程序结束完的状态码
若为0 则执行完毕,其余均为错误
使用if-then语句 :
if command then
commands
fi
比较
#!/bin/bash
var1=baseball
var2=hockey
if [ $var1 \> $var2 ]
then
echo "$var1 is greater than $var2"
else
echo " $var1 is less then $var2 "
fi
符号需要转义
在比较测试中,大写字母被认为是小于小写字母的。但sort命令恰好相反。当你将同样的 字符串放进文件中并用sort命令排序时,小写字母会先出现。这是由各个命令使用的排序技术 不同造成的。
-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 检查file是否存在并且默认组与当前用户相同
file1 -nt file2 检查file1是否比file2新
file1 -ot file2 检查file1是否比file2旧
(( expression )) expression可以是任意的数学赋值或比较表达式。除了test命令使用的标准数学运算符,
Ex1
#!/bin/bash
# using double parenthesis #
val1=10
#
if (( $val1 ** 2 > 90 )) then
(( val2 = $val1 ** 2 ))
echo "The square of $val1 is $val2"
fi
[[ expression ]] 双方括号里的expression使用了test命令中采用的标准字符串比较。但它提供了test命
令未提供的另一个特性——模式匹配(pattern matching)。
ex2:
#!/bin/bash
# using pattern matching #4 if [[ $USER == r* ]]
then
echo "Hello $USER"
else 5
echo "Sorry, I do not know you"
fi
for 语句
for var in list
do
commands
done
Ex1:
#!/bin/bash
# basic for command
for test in Alabama Alaska Arizona Arkansas California Colorado
do
echo The next state is $test
done
#!/bin/bash
# reading values from a file
file="states"
IFS=$’\n’ 这里是修改系统判定行的环境因素
for state in $(cat $file)
do
echo "Visit beautiful $state"
done
在处理代码量较大的脚本时,可能在一个地方需要修改IFS的值,然后忽略这次修改,在 脚本的其他地方继续沿用IFS的默认值。一个可参考的安全实践是在改变IFS之前保存原 来的IFS值,之后再恢复它。
这种技术可以这样实现:
IFS.OLD=$IFS IFS=$'\n' <在代码中使用新的IFS值> IFS=$IFS.OLD
这就保证了在脚本的后续操作中使用的是IFS的默认值。
幸好有个方便的小命令可以帮到我们。basename命令会返回不包含路径的脚本名
这里开始就要开始有点想法了
循环判断
for obj in ./* do if [ -d $obj ] then echo $obj is a dir
else echo $obj is a file fi done
写这个主要是想每次写个shell的时候都要赋权,chmod +x shellName ,有了这个想法,就可以每次调用这个方法
以下为refresh方法 虽然没有写的很完美,但是,还是赞的
#!/bin/bash dir=`pwd` echo $dir if [ -d $dir ] then chmod -R +x $dir echo "===刷新权限成功" else echo "===刷新权限失败" fi
开始抄作业
(多变量,基本不可能用到)在第9个变量之后,你必须在变量数字周围加上花括号,比如${10}。下面是一个这样的例子。
$ cat test4.sh
#!/bin/bash
# handling lots of parameters
#
total=$[ ${10} * ${11} ]
echo The tenth parameter is ${10}
echo The eleventh parameter is ${11}
echo The total is $total
$ ./test4.sh 1 2 3 4 5 6 7 8 9 10 11 12
The tenth parameter is 10
The eleventh parameter is 11
The total is 110
if [ -n $val1 ] 判断val1变量是否长度非0,而它的长度正好非0,所以then部分被执行了。
if [ -z $var2 ]判断val2变量是否长度为0,而它正好长度为0,所以then部分被执行了。
有点不理解下面的双引号为什么要加,或者说加了之后当一个字符?
#!/bin/bash
if [ -n "$1" ]
then
echo param $1
else
echo null input
fi
特殊字符的替换