inspec/lib/inspec/shell_detector.rb
Clinton Wolfe cdfb325ca3 Apply chefstyle -a, and manually remove duplicate requires
Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
2020-12-21 13:25:04 -05:00

89 lines
1.9 KiB
Ruby

require "etc" unless defined?(Etc)
require "rbconfig" unless defined?(RbConfig)
module Inspec
#
# ShellDetector attempts to detect the shell the invoking user is
# running by checking:
#
# - The command of our parent
# - The SHELL environment variable
# - The shell returned by getpwuid for our process UID
#
# Since none of these methods is fullproof, the detected shell is
# verified against a list of known shells before being returned to
# the caller.
#
class ShellDetector
NOT_DETECTED = Object.new.freeze
KNOWN_SHELLS = %w{bash zsh ksh csh sh fish}.freeze
def initialize
@shell = NOT_DETECTED
end
def shell
@shell = detect unless detected?(@shell)
@shell
end
def shell!
@shell = detect
end
private
def detect
# Most of our detection code assumes a unix-like environment
return nil if RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/
shellpath = detect_by_ppid
if shellpath.nil? || shellpath.empty? || !known_shell?(shellpath)
shellpath = detect_by_env
end
if shellpath.nil? || shellpath.empty? || !known_shell?(shellpath)
shellpath = detect_by_getpwuid
end
shellname(shellpath) if known_shell?(shellpath)
end
def detected?(arg)
arg != NOT_DETECTED
end
def detect_by_ppid
ppid = Process.ppid
if Dir.exist?("/proc")
File.readlink("/proc/#{ppid}/exe")
else
`ps -cp #{ppid} -o command=`.chomp
end
end
def detect_by_env
ENV["SHELL"]
end
def detect_by_getpwuid
Etc.getpwuid(Process.uid).shell
end
#
# Strip any leading path elements
#
def shellname(shellpath)
shellpath.split("/").last
end
#
# Only return shells that we know about, just to be sure we never
# do anything very silly.
#
def known_shell?(shell)
KNOWN_SHELLS.include?(shellname(shell))
end
end
end