小编在最近的测试过程中遇到了一个由于Linux权限问题导致测试用例验证失败的情况,正好借此机会和大家一起熟悉一下Linux权限相关知识。
为了解决某个问题,开发大大在某次迭代中加入了如下逻辑:当应用的私有目录下的A文件损坏时,程序自动从应用携带的资源文件中复制出同名的文件来替换损坏的文件,这就需要小编模拟A文件损坏的情况下程序能否正常执行完成替换动作。由于在
adb
中不方便直接修改文件内容,所以小编采取的方式是创建一个损坏的文件并使用adb
的root
账户将文件从/sdcard
下移动到目标路径/data
目录下,但这时的APK应用并不能完成预想的逻辑。由于改动非常简单,review
过代码发现没有什么问题,于是猜测可能是权限问题导致文件更新失败。 查看移动进去的文件权限如下:
而其他由应用程序自动创建创建的文件权限是:
可以看出不论是权限还是拥有者或组名都不一致,于是通过命令将新移动的文件权限和拥有者进行修改与其他文件一致,这时候再进行测试就可以验证通过了。
安卓是基于Linux内核的系统,它的权限管理和Linux基本一致。
r
、w
、x
。权限的粒度有拥有者、群组、其它组(u
、g
、o
)三种。每个文件都可以针对三个粒度,设置不同的r
、w
、x
权限。通常情况下,一个文件只能归属于一个用户和组,如果其它的用户想有这个文件的权限,则可以将该用户加入具备权限的群组,一个用户可以同时归属于多个组。rwx
权限配置情况,最高位代表r
权限的有无,第二位代表w
权限的有无,最低位代表x
权限的有无。换算为十进制时最高位有的话就是数字4,第二位有的话就是数字2,最低位有的话就是数字1。所以针对某一粒度设置他们的权限时可以使用一个累加的十进制数字表示,比如要同时设置rwx
(可读可写可运行)权限则将该权限位设置为4+2+1=7
;要同时设置rw-
(可读可写不可运行)权限则将该权限位设置为4+2=6
;要同时设置r-x
(可读可运行不可写)权限则将该权限位设置为4+1=5
。chmod [-cfvR] [--help] [--version] mode file...
其中:
u
表示该文件的拥有(owner
),g
表示与该文件的拥有者属于同一个群体(group
)者,o
表示其他以外(other
)人,a
表示这三者皆是。
+
表示增加权限、-
表示取消权限、=
表示唯一设定权限。
r
表示可读取,w
表示可写入,x
表示可执行,X
表示只有当该文件是个子目录或者该文件已经被设定过为可执行。
其他参数说明:
-c
:若该文件权限确实已经更改,才显示其更改动作
-f
:若该文件权限无法被更改也不要显示错误讯息
-v
:显示权限变更的详细资料
-R
:对目前目录下的所有文件与子目录进行相同的权限变更(即以递回的方式逐个变更)
--help
:显示辅助说明
--version
:显示版本
比如设置a文件为所有人都可读取就是chmod ugo+r a
,或者是使用数字标识权限格式chmod 444 a
,但是这两种方式的结果不同,前一种是针对a
文件给ugo
追加了读权限,后一种是给ugo
只设置了读权限,可能影响ugo
本来就拥有的权限。chown [-cfhvR] [--help] [--version] user[:group] file...
其中 :
user
: 新的文件拥有者的使用者ID
group
: 新的文件拥有者的使用者组(group)
-c
: 显示更改的部分的信息
-f
: 忽略错误信息
-h
:修复符号链接
-v
: 显示详细的处理信息
-R
: 处理指定目录以及其子目录下的所有文件
--help
: 显示辅助说明
--version
: 显示版本
比如将文件a
的拥有者设为ownerx
,群体的使用者设置为groupx
:chown ownerx:groupx a
;
使用这个命令可以看到文件的详细信息,其中第一个字段就是代表的文件属性字段,该字段共有10个字母组成,其中第一位代表的是文件的类型,类型可以是以下几种中的一个:
d
代表的是目录(directroy
)
-
代表的是文件(regular file
)
s
代表的是套字文件(socket
)
p
代表的管道文件(pipe
)或命名管道文件(named pipe
)
l
代表的是符号链接文件(symbolic link
)
b
代表的是该文件是面向块的设备文件(block-oriented device file
)
c
代表的是该文件是面向字符的设备文件(charcter-oriented device file
)
而剩下的九位就代表的是上面说到的文件的权限,其中前三个表示文件所有者的权限,中间三个表示组用户权限,最后三个表示其他用户权限。
SET
位权限(suid
,sgid
)和粘滞位权限(sticky
)。这里主要介绍Linux的基本权限,关于附加权限就不过多展开解释了。再回头看小编遇到的那个问题就可以很简单的定位原因了:应用程序自动创建的文件使用的用户名是
u0_a1996
,组名是u0_a1996
,而使用root
账户创建的文件的所有者是root
,所属组名是sdcard_rw
,root
账户及sdcard_rw
组对文件拥有读写权限,但是其他组对文件没有读写权限,所以应用程序更新损坏文件失败了。 解决办法主要有三种,第一种方法是修改应用程序的用户组,加入到sdcard_rw
组中,第二种方法是修改文件的其它组权限同样为可读可写,第三种方法就是修改文件的拥有者或者是所属组。采用任意一种方法都能够解决问题。 最后在测试过程中还发现当使用root
账户向/data
目录下cp
文件时会保留原路径下文件的权限及所属关系,但是当使用mv
命令时则会将源文件的所有权限及所属关系属性全部移动过去,所以上面构造测试数据时使用cp
命令也可以避免权限问题的出现。