首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash内置读命令与Korn shell的区别

Bash内置读命令与Korn shell的区别
EN

Stack Overflow用户
提问于 2015-12-11 18:44:38
回答 1查看 130关注 0票数 2

我使用以下脚本检索数百台Solaris (v9、10、11)和Red (v5,6,7)服务器上挂载的文件系统的信息,以便进行分析。

代码语言:javascript
复制
# 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执行此操作。

代码语言:javascript
复制
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输出)却不工作。我通过在第二次阅读之后放置一个“集合”来确认,而那些环境勇士并不在环境中。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-11 18:51:17

read (作为管道元素)发生在子subshell中,因此即使它实际上执行得很好,一旦管道退出,它的结果对于运行在单独行上的echo (作为最初生成管道的父进程的一部分)是不可用的。POSIX完全允许这样做;管道的哪个组件(如果有的话)由shell生成执行,该管道由标准未指定,因此实现定义。

您可以通过将echo放在与read相同的管道元素中来解决这个问题。

代码语言:javascript
复制
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

参考文献:

  • BashFAQ #24 (我在管道中的循环中设置变量。为什么在循环结束后它们就消失了?或者,为什么我不能用管道读取数据?)
  • ParsingLs (为什么不解析ls(1)的输出)

如果您有GNU statfind,允许您提供一个格式字符串来控制元数据输出,那么我强烈建议使用它们代替ls -l来解析元数据。即使是perl也有更好的效果,只有一个通用的实现,在不同版本之间具有统一的stat行为。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34230444

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档