Linux Shell 学习笔记(一)

来源:互联网 发布:sql2005数据库复制 编辑:程序博客网 时间:2024/05/18 17:03

Linux Shell 学习笔记(一)

环境: Centos 7 bash

1. Hello World

1.1 echo

终端打印命令

命令格式:

echo "String"/'String'/String

在屏幕上打印string

  • 打印!:要么不使用”“包括要打印的String,要么使用\进行转义

1.2 printf

相比于echo,printf能适应格式化输出,与C中的printf相似

命令格式:

printf "strFormat" string1 string2 ...stringn//示例printf "%-5s %-10s %-4s\n" no name markprintf "%-6.4f\n" 2.1

“-5s”:

  • ‘-‘表示左对齐,默认为右对齐

  • 5代表在屏幕上显示的列数。5.0表示数字类型时,如果数字的位数不够5,则使用0填充

  • s代表要输出的数据类型

    • s:字符串类型

    • d:整数类型

    • f:浮点数类型

2.环境变量

当一个应用程序在执行时,它接受一组环境变量,可以使用env命令进行查看。对于每一个进程,其运行时的环境变量可以使用以下命令查看$PID表示进程的id

cat /proc/$PID/environ

2.1变量赋值与相等

var=value 变量赋值,如果value中存在空格,则需要使用引号

var = value 判断变量相等

var=sssssecho $varecho ${var}echo var #错误echo "we hava many ${var} m"

2.2环境变量

环境变量:未在当前进程中定义,从父进程继承而来的变量

//例如HTTP_PROXYecho HTTP_PROXYexport HTTP_pROXY

linux提供了许多标准的环境变量,比如$PATH

echo $PATh#输出 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin# 各目录路径之间使用:分割。给出命令之后,linux将会在各个目录中搜索指定命令名称的可执行文件# 添加新的路径至$PATH#'=' 两边没有空格export $PATH="$PATH:/fullPATH"

2.3补充内容

2.3.1获取变量值长度
var=valuelen=${#var}echo $len
2.3.2当前SHELL版本
# way 1echo $SHELL#way 2echo $0
2.3.3 检查当前是否是超级用户
if [$UID -ne 0]; thenecho not a root userelseecho "root user"fi

3.数学运算

在bash环境中,可以利用let,(()),[]执行基本的运算,expr和bc可以进行高级运算

3.1整数运算

var1=10var2=30let result=var1+var2echo result   # 40#let支持++/--和简写模式let var1++let var1--let var1+=10let var1-=10let var1/=2let var1*=2#[]命令与let相似result=$[var1 + var2]result=$[$var1 + var2]#(())使用与[]相似result=$(($var1 + 10))result=$((var1 + 10))# exprresult=`expr 3 + 4`result=$(expr $var1 + 10)

3.2 bc命令 支持浮点数运算

# 命令格式echo "4*0.15" | b`

bc命令的参数可以置于要执行的具体操作之前,使用;进行分割

#设置数值精度echo "scale=2;3/8" | bc#进制转换echo "obase=2;16" | bc                  #结果 10000echo "obase=10;ibase=2;1000" | bc       #结果 8#计算平方/平方根echo "sqrt(100)" | bcecho "10^2" | bc

4. 文件描述符&&重定向

4.1 文件描述符

0       stdin       标准输入1       stdout      标准输出2       stderr      标准错误    

4.2 重定向

#输出重定向echo "i am a boy" > temp.txt        #清空原文件,然后写入echo "i am a boy" >> temp.txt       #在源文件末追加#tee命令 将输入输出到标准输出,并且输出到指定的文件中echo "meaningless string" > temp.txtcat temp.txt | tee temp.back.txt | cat#将脚本中的文本输出到文件中(下面的例子为一个shell脚本文件内容)#!/bin/bashcat <<EOF>log.txtline 1line 2line 3EOFcat log.txt     #将会输出line 1\n line 2\n line 3\n

4.3 自定义文件描述符

文件打开方式有三种,只读\截断\追加

可以使用命令exec创建自定义文件描述符

  • < 将文件内容读入stdin

  • > 截断模式写入文件,原文件内容被删除

  • >> 追加模式写入文件,数据被写在文件的尾部

    exec 3<log.txtcat <&3

find妙用

#查找当前目录以及子目录下所有的txt文件,并且找出含有‘bin’的行find ./ -name "*.txt" -exec grep "bin" {} \; #删除当前目录以及子目录下所有的txt文件find ./ -name "*.txt" -exec rm {} \;

5. 数组和关联数组

5.1 普通数组

#定义array=(1,2,3,4,5)#输出echo ${array[0]}index=1echo ${array[$index]}#打印所有元素echo ${array[*]}echo ${array[@]}

5.2 关联数组

#定义declare -A ass_arrayass_array=([index1]=var1)ass_array[index2]=var2#输出##输出元素echo ${ass_array[index]}echo ${ass_array[*]}echo ${ass_array[@]}##输出索引echo ${!ass_array[@]}

6.别名

#创建别名 命令aliasalias new_command="command sequence"alias install="sudo apt-get install"

alies命令生效时长尾终端的未关闭的时长

如果想保存alias设置,可以将命令写入~/.bashrc

echo alias new_command >> ~/.bashrc

删除alias设置:

1.删除~/.bashrc中的对应项2.使用unalias命令    unalias new_command

7. 终端信息

tput stty 两个工具

7.1 使用介绍

#获取终端行数/列数tput colstput lines#当前终端名tput longname#光标移动tput cup 100 100 #坐标(100,100)

7.2 运行脚本的方法

后面的内容要真正开始编写小脚本,先从如何运行脚本开始学习

7.2.1 将脚本作为sh的命令行参数进行运行
sh ./script.sh                  #假设脚本位于当前工作目录sh /home/path/script.sh         #使用脚本的完整目录运行脚本
7.2.2 作为有执行权限的可执行文件运行
#添加执行权限chmod a+x script.sh             # 默认脚本位于当前工作目录,否则使用脚本的完整运行目录./script.sh                     # 运行 同样注意脚本目录

至于文件权限的知识,后文会讲到

7.3 脚本实现不输出密码

  • stty echo 允许输出到终端

  • stty -echo 禁止输出到终端

    #!/bin/sh#Filename: password.shecho -e "enter password"stty -echoread passwordstty echoechoecho password read doneecho what we have got : $password

8.时间与日期

8.1 使用介绍

#获取时间date#打印纪元时#纪元时 1970/1/1/0:0:0 至今的秒数date +%s 

8.2 循环监视脚本

循环&&判断 不必多说

tput sc存储光标位置,在循环中,恢复之前的光标位置tput rc

tput ed清除光标当前位置到行末的内容,使得旧值被清除,新值显示在旧值位置

#!/bin/shecho -n Count:tput sccount=0;while true:doif [$count -lt 40]then let cout++;sleep 1;tput rctput edecho -n $countelse exit 0;fidone

9. 脚本调试

shell脚本调试不需要任何的工具

bash -x script.sh# 或sh -x script.sh

-x 标识将脚本中执行过的每一行都输出到stdout

也可以只关注某一部分代码,在脚本中可以使用如下命令启用或者禁用调试打印

set -x      # 在执行时显示参数和命令set +x      # 进制调试set -v      # 当命令进行读取时显示输入set +v      # 禁止打印输入

9.1 实践

#!/bin/bashfor i in {1...6}doset -xecho $iset +xdoneecho "script executed"

9.2 自定义调试信息输出格式

通过传递_DEBUG环境变量实现

#!/bin/bashfunction DEBUG(){echo $_DEBUG && $@ || :}for i in {1..6}doDEBUG echo $idone# 代码保存为 script.sh

运行

chmod a+x script.sh_DEBUG=on ./script.sh

便捷调试

在脚本文件首行末添加 “ -xv”

脚本将自动以调试模式运行

9.3 函数

在 9.2 中,我们已经看到了函数

9.3.1 定义函数
#1.function funcName(){statements;}#2.funcName(){statements;}
9.3.2 函数调用
#只需使用函数名 即可调用函数funcName;#参数传递funcName arg1 arg2 ;#示例funcName(){echo $1 $2;    # 输出第一二个参数echo "$@";     # 以列表形式打印所有参数echo "$*";     # 以实体形式打印所有参数return 0;       # 函数返回值}#获取函数返回值# 函数执行后, 返回值暂时保存在$?中funcNameecho $?#补充 fork炸弹:(){ :|:& };:#函数无限递归,造成服务器内存溢出,死机=>拒绝服务攻击#博主也没看明白,函数的实现原理orz

10.命令

10.1 向命令传递参数

#有command命令,假设-p-v是可选项, -K NO是一个可以接受数字的选项,同时该命令可以接受一个文件名作为参数#举例执行方式#1. command -p -v -k 2 file#2.command -pv -k 2 file#3.command -pvk 2 file#4.command file -pvk 2

10.2 命令序列输入输出

shell脚本可以将多个命令或工具一起组合起来使用。一个命令的输出可以作为下一个命令的输入,这个命令的输出又可以作为下一个命令的输入,以此类推。

10.2.1 预备知识

输入通常通过stdin或命令参数传递给命令

输出要么存在于stderr,要么存在于stdout

我们使用管道pipe来连接多个命令,管道的标识符为 “|

被管道连接的命令,我们称之为过滤器filter

10.2.2 实践
#将ls命令的返回加上行号输出到文件中ls | cat -n > out.txt#获取命令的返回output=$(ls)ouput=`ls`      # 反引用#创建子进程#使用()可以创建子进程pwd(cd ..)pwd             #两个输出是相同的

10.3 read命令

10.3.1 不使用回车获得键盘输入

通常bash命令行在接受到键盘回车信号后,认为用户的本次输入完成。我们可以使用read命令实现

read -n 2 varecho $var#执行上述命令脚本,在输入两个字符后,程序马上返回先前输入的两个字符
10.3.2 read参数介绍
# 回车方式获得输入read var            #输入之后,回车结束本次输入# 使用不回显的方式获取输入read -s var# 显示提示信息read -p "please input:" var# 在指定时间内完成输入(时间单位:秒)read -2 var# 指定定界符read -d "EOF" var#用户输入SSEOF之后,输入完成,var的值为SS

10.4 字段分隔符与迭代器

内部字段分割符(Internal Field Seperator, IFS)是shell文本处理的重要内容之一。

shell默认使用的定界字符组存储在$ISF中

10.4.1 处理CSV(Comma Seperated Value)

#!/bin/bashdata="name,gender,address,phoneNum"oldIFS=$IFSIFS=,for item in $data;doecho Item: $itemdone    IFS=$oldIFS

11.循环与判断

11.1 for循环

for i in list;dostatements;done#上文中list{1..50}{a..z}{a..Z}

11.2 while循环

while conditiondostatements;done# condition 是boolean值

11.3 until

until condition;dostatements;done#一直执行直到condition为true

11.4 if

if condition;thencommands;fi

11.5 else elif

if condition1;then    commands;elif condition2;then    commands;else    commands;fi

11.6 算数比较

-gt     大于-lt     小于-eq     等于-ge     大于等于-le     小于等于# 格式[ $var -gt 123 ]

11.7 文件系统比较

[-f $file_var]     判断变量代表的文件或目录是否存在,存在返回真[-x $file_var]     判断文件是否是可执行的,可执行,返回真[-d $file_var]     变量是否代表目录[-e $file_var]     变量代表的文件或目录是否存在[-c $file_var]     变量是否代表字符设备文件[-b $file_var]     变量是否代表块设备文件[-r/w $file  ]     文件是否可读/可写

11.8 字符串比较

[[$str1 = $str2]]   字符串是否相等[[$str1 == $str2]]   同上[[$str1 != $str2]]   字符串是否不相等[[$str1 > $str2]]  字符串字母序大小比较[[ -z $str2]]      字符串是否为空[[ -n $str2]]      字符串是否不为空## 示例#!/bin/bashstr1="a"str2="b"if [[ $str1 > $str2 ]];thenecho "sssssss"elseecho "mmmmmmm"fi
原创粉丝点击