如何编写bash脚本以允许带空格的整个命令?

时间:2015-10-22 14:49:51

标签: linux bash perl

基本上,我正在寻找一种让下面的bash脚本无问题的方法。当单独测试时,每个命令实际上都有效,只有在实际脚本中它才有问题。代码如下:

#!/bin/bash

answer="$(/usr/bin/grep "PermitRootLogin yes" /etc/ssh/sshd_config)"

  if [ $answer ]; then
       (perl -pi -e \'s/\"PermitRootLogin yes\"/\"PermitRootLogin no\"/g\' /etc/ssh/sshd_config)
 else
    echo "Root login is already not permitted, no values changed."
fi

以下是我尝试运行时会发生的事情:

test.sh:  line 9: [: PermitRootLogin: unary operator expected
Root login is already not permitted, no values changed.

所以基本上,它不是通过perl命令在文件上执行查找/替换,而是尝试将其解释为单独的指令。

它试图做的只是查看/etc/ssh/sshd_config文件,然后如果发现“回答”为是,则将相关条目从yes更改为no。

我基本上都在寻找一种方法来完成这项工作。我在这个网站上看了很多bash的例子,但似乎都没有涵盖这个具体案例。

另外,我使用perl的原因是sed在Solaris 11上工作得非常奇怪,或者没有安装在极其旧的版本上,并且每个版本都安装了perl版本从8前进。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

在方括号中双引号变量。

if [ "$answer" ] ; then

否则,它会进行扩展和分词,但[不知道如何处理两个单词(它希望第一个单词是{{1}的一元运算符这就是错误告诉你的内容。

答案 1 :(得分:1)

$(grep...)的值是grep或空字符串找到的行。使用这些行作为[的参数并不太有用。

尝试

if /usr/bin/grep "PermitRootLogin yes" /etc/ssh/sshd_config >/dev/null; then

代替。

它是如何运作的?

bash(或sh)中if的实际语法是

if command args; then

使用if [ ... ]语法时,您只需使用[作为test命令的别名(尝试在您的计算机上运行which [)。

当命令成功(退出代码为0)时,

ifthen分支,失败时取else分支 - 返回非零退出代码。

grep在找到模式时成功,在找不到时失败。

答案 2 :(得分:1)

你可以直接运行替换,因为如果没有必要,它就不会匹配,它也不会做任何事情。

这与首先grep文件一样高效。

如果你需要一条消息,那么如何计算它是否真的这样做了:

perl -i.bak -pe '$result += s/PermitRootLogin yes/PermitRootLogin no/; END { exit 1 unless $result }' /etc/ssh/sshd_config

(然后在脚本中测试$?)。

或者:

perl -i.bak -pe '$result += s/PermitRootLogin yes/PermitRootLogin no/; END { print "Fixed permissions\n" if $result }' /etc/ssh/sshd_config