web-dev-qa-db-ja.com

Puppetスクリプトのsedコマンドで「/」をエスケープする方法は?

設定ファイルで、PREFIX=/jenkinsをたとえばPREFIX=/foobarに置き換えようとしています。

(bash)コマンドラインでは、これは正常に機能します。

sed -i.bak s/PREFIX=\\/jenkins/PREFIX=\\/foobar/g /etc/default/jenkins

ただし、Puppetスクリプト(.ppファイル)の場合:

exec { 'Change-prefix':
  command => "sed -i.bak s/PREFIX=\\/jenkins/PREFIX=\\/foobar/g /etc/default/jenkins",
  path    => ["/bin"],
}

生成:

err: /Stage[main]//Exec[Change-prefix]/returns: change from notrun to 0 failed:
sed -i.bak s/PREFIX=\/jenkins/PREFIX=\/foobar/g /etc/default/jenkins 
returned 1 instead of one of [0] 

sedコマンドを適切にエスケープする方法は?それとも何か他の問題がありますか?

\\\/も試してみましたが、次のようになります:warning: Unrecognised escape sequence '\/'

3
Jonik

Sed式に「/」が含まれている場合は、別の区切り文字の使用を検討することをお勧めします。この例では、パイプ記号を選択しました。

sed -i.bak 's|PREFIX=/jenkins|PREFIX=/foobar|g' /etc/default/jenkins

私の意見では、Puppetマニフェストでこの構文を使用すると、はるかにクリーンで読みやすくなります。


Sed情報ページから:

\%REGEXP%' (The% 'は他の単一文字に置き換えることができます。)

 This also matches the regular expression REGEXP, but allows one to
 use a different delimiter than `/'.  This is particularly useful
 if the REGEXP itself contains a lot of slashes, since it avoids
 the tedious escaping of every `/'.  If REGEXP itself includes any
 delimiter characters, each must be escaped by a backslash (`\').
4

Sedの多くのバージョンでは、区切り文字として別​​の文字を使用して、エスケープする必要をなくすことができます。たとえば、|を使用するのは非常に一般的です。または#

sed -i.bak 's#PREFIX=/jenkins#PREFIX=/foobar#g' /etc/default/jenkins
4
user9517

おっと、おっ...ちょっと待って! Sedは少しおかしいです。puppetlabsstdlibのfile_lineリソースを使用する必要があります。

(モジュール全体をインストールする必要がありますが、ここにカスタムリソースタイプがあります) https://github.com/puppetlabs/puppetlabs-stdlib/blob/master/lib/puppet/type/file_line.rb

例:

  file_line { 'Sudo_rule':
    path => '/etc/sudoers',
    line => '%Sudo ALL=(ALL) ALL',
  }
3
robbyt

判明\\\\/は機能します。

例えば:

exec { 'Change-prefix':
  command => "sed -i.bak s/PREFIX=\\\\/jenkins/PREFIX=\\\\/foorbar/g /etc/default/jenkins",
  path    => ["/bin"],           
}

Edit:...しかし、もちろん、 Kenny および Iain が提案されているように、異なる区切り文字を使用します、非常にクリーンなソリューションです!

1
Jonik