Unix shell学习笔记

[非常粗糙,没太多时间整理细致]

Shell指南笔记

文件安全与权限

目的就是设置文件和目录权限。顺便可以了解下UNIX文件管理方面的知识,比如文件属性等。

文件的访问方式分为:读写和执行,文件的用户分为文件属主,同组用户,其他用户。注意必须要理解这个区分。

1.1文件相关

系统当然知道文件的全部信息,通过ls命令可以获得想要的信息。这里就不解释ls输出的代表的意思了。

其实很重要,尤其是ls –l的表示rwxrwxrwx9个字符,每三个一组,分别对应ownergroupother组。

total—该目录占用的全部空间。

文件类型在ls –l最前面的那个标示,分为:

l         目录 d

l         符号链接 l

l         套接字文件 s

l         块设备文件 b

l         字符文件 c

l         命名管道文件 p

l         - 普通文件

可以用touch命令创建一个文件。创建的时候,不会自动附上执行权限。注意,目录的执行权限意思和文件不一样(其实就是浏览的功能)。

只读权限的文件可通过重定向方式写入,很奇怪。

那怎么修改权限位啊?命令是chmod

1. chmod

chmod格式有两类,一个是绝对模式,另外一个是长点的符号模式。

符号模式很简单,就是一些字符代表特定的含义。如 u/g/o/a +- rwxstl

绝对模式是用八进制数表示权限位。那么一个八进制位就可代表整个rwx的组合。

 

1.2 目录相关

目录的权限意思不太一样。

l         读权限表示可以列出其中内容

l         写权限表示可以创建文件

l         执行权限表示可以搜索和访问该目录。奇怪,访问目录和读的列出内容有啥区别?后面有个表格就说了,x是搜索或进入该目录。

另外,目录的权限会覆盖到目录文件中的权限。

另外,suidguid的作用。目的是如果属主设置了suid权限,那么其他用户在执行的时候也会自动获得属主的权限。有什么特殊情况需要这个呢?因为有些命令必须让用户以root权限执行,但又不能用root登陆。

如何设置就不说了,4对应suid2对应guid。如果都设置为6。位置在哪?对应权限位的前一位。实际上只能是设置u的位。

1.3 更改文件属主等命令

l         chown/chgrp。一旦交出所有权,将没办法要回来,只能管理员帮忙了。

l         找出其他用户所属组:groupFC11没有)

l         umask:掩码位,这个和0777~就得到真实的权限。这个对文件和目录还不太一样,反正知道是个反的意思即可。

1.4 符号链接

软链接就是一个快捷方式,硬链接不知道是什么,以后再说。链接的命令:

ln [-s] source_path target_path

其中,targetpath是链接名,sourcepath是真正的文件,这个地方很容易混淆。

findxargs命令

2.1 find

find命令用来查找,有些选项能够很强大。

find格式为:find path –option [-print, -exec,-ok]

后面的中括号中为一些可选项。

find选项很多,但我用的比较多的就是按名字查找,文件类型

-name, -type bdcplf –size 递归搜索用-depth

1. name选项

name选项 后跟文件名,可以为模式匹配,但是得用引号。

前面那个path是查找路径。

2. 其他

按时间选项,-mtime -5 表示更改时间在5天以内,+5表示5天以前。

实际在Win下很少用其他选项。

!表示非逻辑。size选项表示指定大小。Nc表示字节,大于用+,小于用-

3. depth

先查找本目录,再到子目录去查找之意。宽度优先。

4. exec

意思为找到后执行的命令。

find xxx –exec/-ok cmd {} / ; //必须是这种格式,好像不用加反引号。-ok是一种安全的方式,带提示的那种。

 

2.2 xargs命令

find在加exec的时候 是把找到的文件一起传给了后续的命令(FT,这样得有多少个参数啊),所以太多参数了有些命名没法处理。所以就出现了xargs命令。find将匹配结果传给xargs,而xargs根据配置(根据选项或者系统内核中的参数)来选择一个或一批结果来传递给后续的命令处理(这样就减少了参数个数)。

find xxx | xargs cmd

这么说,find+xargs确实非常方便。

 

后台执行命令

后台执行其实意味着没有终端也可以执行,或者那些和系统相关的(类型Win下的系统服务程序),可以设置定时执行。

3.1 cron

cron是系统的主要调度进程,用于无需人工干预的自动运行作业(例如自动更新程序),cron是个进程,他来运行任务,运行任务的信息由crontab添加到系统数据库中。

crontab也是一个文件,这里边每项条目就是一个要执行的任务。当然里边条目的列信息很重要。

1       2       3       4       5       6      

分钟小时日    星期 命令

1       22     30     3       3 copy 各个域空格分开。时间段可用,-来表示。

*表示任意。注释由#表示。

注意,后边的命令必须给出绝对路径,因为cron不清楚环境。

crontab –e –l –r

创建完毕后,一个副本在/var/spool/cron中,文件名就是用户名。

测试了下,还没见到它执行啊。每5分钟一次。

3.2 at命令

at命令用于向cron进程提交任务。指定一个时间,如果时间大于几天最好还是用crontab来做。

at命令不再多叙。

3.3 &后台运行

就是腾出一个终端出来可用干别的事情,最好重定向输入输出,否则后台运行的程序仍会把输出发到终端上来,这样很烦。

确实,例如后台运行gedit,老是输出到终端。

后台运行后,想要关掉它就得知道进程ID,一般用ps x命令查看。杀死一个进程用kill命令

kill – signal ID

有时候退出账户了进程还想继续运行,则需要用nohup command & 来实现这个功能。

 

文件名替换

其实说的是shell中的字符串模式匹配规则,这个非常重要。又叫元字符。

元字符:元的概念就是基本字符。类似元数据,就是能表示其他数据的数据。shell中哪些是元字符呢?*[][!]

l         *为任意字符串,包括空

l         ?单个任意字符

l         [...]匹配[]中所包含的任何字符,中间搞个-表示一个范围。

l         [!]匹配[]非!之后的字符

那么如果想表示元字符怎么处理?加上转义符号即可。/? /*等。

这一节内容较少,较详细的内容在后续章节。

 

shell的输入和输出

标准输入是键盘,标准输出是终端相关的屏幕,标准错误输出也是。一般来说能够接受标准输入的命令也可以接受文件做为输入。(这里的文件应该指的是文件的内容。)

5.1 echo & read

echo命令用得很多,一般能想到的控制就是换行/n,和不换行/c–n选项。类似printf

echo string中的string可以非常灵活,通过各种转义字符能执行很多功能。(linux下用-e选项使能转义字符)。

美元$号是特殊字符,包括``抑音符。

通过>(复写) >>(追加)重定向到文件。

echo是输出,read是从输入中读取信息并赋给一个变量。

这么看来,read后一定是一个什么东西来接收输入了,如果只有一个变量则一直输入到文件结束符未知。这么讲的话完全可以把一个文件的内容赋给一个变量。如果有多个变量的话,则输入的空格就是代表变量的切换。

 

5.2 cat

cat可用于显示文件内容,创建文件,显示控制字符。注意cat不会分页,它会一下把整个文件内容全部显示出来,所以只能你自己通过more等命令分页显示了。

cat默认不显示控制字符,通过选项-v来显示。cat f1 f2 f3...能一次显示多个文件。

一个窍门是可以用cat做简易的文本编辑器,cat >/>>filectrl+d结束输入即可。

5.3 管道

管道的作用,在这里正是说明是将一个命令的输出传递给另外一个命令做为输入。这个和重定向没有什么关系。但有功能相似之处,在具体命令上可能不能用重定向。例如

ls | grep “^[x]” 这么做是正确的,但 ls > grep “^[x]” 将错误,因为 > 后面的东西需要在ls中做为一个输出文件打开。这个显然是不能打开的。

 

5.4 tee

tee很形象,有两个输出,一个是标准输出屏幕,另一个是某个文件。

tee –a 表示追加。 who | tee who.out 即会输出到屏幕,又写道文件。如果是普通的>的话将只重定向到文件而没有屏幕输出。

5.5 标准IO和重定向

对应文件描述符是012,在重定向的时候对于文件描述符得用&表示。

command > file 2>&1,解释如此:先通过第一个>将标准输出重定向到file,这样1其实就转变为file了,然后将2重定向到1

可否 command > file 2>file? 这么做事OK的。为何2前面没有&??

command < &-关闭标准输入。

重定向输入比较少用。

sort  < name.txt 这样也行。

command << delimiter 这个其实想法很简单,就是2个分界符之间的内容作为输入的界限。

shell解释命令的顺序是从左到右,所以上面comm > file 2>&1 的这个1是可以直接代表file的。

5.6 exec

exec表示执行一个命令,但是不会启动子shell,而只是替代当前shell并且所有环境都会被清空。

暂时没搞清楚它的应用场景。似乎比较常用,在使用文件描述符上。再研究下例子。

shell的内建命令exec将并不启动新的shell,而是用要被执行命令替换当前的shell进程,并且将老进程的环境清理掉,而且exec命令后的其它命令将不再执行。
因此,如果你在一个shell里面,执行exec ls那么,当列出了当前目录后,这个shell就自己退出了,因为这个shell进程已被替换为仅仅执行ls命令的一个进程,执行结束自然也就退出了。为了避免这个影响我们的使用,一般将exec命令放到一个shell脚本里面,用主脚本调用这个脚本,调用点处可以用bash a.sh,(a.sh就是存放该命令的脚本),这样会为a.sh建立一个sub shell去执行,当执行到exec后,该子脚本进程就被替换成了相应的exec的命令。

source
命令或者".",不会为脚本新建shell,而只是将脚本包含的命令在当前shell执行。

不过,要注意一个例外,当exec命令来对文件描述符操作的时候,就不会替换shell,而且操作完成后,还会继续执行接下来的命令。

    exec 3<&0:这个命令就是将操作符3也指向标准输入。

终于看明白了例子了。原来是先保存再恢复的意思。

exec x<&- 关闭描述符

1 #!/bin/bash
   2 #
使用'exec'重定向标准输入.

3
   4
   5 exec 6<&0          #
文件描述符#6stdin链接起来
.
   6                    #
保存了
stdin.
   7
   8 exec < data-file   # stdin
被文件"data-file"所代替
.
   9
  10 read a1            #
读取文件"data-file"的第一行
.
  11 read a2            #
读取文件"data-file"的第二行
.
  21 exec 0<&6 6<&-
  22 # 
现在将stdinfd #6中恢复, 因为刚才我们把stdin重定向到#6
,
  23 #+
然后关闭fd #6 ( 6<&- ), 好让这个描述符继续被其他进程所使用
.
  24 #
  25 # <&6 6<&-   
这么做也可以
.
  26
  27 echo -n "Enter data  "
  28 read b1  #
现在"read"已经恢复正常了, 就是从stdin中读取
.
  29 echo "Input read from stdin."
有个奇特的地方,难道一定得区分标准输入和输出吗?因为><这两个符号用得很多,如果仅仅是保存作用的话,那么指定一个<符号不就OK了?

 另外一个例子,实现拷贝的。

不提供参数时,它将标准输入输出到标准输出;提供一个文件名参数时,将该文件输出到标准输出;提供两个文件名参数时,它将提一个文件复制到第二个文件。

#! /bin/sh

case $# in

    0)

        exec 3<&0 4>&1  #why这里要区分标准输入和输出啊

        ;;

    1)

        exec 3<$1 4>&1

        ;;

    2)

        exec 3<$1 4>$2

        ;;

    *)

        echo "Usage: `basename $0` [source [dest]]"

        exit 1

        ;;

esac

cat <&3 >&4

exec 3<&- 4<&-

exit 0

 

如何关闭文件描述符

n<&-

关闭输入文件描述符n.

0<&-, <&-

关闭stdin.

n>&-

关闭输出文件描述符n.

1>&-, >&-

关闭stdout.    

命令执行顺序

这个有很多内容吗?其实就是命令组合执行的。

C1&&C2 C1执行成功了才执行C2

C1 || C2 只有C1执行失败,C2才会执行。

如何在一个shell中执行多个命令。

l         在当前shell中执行一组命令,用(C1;C2;...)

l         如果用{C1;C2;...}将在子shell中一起执行。

这个{}方法还有点特殊,必须所有命令输出都被整体重定向时候才放到子shell中。

这个没搞清楚。

 

第十三 登陆环境

登陆的时候检查用户名和密码,这个是在/etc/passwd里边的。登陆成功后执行/etc/profile,第二个是.profile环境设置文件。有啥子用?

13 正则表达式

这个非常重要。关键是掌握模式匹配的规则。先介绍grep中的基本元字符。

元字符的含义掌握了,正则表达式差不多就如此了。

l         ^ 匹配行首,$匹配行尾

l         * 一个单字符后紧跟*,匹配0个或多个此单字符(有点不太一样,应该是后续任何字符都可以)

l         []

l         / 转义字符

l         . 匹配任意单字符

l         pattern/{n/}用来匹配前面pattern出现的次数,n为次数

l         pattern/{n,m/}同上,出现次数在nm

注意,没有?号表示,find中有?在grep中用.,而没有?,在其他中有?.是正则表达式,?是模式匹配,有点不一样的说。

匹配所有空行,用^$表示。

 

^放在[]中表示!的意思。[A-Za-z]*表示任意字母。

怎么感觉怪怪的?应该在后续章节里边大量测试。

grep

grep格式为 –option 表达式 文件。

关于引号的使用:一般字符串和变量都用双引号,如果是模式匹配则使用单引号。

选项比较多,关键看做什么。

例如:-c 输出匹配行技术,-n显示匹配行和行号等,-v显示不匹配行,关闭大小写敏感是-i

查询多个文件的话,看来对文件名也要用匹配方式了。

精确匹配/>是什么意思?

这些匹配模式不能做到非常精确,例如[48]表示4或者8或者48

grep使用与/或模式。加上-E选项,支持|表示或。还支持[[:upper:]]等类方式表示的模式匹配。

一些常用例子。egrepgrep的扩展命令程序,一个比较大的特征是用一个文件作为输入字符串,需要-f开关。

[]这个是匹配一个单字符的范围之意。

grep命令好像没什么,关键是正则表达式弄清楚了就好。

看来正则表达式还是需要花其他点时间仔细总结下的。

AWK介绍

awk是一个根据发明人的名字来命名的一种解释性语言。它的功能就是在文件或字符串中基于指定规则浏览和抽取信息,抽取信息后才能进行其他文本操作。

l         使用命令如下:awk [-F field-separator] ‘commands’ input-files 其中field-seperator:预分隔符,这个很重要啊,默认是空格

l         awk写成脚本文件,首行得是#!/bin/awk

l         awk调用awk脚本 awk –f awk-script-file inputfiles

awk解释是一行一行的,每一行通过域分隔符来区分域。有点像列表控件。

command分为模式和动作,模式决定如何动作,动作即对数据进行操作的意思。

模式中的两个特殊字段 BEGIN/ENDBEGIN语句使用在浏览动作之前,END用于完成浏览动作后打印输出,实际动作在{}指明,还可输入代码。

9.1 /etc/profile域和记录

此文件干啥用的?包括全局或局部环境变量,PATH信息。

13$1,$2awk解析出来的域,其中$0为所有域的意思。

9.2 $HOME/.profile正则表达式

这个是登陆后执行的,用户可以覆盖profile内定义的值。

修改成功后,通过.source命令来执行。

awk中的正则表达式用//括起来。

有几个地方比grep要多:

l         +匹配一个或多个

l         ?匹配模式出现的频率

还有些条件操作符,如<,<=,==,!=,>=,~(匹配正则表达式),!~

除了使用~外,还可使用if()语句,AND,OR,!判断等。

从它的几个例子来看,如果是字符串的话就用双引号,如果需要搞那种模式匹配的话就用//

 

9.3 内置变量及其他

内置变量可以很好得完成某些功能,如ARGC,ARGV,ENVIRON,FILENAME,FNR,FS等。

awk可定义变量名。直接定义并赋值即可,例如name=$n;belts=$2,中间和最后得用分号隔开。

l         NR:已经读取的记录条数(一行是一个记录)

l         NF:每行的域个数,$NF是最后一行最后一个域的值

注意,任何awk修改的只是复本,原输入文件不会修改。

修改数值域,修改文本域,创建新域,内置字符串函数等操作,这里不讲了。

后边的内置字符串函数,数组等内容不再讲述,否则东西太多了,相当于又学习了一门新语言。

sed

sed是一个非交互的文本流编辑器。sed并不修改源文件,所以只能你自己保存修改后的文件了。由于是非交互式的,所以得告诉sed的行号或匹配模式好让他知道处理什么内容。

sed –p 命令 文件,实际命令要加单引号,和awk很像。

sed定位文本的方式为

l         指定行号xx,y

晕,就是一个非交互式的文本编辑器,功能得差不多和交互式的,不过完全是用命令来做罢了。有难度。

sed命令一般用途是修改或删除文件或字符串中的文本。

先不讲述了。

十一 合并与分割

处理文本文件分类,合并和分割。

11.1 sort系列命令

sort选项太多了。就是向列表控件那样排序的功能。它的列表域从0开始。如果要按数值来排序则要指定-n,否则就按字母排序了。按指定域的话用 –kn来表示。这个时候列表域从1开始与awk一样。

headtail命令显示头或尾的几行。

实际sort是排序,排序完了可以对几个文件进行合并。

uniq命令,uniq去除连续重复行,而sort去除所有重复行。

join命令,将几个排序文件行连在一起。

cut/paste命令

split拆分文件。

 

十二 tr命令

tr用来替换或删除操作进行字符替换,主要用于删除文件中控制字符或进行字符转换。用法:

tr –c –d –s “s1” “s2” file

这个s1s2的有要求。s1模式转换成s2模式。如 tr “[a-z]” “[A-Z]” 从小写转换成大写。

 

 

 

十四 环境变量和shell变量

14.1 本地变量

本地变量为用户现在的shell生命期脚本中使用,使用时候尽量用花括号弄起来。设置时候用:

V1=value/${V1},等号两边可有空格,如果取值含空格,则需用双引号引起来。变量设置的不同模式:

=/+/:?/?/:=/:-等,用echo命令通过$显示变量取值。用unset消除变量。变量并排可以结合变量。${V1}${V2}。有什么用?

关于echo这个双引号或者$问题,如果是变量,则用花括号即可,如果是值的话,最好加双引号。

l         测试变量是否赋值:v1:-value意味如果v1存在则使用旧值,否则用value,但是不赋值。

l         v1:=value,这个当v1不存在的时候会赋新值

l         v1:+value,如果未设置则返回空串

设置只读变量,利用readonly v1命令。

 

14.2 环境变量

环境变量和一般变量无二,但环境变量能在所有子进程中使用,所以需要通过export命令导出环境变量。

l         env显示所有环境变量

l         unset清除环境变量

l         set –a 将脚本中的所有变量全部导出(相当于每变量写一个export语句)

另外,export的另外一个作用就是导出的变量能在子脚本中使用。

export导出的作用还不仅仅是环境变量。应该这么理解,export导出的东西在所有脚本中都可以使用,但是要使得成为环境变量,还得调用source命令进行处理。

14.3 位置变量和特定变量参数

shell变量共分四种:

l         一般变量(本地变量)

l         环境变量(可以认为是全局变量)

l         位置变量,即$0,$1等等

l         特定变量,见后续讲解

shell中没有类似main(int argc,char*argv[])这些表示外界传入参数的东西,但是它有自己的表示方法,这就是位置变量参数。

l         shell脚本的参数可以任意多,但只有前9个可以被访问,后续的必须通过shift命令来访问,前9个分别是$0.$1...$8,$9其中$0默认都是脚本文件的名字。参数间以空格隔开

1.特定变量

7个特定变量(其实就是有他特殊含义的变量)。

l         $#:传递到脚本的参数个数

l         $*:以一个单字符串显示所有脚本参数,可超过9个(就是一个参数列表字符串,无附加引号)

l         $$:当前进程ID

l         $!:后台运行的最后一个进程的ID

l         $@:与$*相同,但使用时加引号,在引号中返回每个参数(每个参数都有引号)

l         $-:显示shell当前使用的选项,与set命令功能相同

l         $?:显示脚本退出返回值,0表示正确

十五 引号

确实,shell中引号到底怎么用,用法是什么需要特定强调一下。

分为双,单,反引号和反斜线。

15.1 双引号

双引号可引用除$,`,/外的任意字符或字符串(也就是说,双引号里边的内容如果包含这三个特色符号的话,shell将按特殊符号处理)。

15.2 单引号

单引号忽略如何引用(即忽略任何特殊字符)

15.3 反引号

shell将反引号中的内容做为一个系统命令,也就是说会先执行这个命令,将它的结果作为其他命令的输入。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 什么是shell脚本Shell脚本是一种编程语言,它是在Unix和Linux操作系统中使用的一种脚本语言。它可以帮助用户自动化任务,并且可以运行一系列命令。 Shell脚本通常以.sh扩展名结尾。 2. 为什么要学习shell脚本学习shell脚本可以帮助你自动化任务,提高工作效率。Shell脚本也可以帮助你编写小工具,方便你自己或其他人使用。Shell脚本还可以帮助你更好地理解Linux和Unix操作系统。 3. 如何编写一个简单的shell脚本? 首先,在命令行中输入命令nano test.sh,创建一个名为test.sh的文件。然后,在文件中输入以下内容: #!/bin/bash echo "Hello World" 接着,按下Ctrl + X,然后按下Y,最后按下Enter,保存并退出文件。接下来,您需要在命令行中输入以下命令: chmod +x test.sh ./test.sh 这将使test.sh文件可执行,并运行脚本。在命令行中,您应该看到输出“Hello World”。 4. shell脚本中的注释是什么? 注释是用于向脚本中添加说明和文档的文本。在Shell脚本中,注释以“#”开头。注释不会被脚本解释器执行,但可以帮助其他人更好地理解脚本。 5. 如何在shell脚本中使用变量? 变量是一个用于存储值的占位符。在Shell脚本中,您可以使用以下语法来定义变量: my_variable="Hello World" 您可以使用echo命令来输出变量的值: echo $my_variable 6. 如何在shell脚本中使用条件语句? 在Shell脚本中,您可以使用条件语句来执行基于条件的操作。以下是一个示例条件语句: if [ $my_variable = "Hello World" ] then echo "The variable contains Hello World" else echo "The variable does not contain Hello World" fi 7. 如何在shell脚本中使用循环? 在Shell脚本中,您可以使用for循环或while循环来执行重复的操作。以下是一个示例for循环: for i in 1 2 3 4 5 do echo $i done 以上代码将输出数字1到5。 8. 如何在shell脚本中使用函数? 在Shell脚本中,您可以使用函数来组织和重复使用代码。以下是一个示例函数: function say_hello { echo "Hello World" } 您可以通过以下方式调用函数: say_hello 9. 如何从shell脚本中读取用户输入? 在Shell脚本中,您可以使用read命令来从用户那里读取输入。以下是一个示例: echo "What is your name?" read name echo "Hello $name" 以上代码将提示用户输入他们的名字,并输出“Hello”后跟用户的名字。 10. 如何在shell脚本中使用命令行参数? 在Shell脚本中,您可以使用$1、$2、$3等变量来访问命令行参数。例如,以下是一个示例脚本,它接受两个命令行参数并将它们相加: #!/bin/bash sum=$(($1 + $2)) echo "The sum of $1 and $2 is $sum" 您可以使用以下命令来运行脚本并传递两个参数: ./test.sh 2 3 以上代码将输出“The sum of 2 and 3 is 5”。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值