String 为什么Ansible无法执行这个简单的shell脚本?
我在Ansible(1.8.2)中遇到了一个非常奇怪的问题,归结起来就是在shell脚本中执行这个简单的命令:String 为什么Ansible无法执行这个简单的shell脚本?,string,bash,shell,solaris,ansible,String,Bash,Shell,Solaris,Ansible,我在Ansible(1.8.2)中遇到了一个非常奇怪的问题,归结起来就是在shell脚本中执行这个简单的命令: #!/bin/sh # transform a String into lowercase chars: echo "TeSt" | tr [:upper:] [:lower:] 当我登录到远程Solaris计算机时,无论我在哪个shell中(例如,/bin/sh,/bin/bash),此脚本似乎都能工作: 另外,当我使用远程ssh命令执行此脚本时,它也可以工作: # ssh ro
#!/bin/sh
# transform a String into lowercase chars:
echo "TeSt" | tr [:upper:] [:lower:]
当我登录到远程Solaris计算机时,无论我在哪个shell中(例如,/bin/sh
,/bin/bash
),此脚本似乎都能工作:
另外,当我使用远程ssh命令执行此脚本时,它也可以工作:
# ssh root@<remote-host> '/tmp/test.sh'
test
我花了很长时间才发现它与raw
模块一起工作:
- raw: executable=/bin/sh /tmp/test.sh [OK]
有人知道为什么shell
和命令
模块会产生此错误吗
有关脚本失败的远程主机的更多信息:
- SunOS 5.10通用_150401-18 i86pc i386 i86pc
- 所有shell(
,/bin/sh
,/bin/bash
)都是GNU bash,版本4.1.2(1)-发行版(x86_64-redhat-linux-GNU)/bin/ksh
- Python 2.6.6
LANG=
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_ALL=
然而,有了Ansible,我得到了:
LANG=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_ALL=
不管您还有什么问题,您的
tr
命令肯定有问题
tr [:upper:] [:lower:]
因为[]
是由shell扩展的字符范围规范。如果您碰巧有一个名为:
,u
,p
,e
,r
,l
,o
或w
的文件,则在tr
将其视为参数之前,此文件将被展开:
$ touch u
$ echo [:upper:]
u
修正:使用引号,如中所示
tr '[:upper:]' '[:lower:]'
好的。所以,不管Jens怎么说,这个脚本在大多数环境中并没有“崩溃”。我在
pdksh
包的bash
、bash--posix
、dash
、busybox sh
和ksh
下测试了它,在所有情况下它都能工作
所以我去搜索那个特定的错误消息(坏字符串
),发现:
这似乎正好描述了你的问题。这不是脚本中的bug;这是Solaris上的
tr
中的一个错误。引用tr
的参数是否有帮助?这是在什么样的系统上运行的?区域设置是什么?我添加了一些系统信息。引用tr
的参数不是一个选项,脚本是软件包安装的一部分,我无法修改该代码。@dokaspar那么是时候向编写该坏脚本的人报告错误了。@Jens:是的,我一定会这么做!您是否可以将tr脚本替换为另一个脚本,忽略参数,只执行tr'[:upper:]['[:lower:]['
。或者当您不想更改tr时,请在执行包安装之前更改路径?脚本已断开:必须引用[:upper://code>和[:lower://code>!这是因为shell将把[…]
理解为一个字符范围。请在包含名为u
的文件的文件夹中进行尝试。您将看到(无引号)[:upper://code>将扩展为u
。并不是因为它在大多数情况下似乎有效,而是因为它每次都有效@Jens在他的回答中对此做了很好的解释。是的,我对引用的评论来自于在Solaris上找到关于“坏掉的”/bin/tr
的类似信息。脚本坏掉了,再多的手工操作也无法改变它。如果脚本的CWD中有一个名为u
的单字符文件,则tr
会将u转换为u,实际上什么也不做。如果有两个单字符文件,例如e
和r
,它将运行tr e r
,但会出现错误。这可能不是你的错误,但它是一颗等待爆炸的定时炸弹。无论如何,引用不是错误背后的问题。如果OP遇到错误的外壳扩展导致的问题,他可能会提出一个新的问题。我开始觉得这两个都是真的。。。(1) 由于CWD中名为u
的文件失败,脚本被破坏;(2)Solaris中也有一个错误tr
,因为脚本在任何其他环境中仍然有效(前提是没有名为u
…),这两个错误信息的人是谁?甚至没有提供理由?+1谢谢你的解释!不幸的是,这些不带引号的参数存在于我自己无法修复的代码中:(
$ touch u
$ echo [:upper:]
u
tr '[:upper:]' '[:lower:]'