Linux | 文件的目录和权限 / Shell的基本机制

Linux专栏主要系统介绍了在Linux的开发和应用过程中所需要的各种基础知识和相关命令,共分为七部分。 

1.  Linux | 系统状态查看 / 文本文件处理命令_菜鸟的人工智能之路的博客-CSDN博客

2.  Linux | 正则表达式和相关概念_菜鸟的人工智能之路的博客-CSDN博客

3.  Linux | 文件比较 / vi编辑与使用 / 文件通配符_菜鸟的人工智能之路的博客-CSDN博客

4.  Linux | 文件管理 / 目录管理_菜鸟的人工智能之路的博客-CSDN博客

5.  Linux | 命令风格 / 文件系统_菜鸟的人工智能之路的博客-CSDN博客

6.  Linux | 文件的目录和权限 / Shell的基本机制_菜鸟的人工智能之路的博客-CSDN博客

7.  Linux | 替换 / 元字符 / 转义_菜鸟的人工智能之路的博客-CSDN博客

文章目录

1 文件和目录的权限

1.1 文件的权限

1.2 目录的读写权限

(1)目录读写执行权限

(2)权限验证的顺序

1.3 权限相关命令

(1)使用 ls 命令

(2)chmod 修改权限

(3)umask 控制文件/目录的初始权限

1.4 SUID权限

(1)三级权限存在的问题

(2)策略和机制相分离

2 Shell的基本机制

2.1 shell概述

(1)shell种类

(2)shell功能

(3)shell特点

(4)学习bash的目的

2.2 bash的启动

(1)三种启动方法

(2)自动执行的一批命令

(3)脚本文件

(4)脚本文件的执行

2.3 历史与别名

(1)历史表和历史替换

(2)别名和别名替换

(3)TAB键补全

2.4 输入重定向

2.5 输出重定向和管道

(1)程序的标准输入/输出

(2)stdout输出重定向

(3)stderr输出重定向

(4)管道


1 文件和目录的权限

1.1 文件的权限

用于控制进程对系统的文件和目录的访问

权限的三个级别

  • 文件主,同组用户,其他用户
  • 每个文件有唯一的属主

普通文件的权限

  • 读、写、可执行
  • 不可写的文件也可能会被删除

两类可执行文件

程序文件(可执行文件)

  • 二进制的CPU指令集合,满足操作系统规定的格式才可以被加载运行。

脚本文件

  • 里面存储文本文件。
  • 默认的解释程序为/bin/sh。
  • 可以在文件的第一行自行指定解释程序(必须是第一行,#! 必须是这个文件首先出现的两个字符)。例如:#! /bin/bash   说明该脚本利用bash进行解释;#! /usr/bin/bc。
  • 解释程序也可以是用户自己编写的应用程序。
  • 脚本程序运行时,实际上是由解释程序创建一个进程。

1.2 目录的读写权限

(1)目录读写执行权限

读权限

  • 如果目录无读权限,那么“目录表”文件不允许读,ls会失败。

写权限

  • 若无写权限,那么“目录表”许写。
  • 创建文件,删除文件,文件改名会修改目录文件。
  • 修改文件不需要修改目录文件,需要修改i节点。
  • 目录无写权限不是指目录下所有文件禁止写(目录没有写的权限和目录下的文件的权限没有直接关系)。

执行权限

  • 有执行权限意味着分析路径名过程中可检索该目录。
  • cat  /a/b/c  要求/a,a/b三目录均有x权限,c文件有读权限;否则,命令执行失败。
  • cd  ../st8 要求当前目录,..和st8必须有x权限。

(2)权限验证的顺序

  • 每个文件都有文件主和组的属性(文件节点中)
  • 每个进程也有进程主和组的属性(进程PCB中)

这4个属性都是整数,uid和gid的编号与名字对应关系见 /etc下passwd和group文件。需要注意的是超级root用户不会收到权限的制约。

1)文件主与进程主相同

  • 使用文件主权限;不再查组和其他用户的权限。

2)文件主与进程主不同,但文件主与进程主同组

  • 只使用组权限,不使用关于其他用户的权限。

3)文件主与进程主不同,文件主与进程主又不同组

  • 使用文件关于其他用户的权限。

1.3 权限相关命令

确定文件的权限

(1)使用 ls 命令

有关选项 -l 和 -d

  • 例如:ls -l  可以查看当前目录下所有文件和子目录的权限
  • ls  -ld  .    列出当前目录自身的权限

(2)chmod 修改权限

1)字母形式

chmod  [ugoa]  [+-=][rwxst]  文件名表

  • u--user       文件主的权限
  • g--group    同组其他用户的权限
  • o--other     其他用户权限
  • a--all         所有上述三级权限

例如:chmod  go-rwx  *.[ch]     对于所有的.c或者.h文件,对于同组和其他用户都不允许读、写和执行。

chmod  a+x  batch   对于batch文件,对于所有用户均允许执行。

2)数字形式(八进制数字)

例如:chmod  644  xyz1  xyz2

八进制644
二进制110100100
权限rw-r--r--

注意:只允许文件主和超级用户修改文件权限。

(3)umask 控制文件/目录的初始权限

功能:决定文件/目录的初始权限

  • 用vi新建文件
  • 用输出重定向创建文件
  • 创建新目录

umask是进程属性的一部分

  • umask是shell内部命令
  • umask是进程属性的一部分

命令

  • umask           打印当前的umask值
  • umask  022   将umask值设置为八进制的022

掩码值的含义

  • umaxk 022 (000 010 010)  //取消新文件和新目录的组w权限和其他用户w权限。
  • umask 077  //禁止组权限和其他用户权限(unmask对应比特1处的权限被屏蔽掉)。

系统调用umask

初始文件的权限

  • 受open的规定值和进程自身属性umask值影响。
  • 已存在的文件的权限,不受open/umask的影响。例如:当umask为077时,用C程序fd=open(filename, O_CREAT|O_WRONLY, 0666);open的权限为0666,利用umask屏蔽掉077后实际为0666。
  • 这样可以在创建文件的时候指定文件的权限,或者在后续进程处理过程中通过umask()修改权限。

int umask(int mask);

  • mask为指定的新umask值,返回值为原先的umask值。
  • 读出进程umask属性而不改变它,需调用umask两次。

1.4 SUID权限

(1)三级权限存在的问题

系统中任一用户,要么对文件的全部内容具有访问权,要么不可访问文件。有的情况下,很不方便。

用户Liu的文件list.txt:希望用户Liang只能读取行首为 # 的行和与他有关的行。这样的话利用三级权限会面临困难,具体怎么解决该问题:

(2)策略和机制相分离

文件list.txt的文件主Liu给文件query增加SUID权限

  • $ chmod  u+s  query
  • $ ls  -l  query
  • -rws--x--x  1  liu  leader  56134  Dec  10  23:07  query

进程的实际UID和有效的UID

  • 一般情况下,进程的实际UID和有效的UID相等。有效UID是用来进行权限判断的,实际UID是用于记账和其他操作。
  • 打开文件open()时,系统根据进程的有效UID,与文件所有者UID之间的关系和文件的权限进行访问合法性验证。
  • 可执行程序具有SUID权限,进程的实际UID和有效UID不再相等。实际UID是当前用户,而有效UID为可执行文件的文件主。
  • SUID使得用户可以通过文件主提供的程序,以文件主的权限访问文件,但这种访问依赖文件主提供的程序,进行有限的访问。

例如某个用户有下述文件,但里面有些信息不想让别人访问到,可以做下述处理:

ls -l list.txt  //查看文件的权限
-rw------  1  liu ....  //文件只能是所有者自己读写,
//但实际中需要其他用户也可以访问文件中的部分信息
需要写一个程序query处理只能访问一个文件中的部分信息
chmod u+s query  //给文件赋予suid权限

2 Shell的基本机制

2.1 shell概述

kernel和shell

  • kernel指内核,是操作系统内部资源管理的一些程序。内核里面的程序允许在CPU的特权状态。
  • shell指外壳,相对于CPU内核而言shell是应用程序中的一部分(对于CPU而言,编译程序等都是它的应用程序)。

(1)shell种类

  • B-shell:/bin/sh. 由Stephen R. Bourne在贝尔实验室开发,值最早别认可的shell,早期UNIX的标准shell。
  • C-shell:/bin/sch 由加利福尼亚大学的William N. Joy 在20世纪70年代开发,最初用在BSD2.0。
  • K-shell:Korn shell,/bin/ksh 贝尔实验室的David Korn在1986年开发。是B-shell的超集,支持带类型的变量,数组。
  • /bin/bash:Bourne Again shell,是linux上的标准shell,兼容 Bourne shell,扩展了B-shell,吸收了C-shell的某些特点。交互式使用时命令行编辑非常方便。

(2)shell功能

  • shell 是命令解释器(每读一行处理一行)。
  • 文件名替换,命令替换,变量替换。
  • 历史替换,别名替换。
  • 流程控制的内部命令(内部命令和外部命令)。

(3)shell特点

  • 主要用于批处理,执行效率比算法语言低。
  • shell编程风格和C语言等算法语言是有区别的。
  • shell是面向命令处理的语言,提供的流程控制结构通过对一些内部命令的解释实现。
  • 同C语言设计思路一样,shell本身的设计非常精炼,但是它提供了灵活的机制(策略与机制相分离)。
  • shell许多灵活的功能,通过shell替换实现。例如:流程控制多需要的条件判断,四则运算,都由shell之外的命令完成。

(4)学习bash的目的

  • 交互方式:熟悉shell的替换机制、转义机制,掌握循环等流程控制,可以编写复合命令。
  • 非交互方式:编写shell脚本程序,把一系列的操作,编纂成一个脚本文件,批量处理。

需要了解的shell知识

  • 重定向与管道。
  • 方便交互使用的功能:历史替换与别名替换。
  • shell变量。
  • shell的变量替换,命令替换,文件名替换。
  • 元字符,如:单引号,双引号。
  • 流程控制。
  • 子程序。

2.2 bash的启动

(1)三种启动方法

  • 注册shell:注册shell
  • 键入bash命令:交互式shell
  • 脚本解释器

(2)自动执行的一批命令

用户偏好

  • 当bash作为注册shell被启动时:自动执行用户主目录下的.bash_profile文件中的命令,~/.bash_profile或$HOME/.bash_profile。当bash作为注册shell退出时:自动执行$HOME/.bash_logout
  • 当bash作为交互式shell启动时:自动执行$HOME/.bashrc。
  • 可以把类似umask之类的文件,应当写在.bash_profile文件中,在每次启动时都会被执行。

系统级(系统均需要执行,执行时机比用户偏好要早)

  • 当bash作为注册shell启动时:自动执行/etc/profile文件中的命令。
  • 当bash作为交互式shell启动时:自动执行/etc/bash.bashrc。
  • 当bash作为注册shell退出时:自动执行/etc/bash.bash.logout。

(3)脚本文件

编辑文件 lsdir(格式为文本文件,文件名不必须为.sh后缀,只是个惯例),具体脚本代码如下所示:

if [ $# = 0]   #判断命令行参数个数是否为零
then
    dir=.
else
    dir=$1     #赋值为命令行第一个参数
fi
#将所有属性是目录的项目打印出来,打印指定目录下的目录树
find $dir -type d -print
echo '------------------'
cd $dir
pwd

(4)脚本文件的执行

新创建子进程,并在子进程中执行脚本

  • <1> bash < lsdir  相当于重定向的操作,启动新的bash进程从lsdir文件里面获取数据输入,然后进行逐行解释。无法携带命令行参数。
  • <2> bash lsdir
  • bash -x lsdir    每执行一行命令,将命令打印出来。可以看到脚本的执行轨迹。
  • bash lsdir /usr/lib/gcc
  • <3> 给文件设置可执行属性x:chmod u+x lsdir  然后执行 ./lsdir  /usr/lib/gcc

上面的三种方法,都需要启动程序/bin/bash,生成新进程。

在当前shell进程中执行脚本

  • .  lsdir  /usr/lib/gcc   命令中.后的空格表示在当前的shell中执行lsdir脚本
  • source  lsdir  /usr/lib/gcc   意思同上,但是可读性好点

2.3 历史与别名

(1)历史表和历史替换

历史表大小

  • 先前键入的命令存在于历史表,编号递增,FIFO刷新。
  • 表的大小有变量HISTSIZE设定。
  • 修改HISTSIZE的配置应该放入 ~/.bashrc (该文件是系统启动时自动执行)

查看历史表

  • 使用内部命令hisroty。(文件$HOME/.bash_history中存储历史表)

历史替换

1)人机交互时直接使用上下箭头键,调出曾经使用过的命令。

2)其他引用历史机制的方法。

  • !! 引用上一命令
  • !str  以str开头的最近用过的命令,如 !v  !m  !.

(2)别名和别名替换

在别名表中增加一个别名(内部命令alias),如果需要,应把alias命令放入 .bashrc 中。

alias h="history"
alias p='ping 202.123.23.124'
alias rm='rm -i'   #命令重载
alias dir="ls -flad"

(3)TAB键补全

使用TAB键可以补全后续单词,同时可以使用上下键进行滚动选择。

1)补全每行的首个单词

  • TAB键补全搜索$PATH下的命令

2)补全行中的其他单词

2.4 输入重定向

输入重定向,指从数据文件中获取stdin。

(1)<filename

从文件filename中获取stdin,例如:sort < telno.txt    #表示从文件中获取排序数据,不再通过交互式输入获取。

(2)<<word

从shell脚本文件获取数据直到再次遇到定界符word。换言之就是遇到word之后停止。

定界符所界定内容加工处理(等同双引号处理):

  • 变量替换,命令替换
  • 不执行文件名生成

从shell脚本程序获取数据直到再次遇到定界符,定界符两侧加单引号:不允许定界符之间的内容进行替换操作。

(3)<<<word

base64 <<< nohavepasswd   #将后面的字符变为base64编码格式,也就是<<<后面的所有信息作为命令的输入。

base64 <<< 'no have passwd'

Now : `date`
My Home Dir is $HOME
#执行替换和运行的结果为
Now : Tue Dec 4 12:32 CTS 2020
My Home Dir is /home/li

2.5 输出重定向和管道

(1)程序的标准输入/输出

fd是对应的文件描述符,stdin是标准输入,stdout是标准输出。

 使用系统调用(原始I/O)的程序实例

//使用原始I/O方式
int main(void) {
    static char *str1 = "string1\n";
    static char *str2 = "string2\n";
    for (int i = 0; i < 10; i++) {
        write(1, str1, strlen(str1));
        write(2, str2, strlen(str2));
    }
}

使用C语言里面库函数(缓冲I/O)的程序实例

//FIFE类型的变量stdin, stdout, stderr
//使用缓冲I/O
int main(void) {
    static char *str1 = "string1\n";
    static char *str2 = "string2\n";
    for (int i = 0; i < 10; i++) {
        printf("%s", str1); //或 fprintf(stdout, "%s", str1);
        fprintf(stderr, "%s", str2);
    }
}

(2)stdout输出重定向

>filename

将stdout重定向到文件filename,文件已存在则先清空(覆盖方式清空)。

>>filename

将stdout重定向追加到文件filename尾部。

(3)stderr输出重定向

2> filename

将文件句柄2重定向到文件filename。(将错误输出信息也从定向到文件中)

分离stdout与stderr的意义:正常情况一般是重定向到一个文件当中,使用stdout就行,但是有时候可能在重定向的过程中出现错误,这时候需要将错误信息打印出来以方便程序员查看。

2>&1

将文件句柄2重定向到文件描述符1指定的文件。也就是将stdout和stderr重定向合并。

允许对除0,1,2外其他文件句柄输入或输出重定向,例如:

  • ./myap 5< a.txt 6> b.dat   //在myap程序运行过程中,5号文件不用打开,直接从a.txt中读取;6号文件输出到b.dat文件中。
  • gcc try.c > try.err 2>&1     //将标准输出以及标准错误输出都重定向到文件try.err中。
#使用原始I/O方式。文件名为stda
int main(void) {
    static char *str1 = "string1\n";
    static char *str2 = "string2\n";
    for (int i = 0; i < 10; i++) {
        write(1, str1, strlen(str1));
        write(2, str2, strlen(str2));
    }
}
#对于该程序直接执行 ./stda 会输出标准输出和标准错误输出
#使用重定向可以仅仅打印出标准错误输出,将标准输出定向到文件中
./stda > stda.out
#同时将标准错误信息定向到文件stda.err
./stda > stda.out 2> stda.err

./stda > rpt 2>&1

刚开始1和2号文件指向终端,0号文件指向键盘;第一个 > 操作之后,将1号文件的指向变为rpt;后面的2>&!标志2号文件的指向和1号文件一样,都是rpt。

(4)管道

管道只是把标准输出重定向到后面的命令输入中,对于标准错误输出没有进行重定向。如果需要将标准错误输出(2号文件)也定向都后面,需要增加 2>&1。

  • gcc try.c 2>&1 | more   #more作用是当输出的错误信息满一屏之后就停止,但是如果没有 2>&1 的话,只是保证标准输出信息受more的控制,对于标准错误输出信息不受more控制。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值