我使用以下脚本检索数百台Solaris (v9、10、11)和Red (v5,6,7)服务器上挂载的文件系统的信息,以便进行分析。
# retrieves for all mounted file-systems: server, device, allocated, used, available, percent_used, mount_directory, permissions, owner_name, and group_name
server=$(uname -n)
df -h | awk '
NF == 6 { print ($0); }
NF == 1 { device = $1; }
NF == 5 { print (device, " ", $0); }
' | while read device allocated used available percent mount
do
ls -ld "${mount}" | read permissions links owner_name group_name size month day time directory
echo "${server} ${device} ${allocated} ${used} ${available} ${percent} ${mount} ${permissions} ${owner_name} ${group_name}"
done我使用PuTTY "plink“实用程序从Windoze执行此操作。
plink -m filesys.script server_name >>filesys.txt所有这些都按预期工作,直到我的默认shell在所有服务器上从ksh更改为bash为止。现在,获取权限、owner_name和group_name的ls输出的第二个read命令不起作用,也不会产生任何错误消息。因此,结果是只有七个令牌处于输出状态(服务器通过挂载),没有权限、owner_name或group_name。
我已经确认,如果我将脚本上传到Unix服务器,并在最上面的一行使用shebang (#!/bin/ksh),脚本就会像预期的那样工作。但是,我不想将此脚本推送到数百台服务器上,并在分布式机制中维护脚本。我想保留脚本在中央Windoze工作站和调用与-m参数的plink。使用plink -m选项在文件顶部放置shabang不执行ksh。
正在使用的Bash版本为3.2和4.1。我还确保Windoze脚本文件删除了回车返回。awk实用程序用于处理设备名称太长且df将输出中断两行的情况。
同样,第一个读取(来自df/awk)工作正常,但第二个(ls输出)却不工作。我通过在第二次阅读之后放置一个“集合”来确认,而那些环境勇士并不在环境中。
发布于 2015-12-11 18:51:17
read (作为管道元素)发生在子subshell中,因此即使它实际上执行得很好,一旦管道退出,它的结果对于运行在单独行上的echo (作为最初生成管道的父进程的一部分)是不可用的。POSIX完全允许这样做;管道的哪个组件(如果有的话)由shell生成执行,该管道由标准未指定,因此实现定义。
您可以通过将echo放在与read相同的管道元素中来解决这个问题。
server=$(uname -n)
df -h | awk '
NF == 6 { print ($0); }
NF == 1 { device = $1; }
NF == 5 { print (device, " ", $0); }
' | while read device allocated used available percent mount
do
# NOTE: parsing output from "ls" is unreliable
ls -ld "${mount}" | {
read permissions links owner_name group_name size month day time directory
echo "${server} ${device} ${allocated} ${used} ${available} ${percent} ${mount} ${permissions} ${owner_name} ${group_name}"
}
done参考文献:
如果您有GNU stat或find,允许您提供一个格式字符串来控制元数据输出,那么我强烈建议使用它们代替ls -l来解析元数据。即使是perl也有更好的效果,只有一个通用的实现,在不同版本之间具有统一的stat行为。
https://stackoverflow.com/questions/34230444
复制相似问题