查找目录或文件的所有者,但仅返回该目录或文件的所有者


62

我正在寻找一个仅返回目录所有者的命令-例如解析该ls -lat命令的正则表达式或类似的东西?我想在另一个脚本中使用结果。

Answers:


102

statGNU coreutils可以做到这一点:

stat -c '%U' /path/of/file/or/directory

不幸的是,有许多版本stat,并且它们的语法没有很多一致性。例如,在FreeBSD上,

stat -f '%Su' /path/of/file/or/directory

如果需要考虑可移植性,那么最好使用Gilles提出的合并ls的建议awk。它必须启动两个进程而不是一个进程,但是它具有仅使用POSIX标准功能的优点:

ls -ld /path/of/file/or/directory | awk '{print $3}'

2
stat -c%U / path(如果简短是一种奖励)。
tsvallender 2011年

1
假设使用GNU stat,而在较旧的Linux系统上则不是这样(即使在较新的系统上,我也会警惕,用户家stat/usr/local/bin或某处可能存在其他(站点范围的标准)),并且很少有在其他联合国上。
吉尔斯

1
stat -c %U有也有工作的优势BusyBox的,如果stat命令在编译。
吉勒·

1
很好,最后一个示例(ls)在Unix / OSX和Linux上
均可使用

1
需要注意的是LS将打印UID,如果有匹配的所有者(即网络共享)没有任何本地用户,而是stat -c '%U' DIR将打印UNKNOWN,这是帮助较小或较为合适,这取决于你如何看待它。
2014年

18

解析输出ls很少是一个好主意,但是获取前几个字段是一个例外,它实际上适用于所有“传统”的unices(不适用于某些平台,例如某些Windows实现中允许在用户名中留有空格)。

ls -ld /path/to/directory | awk 'NR==1 {print $3}'

另一个选择是使用stat命令,但是stat从shell来的问题是有多个具有不同语法的命令,因此stat在shell脚本中是不可移植的(即使在Linux安装中也是如此)。

请注意,测试给定用户是否为所有者是另一种主张。

if [ -n "$(find . -user "$username" -print -prune -o -prune)" ]; then
  echo "The current directory is owned by $username."
fi
if [ -n "$(find . -user "$(id -u)" -print -prune -o -prune)" ]; then
  echo "The current directory is owned by the current user."
fi

ls | awk不幸的是,正如我在此处指出的那样,这种方法有些警告。我在最近的评论中提到的“目标文件/目录是一个具有不同名称的符号链接”的解决方案尚未解决。
beporter

而不是find . -user "$username" -print -prune -o -prune您只能这样做find . -maxdepth 0 -user "$username"
Niklas Holm

@Gilles您使用什么原因awk 'NR==1 {print $3}'而不是仅仅使用awk '{print $3}'?我不确定为什么在NR==1这里有必要。
Harold Fischer

1
@HaroldFischer仅在路径包含换行符的极端情况下。几乎没有必要,但永远不会有害。
吉尔斯

@吉尔斯非常高兴知道!只是好奇,您是否知道ls某个路径中的换行符导致该行拆分为两行的实现(我认为这是您要覆盖的边缘情况)?上GNU ls(新望版),BusyBox的ls和FreeBSD ls换行符返回为$'\n'??分别。
哈罗德·菲舍尔

9

一个人也可以用GNU查找来做到这一点:

find $directoryname -maxdepth 0 -printf '%u\n'

这不能移植到GNU系统之外,但是我惊讶地发现Linux发行版无法正常工作。


1
这适用于每个非嵌入式Linux系统以及其他几个系统(例如Cygwin)。嵌入式系统可能有Busybox,而后者find没有-printf
Gilles

就像我说的,GNU系统。
mattdm 2011年

没有GNU coreutils的系统(例如FreeBSD)没有-printf
。– pevik

@pevik是的,就像我说的一样。但是您可以根据需要安装GNU find。:)
mattdm

@mattdm:并非总是:-(。最重要的是,当您编写应该可移植的脚本时
。– pevik

2

在纯bash中,您可以将的输出转换为ls数组并对其进行索引。

# (lrwxr-xr-x, 1, myuser, staff, 36, Oct, 21, 16:36, /path/to/file)    
file_meta=($(ls -ld /path/to/file))
file_owner="${file_meta[2]}" # myuser

它不如使用stat,,find或优雅awk,但可以在紧急情况下使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.