我在另一台机器上的 bash 脚本中遇到了一个奇怪的错误,该脚本通过 ssh(或其他类似 ssh 的客户端)访问。
它基本上是一个菜单,特别是显示它所托管的计算机的 IP 地址。
重要的部分是这段代码:
#!/bin/bash
function int-ips { /sbin/ifconfig |grep -B1 "inet addr" |awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' |awk -F: '{ print $1 ": " $3 }'; }
echo $(int-ips)
(我刚刚复制粘贴了上面的函数http://www.if-not-true-then-false.com/2010/linux-get-ip-address/)
它在 Mac OS X 上的 F19 上运行得很好。然后另一位同事在他的 OS X 上尝试了它,令人惊讶的是,完全没有打印任何内容。该脚本仍在同一台计算机上执行,只是从另一个客户端通过 ssh 访问它。
我花了一些时间才明白这是一个区域设置的问题:最后一台机器的语言不是英语,并且用于检索 IP 地址的函数使用“grep Link”,“link”一词恰好被翻译为ifconfig 与其他语言环境,至少是我的同事正在使用的语言环境。
意识到存在可怕的错误来源,我想知道如何正确地保护自己免受这种区域设置依赖问题的影响。
例如,我知道我将使用“file”命令来了解有关输入的文件类型,并且我可能会使用“grep”等来分析结果。
我的解决方案:
将其添加到我的脚本的开头:
export LANG=C
export LC_ALL=C
(或者可能是 en_US.utf8 而不是 C)
我稍后会做的可能更干净的解决方案:
- 保存当前 LANG 和 LC_ALL
- 导出 LANG=C ;导出 LC_ALL=C
- 执行我的区域设置相关代码
- 恢复 1) 中保存的用户区域设置
我的问题:
A)这个修复可以吗?我的意思是,是否有一些经过实验的 bash / nix 编码员可以警告我一些我没有看到的使用此方法的危险? (我越深入 nix/nux,我就越确定没有什么:P)
B)有没有一种更简洁/更优雅的方式来完成这一切?
PS 仅供参考,但不相关,恕我直言:
托管脚本的计算机位于 Centos 6.4 的虚拟机上。
我们访问虚拟机的机器位于 Fedora 19 或 Mac OS X(通过 ssh-terminal)或 Windows 7(通过 Putty)
答案1
直接在命令前面添加环境变量只会使其占用命令的持续时间,这可能适合也可能不适合最终的应用程序。
LC_MESSAGES=C /sbin/ifconfig | grep ...