Merge pull request #18865 from Homebrew/systemd-quote
Fix systemd command line quoting
This commit is contained in:
commit
2d8a19d260
@ -455,7 +455,7 @@ module Homebrew
|
||||
sig { returns(String) }
|
||||
def to_systemd_unit
|
||||
# command needs to be first because it initializes all other values
|
||||
cmd = command&.map { |arg| Utils::Shell.sh_quote(arg) }
|
||||
cmd = command&.map { |arg| Utils::Service.systemd_quote(arg) }
|
||||
&.join(" ")
|
||||
|
||||
options = []
|
||||
|
||||
@ -727,7 +727,7 @@ RSpec.describe Homebrew::Service do
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=#{HOMEBREW_PREFIX}/opt/#{name}/bin/beanstalkd test
|
||||
ExecStart="#{HOMEBREW_PREFIX}/opt/#{name}/bin/beanstalkd" "test"
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
WorkingDirectory=#{HOMEBREW_PREFIX}/var
|
||||
@ -760,7 +760,7 @@ RSpec.describe Homebrew::Service do
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=#{HOMEBREW_PREFIX}/opt/#{name}/bin/beanstalkd
|
||||
ExecStart="#{HOMEBREW_PREFIX}/opt/#{name}/bin/beanstalkd"
|
||||
SYSTEMD
|
||||
expect(unit).to eq(unit_expect)
|
||||
end
|
||||
@ -783,7 +783,7 @@ RSpec.describe Homebrew::Service do
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=#{HOMEBREW_PREFIX}/opt/#{name}/bin/beanstalkd
|
||||
ExecStart="#{HOMEBREW_PREFIX}/opt/#{name}/bin/beanstalkd"
|
||||
WorkingDirectory=#{Dir.home}
|
||||
SYSTEMD
|
||||
expect(unit).to eq(unit_expect)
|
||||
|
||||
24
Library/Homebrew/test/utils/service_spec.rb
Normal file
24
Library/Homebrew/test/utils/service_spec.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/service"
|
||||
|
||||
RSpec.describe Utils::Service do
|
||||
describe "::systemd_quote" do
|
||||
it "quotes empty strings correctly" do
|
||||
expect(described_class.systemd_quote("")).to eq '""'
|
||||
end
|
||||
|
||||
it "quotes strings with special characters escaped correctly" do
|
||||
expect(described_class.systemd_quote("\a\b\f\n\r\t\v\\"))
|
||||
.to eq '"\\a\\b\\f\\n\\r\\t\\v\\\\"'
|
||||
expect(described_class.systemd_quote("\"' ")).to eq "\"\\\"' \""
|
||||
end
|
||||
|
||||
it "does not escape characters that do not need escaping" do
|
||||
expect(described_class.systemd_quote("daemon off;")).to eq '"daemon off;"'
|
||||
expect(described_class.systemd_quote("--timeout=3")).to eq '"--timeout=3"'
|
||||
expect(described_class.systemd_quote("--answer=foo bar"))
|
||||
.to eq '"--answer=foo bar"'
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -48,5 +48,30 @@ module Utils
|
||||
def self.systemctl?
|
||||
!systemctl.nil?
|
||||
end
|
||||
|
||||
# Quote a string for use in systemd command lines, e.g., in `ExecStart`.
|
||||
# https://www.freedesktop.org/software/systemd/man/latest/systemd.syntax.html#Quoting
|
||||
sig { params(str: String).returns(String) }
|
||||
def self.systemd_quote(str)
|
||||
result = +"\""
|
||||
# No need to escape single quotes and spaces, as we're always double
|
||||
# quoting the entire string.
|
||||
str.each_char do |char|
|
||||
result << case char
|
||||
when "\a" then "\\a"
|
||||
when "\b" then "\\b"
|
||||
when "\f" then "\\f"
|
||||
when "\n" then "\\n"
|
||||
when "\r" then "\\r"
|
||||
when "\t" then "\\t"
|
||||
when "\v" then "\\v"
|
||||
when "\\" then "\\\\"
|
||||
when "\"" then "\\\""
|
||||
else char
|
||||
end
|
||||
end
|
||||
result << "\""
|
||||
result.freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user