Linux Shell 学习笔记(一)

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 mark
printf "%-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=sssss
echo $var
echo ${var}
echo var #错误
echo "we hava many ${var} m"

2.2环境变量

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

//例如HTTP_PROXY
echo HTTP_PROXY
export 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=value
len=${#var}
echo $len
2.3.2当前SHELL版本
# way 1
echo $SHELL
#way 2
echo $0
2.3.3 检查当前是否是超级用户
if [$UID -ne 0]; then
echo not a root user
else
echo "root user"
fi

3.数学运算

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

3.1整数运算

var1=10
var2=30

let result=var1+var2
echo result   # 40

#let支持++/--和简写模式
let var1++
let var1--
let var1+=10
let var1-=10
let var1/=2
let var1*=2

#[]命令与let相似
result=$[var1 + var2]
result=$[$var1 + var2]

#(())使用与[]相似
result=$(($var1 + 10))
result=$((var1 + 10))

# expr
result=`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                  #结果 10000
echo "obase=10;ibase=2;1000" | bc       #结果 8

#计算平方/平方根
echo "sqrt(100)" | bc
echo "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.txt
cat temp.txt | tee temp.back.txt | cat

#将脚本中的文本输出到文件中(下面的例子为一个shell脚本文件内容)
#!/bin/bash

cat <log.txt
line 1
line 2
line 3
EOF
cat log.txt     #将会输出line 1\n line 2\n line 3\n

4.3 自定义文件描述符

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

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

  • < 将文件内容读入stdin

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

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

    exec 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=1
echo ${array[$index]}

#打印所有元素
echo ${array[*]}
echo ${array[@]}

5.2 关联数组

#定义
declare -A ass_array
ass_array=([index1]=var1)
ass_array[index2]=var2

#输出
##输出元素
echo ${ass_array[index]}
echo ${ass_array[*]}
echo ${ass_array[@]}
##输出索引
echo ${!ass_array[@]}

6.别名

#创建别名 命令alias
alias 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 cols
tput 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.sh
    echo -e "enter password"
    stty -echo
    read password
    stty echo
    echo
    echo password read done
    echo 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/sh
echo -n Count:
tput sc

count=0;
while true:
do
if [$count -lt 40]
then let cout++;
sleep 1;
tput rc
tput ed
echo -n $count
else exit 0;
fi
done

9. 脚本调试

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

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

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

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

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

9.1 实践

#!/bin/bash
for i in {1...6}
do
set -x
echo $i
set +x
done
echo "script executed"

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

通过传递_DEBUG环境变量实现

#!/bin/bash
function DEBUG()
{
echo $_DEBUG && $@ || :
}
for i in {1..6}
do
DEBUG echo $i
done

# 代码保存为 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;       # 函数返回值
}

#获取函数返回值
# 函数执行后, 返回值暂时保存在$?中
funcName
echo $?

#补充 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 var
echo $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/bash
data="name,gender,address,phoneNum"
oldIFS=$IFS
IFS=,

for item in $data;
do
echo Item: $item
done    

IFS=$oldIFS

11.循环与判断

11.1 for循环

for i in list;
do
statements;
done

#上文中list
{1..50}
{a..z}
{a..Z}

11.2 while循环

while condition
do
statements;
done

# condition 是boolean值

11.3 until

until condition;
do
statements;
done

#一直执行直到condition为true

11.4 if

if condition;
then
commands;
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/bash
str1="a"
str2="b"
if [[ $str1 > $str2 ]];
then
echo "sssssss"
else
echo "mmmmmmm"
fi

你可能感兴趣的:(linux)