在sed命令和ssh命令中添加单引号

时间:2018-12-06 08:10:30

标签: regex bash shell sed

我在ssh调用中执行sed命令时遇到麻烦。我需要在sed命令中使用单引号。这是我的命令行:

ssh root@192.168.0.32 "sed -i '/0 => '192.168.0.32' /a 1 => '$old',' /tmp/test"

这是文件:

<?php
$CONFIG = array (
  'trusted_domains' =>
  array (
    0 => '192.168.0.32',
  ),
  'dbtype' => 'mysql',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'logtimezone' => 'UTC',
  'installed' => true,
  'redis' =>
  array (
    'host' => '192.168.0.13',
    'port' => 9095,
  ),
  'mail_smtpmode' => 'sendmail',
  'mail_from_address' => 'noreply',
  'knowledgebaseenabled' => false,
  0 => 18,
  'loglevel' => 1,
  'maintenance' => false,
);

在这种情况下,我想在第一个元素之后添加trusted_domains,例如1 => '192.168.0.1',

该命令的问题在于他无法识别sed命令中的单引号。

别忘了,sed命令位于ssh命令内部

2 个答案:

答案 0 :(得分:3)

让我们最小化这个问题(并在此过程中意识到,您的大部分上下文都可以从您的问题中删除。)首先,我们定义一个辅助函数args,以了解如何将命令拆分为单词< / p>

$ args() { for x in "$@"; do echo "[$x]"; done; }

$ old=0.0.0.0
$ args ssh root@192.168.0.32 "sed -i '/0 => '192.168.0.32' /a 1 => '$old',' /tmp/test"
[ssh]
[root@192.168.0.32]
[sed -i '/0 => '192.168.0.32' /a 1 => '0.0.0.0',' /tmp/test]

因此,将一个参数("sed -i ...")传递给ssh。双 要进行变量扩展,必须使用引号,但我们可以 通过内联old变量来简化问题:

$ args sed -i '/0 => '192.168.0.32' /a 1 => '0.0.0.0',' /tmp/test
[sed]
[-i]
[/0 => 192.168.0.32 /a 1 => 0.0.0.0,]
[/tmp/test]

我们可以进一步简化

$ args '/0 => '192.168.0.32' /a 1 => '0.0.0.0','
[/0 => 192.168.0.32 /a 1 => 0.0.0.0,]

并用一个简单得多的参数代替复杂的参数

$ args 'foo'1'bar'
[foo1bar]

请注意,三个字符串'foo'1bar已串联到 单一世界foo1bar。现在您可以问一个简单的问题:

  

如何在字符串'foo'1'bar'中添加单引号?答案是:

$ args 'foo'\'1\''bar'
[foo'1'bar]

请注意,"foo'1'bar"在您的情况下不起作用,因为您已经在外部ssh命令中使用了双引号。

答案 1 :(得分:2)

您可以尝试以下命令(根据您的需要替换用户名,主机名):

ssh toto@localhost "sed '/0 => \x27192.168.0.32\x27/a 1 => \x27$old\x27,' /tmp/test"

输出:

<?php
$CONFIG = array (
  'trusted_domains' =>
  array (
    0 => '192.168.0.32',
1 => '1.1.1.1',
  ),
  'dbtype' => 'mysql',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'logtimezone' => 'UTC',
  'installed' => true,
  'redis' =>
  array (
    'host' => '192.168.0.13',
    'port' => 9095,
  ),
  'mail_smtpmode' => 'sendmail',
  'mail_from_address' => 'noreply',
  'knowledgebaseenabled' => false,
  0 => 18,
  'loglevel' => 1,
  'maintenance' => false,
);

如果这行得通,如果您确实确定自己在做什么,只需添加-i选项。您还可以执行-i.bak来强制sed备份文件