Debian学习笔记——shell

目录

前言

1. 界面

2. 常用快捷键

3. 历史命令列表

3. 通配符和特殊字符

4. 输入输出与重定向

结尾而5. 后台作业管理

6. 变量

7. 脚本

8. 控制结构

8.1 判定

8.2 循环控制结构

8.3 条件控制结构

 9. 过滤器

总结


 

前言

shell是一个人机交互接口,可以将用户输入的命令发送给系统运行并反馈运行结果。


1. 界面

shell属于系统软件,通常称为“终端”。界面如下:

Debian学习笔记——shell_第1张图片

 一般用户shell以"$"符号为命令提示符,当用户切换为root时,提示符变成“#”。

2. 常用快捷键

Ctrl+n相当于下箭头(next line)

Ctrl+p相当于上箭头(previous line)

Ctrl+r 检索使用过的历史命令(retrieve)

Ctrl+a:相当于Home键,光标移到行首(ahead)

Ctrl+e:相当于End键,光标移到行尾(end)

Ctrl+b:光标向左移动一个字符(backwards)

Ctrl+ f:光标向右移动一个字符(forwards)

Alt+b:光标向左移动一个单词

Alt+f:光标向右移动一个单词

Ctrl+w:  剪切光标前一个单词

Ctrl+k:剪切光标处到行尾的字符

Ctrl+u:剪切光标处到行首的字符

Ctrl+y:粘贴前面剪切的文本

Ctrl+h:相当于Backspace键,向左删除一个字符

Ctrl+d:相当于Delete键,向右删除一个字符

Ctrl+t: 交换光标所在字符和前一个字符

Alt+t:交换光标前两个单词

Alt+l:将光标后一个单词小写

Alt+u:将光标后一个单词大写

Alt+c:将光标后一个单词首字母大写(单词中其他大写字母会自动更改为小写)

Ctrl+s:使当前快速输出的屏幕静止

Ctrl+q:退出Ctrl+s屏幕静止

Ctrl+z:使正在运行在终端的任务,运行于后台

Ctrl+c:终止终端中正在执行的任务

Ctrl+d: 结束当前命令

Ctrl+l: 类似于执行命令"clear",但是不清空历史显示内容

Esc键:连续按3次显示所有的支持的终端命令

Tab键:命令、变量、文件名等自动补全

3. 历史命令列表

执行以下命令可以列出最近500个历史命令,每个命令前都标有序号,使用!+序号可以直接运行对应命令,使用fc+序号,可以打开一个文件,编辑对应命令行,使用fc -e可以指定编辑器 。

 history        列出近500个历史命令,结果如下:
  ……
  241  cat -n 2 cmd
  242  cat -n cmd
  243  clear
  244  exit
  245  exit
  246  history
  ……
!244        运行序号为244的历史命令
fc -e nano        指定编辑器为nano
fc 244        打开文本编辑器,编辑序号为244的历史命令,保存退出后立即执行

$HISTSIZE = 10        可以将历史命令存储数量调整为10个

echo $HISTFILE        可以查看历史命令存储文件名称及位置

3. 通配符和特殊字符

*        任意数量的任意字符

?      单个任意字符

[]        精确匹配括号中的字符,可以用“-”表示序列,比如test.[a-c]表示test.a、test.b、test.c,以"!"或者"^"符号表示否运算,比如test.[!a]表示不以a结尾的文件

{}        列举方式,可以用".."表示序列,比如test.{a..c}表示test.a、test.b、test.c

root@L-debian:/home/test# ls
cmd
root@L-debian:/home/test# mkdir {tree,list,{tree,list}/test.{1..3},tree/test.{x..z}}
root@L-debian:/home/test# tree
.
├── cmd
├── list
│   ├── test.1
│   ├── test.2
│   └── test.3
└── tree
    ├── test.1
    ├── test.2
    ├── test.3
    ├── test.x
    ├── test.y
    └── test.z

11 directories, 1 file
root@L-debian:/home/test# cd tree

root@L-debian:/home/test/tree# ls test.[x-z]
test.x:
test.y:
test.z:

root@L-debian:/home/test/tree# ls test.[!x-z]
test.1:
test.2:
test.3:

\        转义字符,引用其后面的专用字符,后面输入Enter键时,意为将一行命令分成多行执行

;        在一行内执行多个命令时,使用";"分隔

&&     连接过个命令,只有前一个命令为真(执行成功)时,才执行下一个命令

root@L-debian:/home/test# ls
cmd  list  tree
root@L-debian:/home/test# mkdir test.xy\?    #将通配符?作为文件名的一部分

root@L-debian:/home/test# ls
 cmd   list  'test.xy?'   tree
root@L-debian:/home/test# mkdir test\
> .cc    #这里的.cc将连接到上一行,作为文件名的一部分处理
root@L-debian:/home/test# ls
 cmd   list   test.cc  'test.xy?'   tree

root@L-debian:/home/test# mkdir test.cc ; ls    #先后执行两个命令
 cmd   list   test.cc  'test.xy?'   tree

root@L-debian:/home/test# rm test.cc && ls
rm: 无法删除 'test.cc': 是一个目录    #因为第一个命令未能成功执行,第二个命令将不执行

4. 输入输出与重定向

输入输出分三类:标准输入(0)、标准输出(1)、错误输出(2)。

一般情况下,标准输入为键盘输入,标准输出为屏幕输出,如果需要更改输入输出方式,就涉及到重定向的问题。

<        将标准输入重定向到其后文件或设备

root@L-debian:/home/test# sort    #按照首字母排序,后面没有接参数,代表参数为标准输入
8
20
12
20    #从键盘输入8回车,20回车,12回车,20回车,然后使用Ctrl+d结束输入,以下为运算结果
12
20
20
8
root@L-debian:/home/test# 
root@L-debian:/home/test# cat in    #in文件中包含4个字符串
hello
good
word
sorry
root@L-debian:/home/test# sort < in    #将sort的输入重定向为in文件,运行结果如下
good
hello
sorry
word
root@L-debian:/home/test# 

>        将标准输出重定向到其后文件或设备,如文件已存在则覆盖原文件,如果文件不存在则新建该文件

>>        将标准输出追加到其后文件或设备的结尾

root@L-debian:/home/test# ls -C > dir    #将ls输出结果重定向到dir文件
root@L-debian:/home/test# cat dir
cmd  dir  err  in  list  test.cc  test.xy?  tree

root@L-debian:/home/test# ls -C >> dir    #将ls输出结果追加到dir文件
root@L-debian:/home/test# cat dir
cmd  dir  err  in  list  test.cc  test.xy?  tree
cmd  dir  err  in  list  test.cc  test.xy?  tree

2>        将标准错误重定向到其后文件或设备

2>>        将标准错误追加到其后文件或设备的结尾

root@L-debian:/home/test# rmdir list 2> err    #重定向之后,屏幕不再输出错误信息
root@L-debian:/home/test# cat err
rmdir: 删除 'list' 失败: 目录非空

2>&1        将标准错误重定向到标准输出

>&        将标准输出和标准错误都重定向到其后文件或设备

|&        将标准错误重定向为其后命令的输入(参数)

|        管道符,将前一个命令的运行结果传递给后一个命令作为输入(参数)

#第一个命令的错误输出,作为第二个命令的参数
root@L-debian:/home/test# rmdir list |& cat -n    
     1  rmdir: 删除 'list' 失败: 目录非空

#第一个命令的运行结果,作为第二个命令的参数
root@L-debian:/home/test# ls -laF | cat -n    
     1  总用量 28
     2  drwxr-xr-x 6 root root 4096 10月  6 12:08 ./
     3  drwxr-xr-x 4 root root 4096 10月  6 11:25 ../
     4  -rwxr--r-- 1 root root   14 10月  5 17:20 cmd*
     5  drwxr-xr-x 5 root root 4096 10月  6 11:26 list/
     6  drwxr-xr-x 2 root root 4096 10月  6 12:08 test.cc/
     7  drwxr-xr-x 2 root root 4096 10月  6 12:07 test.xy?/
     8  drwxr-xr-x 8 root root 4096 10月  6 12:06 tree/

5. 后台作业管理

&        在命令后加上此字符,命令将会在后台运行,并提供一个作业号

bg        命令运行过程中,使用Ctrl+z暂停,使用该命令将正在进行的作业转到后台

jods        列出正在后台运行的命令及作业号

ps -a        列出所有正在执行的所有前台和后台命令

notify        后接作业号,要求指结尾而定的命令完成后发送通知

fg        后接作业号,将指定的后台作业带到前台

kill        后接作业号,结束指定的后台作业

如果想要在指定时间运行命令,可以使用at命令,功能非常强大。

#将标准输出及错误输出送入null,并在后台运行,得到作业号为1
root@L-debian:/home/test# apt update >& /dev/null &    
[1] 12473

#列出后台作业号为1的相关信息
root@L-debian:/home/test# jobs
[1]+  已完成               apt update &> /dev/null

#结束作业号为1的后台作业
root@L-debian:/home/test# kill 1

6. 变量

#定义变量VAR,后接等号,不能加空格
root@L-debian:/home/test# VAR='What is your name?'
#引用变量时使用$符号
root@L-debian:/home/test# echo $VAR
What is your name?

可以使用反引号(位于Esc下方的~和`键),将一个命令执行的结果赋给变量

#先看一下ls的运行结果
root@L-debian:/home/test# ls
 cmd   dir   err   in   list   test.cc  'test.xy?'   tree

#使用反引号将ls的运行结果赋给VAR
root@L-debian:/home/test# VAR=`ls`
#调用VAR的结果
root@L-debian:/home/test# echo $VAR 
cmd dir err in list test.cc test.xy? tree

7. 脚本

如果将一系列shell命令保存在一个文本文件中,给这个文件赋予运行权限,就形成一个脚本。

脚本可以使用参数运行,其命令行的变量以"$"开头,按照顺序从1开始编号,比如$1,$2,$3。运行脚本时,也要按照对应顺序为变量赋值。

#新建脚本文件run
root@L-debian:/home/test# touch run

#编辑脚本文件,写入5条命令,两个变量引用
root@L-debian:/home/test# nano run
root@L-debian:/home/test/tree# cat run
echo ---------------
tree $1
echo ---------------
ls -R $2
echo ---------------

#向脚本文件赋予运行权限
root@L-debian:/home/test# chmod u+x run

#运行脚本文件,向$1变量传递参数tree,向$2变量传递参数tree
root@L-debian:/home/test/tree# ./run tree tree
---------------
tree
├── test.1
└── test.x

2 directories, 0 files
---------------
tree:
test.1  test.x

tree/test.1:

tree/test.x:
---------------

8. 控制结构

8.1 判定

控制结构必须对运行结果进行判断,才能达到控制的目的。

test命令可以判定命令执行结果,如下:

test A 判定选项 B

也可以使用 [ ] 进行判定,如下:

[ $var = 10 ]

无论是test命令还是 [ ] 的方式,都可以使用以下判定选项:

数值的判定选项如下:

-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
-eq 等于
-ne 不等于

字符串的判定选项如下:

-z  空字符串测试
=   字符串相等
!=  字符串不相等

逻辑运算的判定选项如下:

-a  逻辑与
-o  逻辑或
!   逻辑非

文件操作的选项如下:

-f  存在的文件,而且是一个规则文件
-s  非空文件
-r  可读文件
-w  可写和修改的文件可执行文件
-x  可执行文件
-d  文件名是目录名

#run.s内容如下:
ron@L-debian:~/test$ cat run.s 
read num
test $num -eq 10 
echo $?
ron@L-debian:~/test$ ./run.s 
10    #输入10,回车
0    #判定结果为真,返回0
ron@L-debian:~/test$ ./run.s 
20    #输入20,回车
1    #判定结果为假,返回0以外的数值

#使用[]判定示例如下:
ron@L-debian:~/test$ cat run.s1
read num
[ $num = 10 ]
echo $?
ron@L-debian:~/test$ ./run.s1
10
0

8.2 循环控制结构

循环控制结构的语句主要有下:

while 判定 do 命令 done        如果判定为真,执行循环

until 判定 do 命令 done        如果判定为假,执行循环

for 值 in 列表 do 命令 done        如果值在列表中,继续循环

#while用法示例
ron@L-debian:~/test$ cat loo.s
read i
while [ $i -lt 3 ]
do
        echo $i
        ((i++))
done
ron@L-debian:~/test$ ./loo.s
1
1
2
#until用法示例
ron@L-debian:~/test$ cat loo.s1
read i
until [ $i -lt 3 ]
do
        echo $i
        ((i--))    # (())内可以直接使用C语言命令格式
done
ron@L-debian:~/test$ ./loo.s1
5
5
4
3
#for用法示例
ron@L-debian:~/test$ cat loo.s2
read i
for i in {1..3}
do
        echo $i
done
ron@L-debian:~/test$ ./loo.s2
1
1
2
3

8.3 条件控制结构

条件控制结构的语句主要有下:

if 判定; then

        命令;

fi;

#判定为真,执行命令,判定为假直接退出

特别要注意:每一条命令的结尾一定要用;来声明本条命令结束

if 判定1;  then

        命令1;

else

        命令2;

fi;

#判定1为真则执行命令1,判定1为假则执行命令2

 

if 判定1;  then

        命令1;

elif 判定2; then

        命令2;

else

        命令3;

fi;      

#判定1为真则执行命令1,判定1为假则执行判定2,若判定2为真则执行命令2,若判定2也为假则直接退出

ron@L-debian:~/test$ cat if.s1
read i;
if [[ $i -gt 10 ]];  then
        echo $i is standard;
elif [[ $i -gt 0 ]]; then
        echo $i is less;
else
        echo $i is err;
fi;

#运行结果如下
ron@L-debian:~/test$ ./if.s1
11
11 is standard
ron@L-debian:~/test$ ./if.s1
10
10 is less
ron@L-debian:~/test$ ./if.s1
0
0 is err

case 变量 in

预设值1)

命令1;

;;

预设值2)

命令2

;;

……

esac

#逐项判定变量与预设值1、预设值2……是否一致,判定为真则执行对应命令。

ron@L-debian:~/test$ cat case.s 
read i;
case $i in
        11 | 12 | 13)
                echo $i 正常;
                ;;
        8 | 9 | 10)
                echo $i 偏小;
                ;;
        *)
                echo $i 错误;
                ;;
esac;

#运行结果如下
ron@L-debian:~/test$ ./case.s 
12
12 正常
ron@L-debian:~/test$ ./case.s 
8
8 偏小
ron@L-debian:~/test$ ./case.s 
-4
-4 错误

 9. 过滤器

grep可以用来搜索并显示搜索结果,也可以对其他输出结果进行过滤。其中涉及到一下规则表达式:

^        一行的开始

$        一行的结束

.        任何一个可能的字符

*        任何一个重复的字符

[]        字符集

示例如下:

#在以if.开头的所有文件里搜索if
ron@L-debian:~/test$ grep if if.*    
if.s:if [[ $i -gt 10 ]]; then
if.s1:if [[ $i -gt 10 ]];  then
if.s1:elif [[ $i -gt 0 ]]; then

#现有文件夹内容如下
ron@L-debian:~/test$ ls -laF
总用量 32
drwxr-xr-x  5 ron ron 4096 10月 11 12:09 ./
drwxr-xr-x 21 ron ron 4096 10月 10 18:06 ../
-rwxr--r--  1 ron ron  126 10月 11 11:26 case.s*
drwxr-xr-x  2 ron ron 4096 10月 11 12:08 dir1/
drwxr-xr-x  2 ron ron 4096 10月 11 12:09 dir2/
drwxr-xr-x  2 ron ron 4096 10月 11 12:08 dir3/
-rwxr--r--  1 ron ron   80 10月 11 10:45 if.s*
-rwxr--r--  1 ron ron  126 10月 11 10:59 if.s1*

#仅显示文件(文件以*结尾)
ron@L-debian:~/test$ ls -laF | grep $'*'
-rwxr--r--  1 ron ron  126 10月 11 11:26 case.s*
-rwxr--r--  1 ron ron   80 10月 11 10:45 if.s*
-rwxr--r--  1 ron ron  126 10月 11 10:59 if.s1*


#仅显示文件夹(文件夹以d开头)
ron@L-debian:~/test$ ls -laF | grep ^d
drwxr-xr-x  5 ron ron 4096 10月 11 12:09 ./
drwxr-xr-x 21 ron ron 4096 10月 10 18:06 ../
drwxr-xr-x  2 ron ron 4096 10月 11 12:08 dir1/
drwxr-xr-x  2 ron ron 4096 10月 11 12:09 dir2/
drwxr-xr-x  2 ron ron 4096 10月 11 12:08 dir3/

#仅显示文件夹(文件夹以/结尾)
ron@L-debian:~/test$ ls -laF | grep $'/'
drwxr-xr-x  5 ron ron 4096 10月 11 12:09 ./
drwxr-xr-x 21 ron ron 4096 10月 10 18:06 ../
drwxr-xr-x  2 ron ron 4096 10月 11 12:08 dir1/
drwxr-xr-x  2 ron ron 4096 10月 11 12:09 dir2/
drwxr-xr-x  2 ron ron 4096 10月 11 12:08 dir3/


 

总结

这里所整理的,仅仅是shell的皮毛。

 

你可能感兴趣的:(linux,debian,学习)