# shellcheck shell=bash
#==============================================================================
# Copyright and license info is available in the LICENSE file included with
# the Server Deployment Package (SDP), and also available online:
# https://workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE
#------------------------------------------------------------------------------
#==============================================================================
# Library Functions.
#------------------------------------------------------------------------------
# Function: run
#
# Short: Run a command with optional description, honoring $VERBOSITY
# and $NoOp settings. Simpler than runCmd().
#
# Input:
# $1 - cmd. The command to run. The command is displayed first
# if $VERBOSITY > 3.
# $2 - desc. Text description of command to run.
# Optionally, the text string can be prefixed with 'N:', where N is
# a one-digit integer, the minimum verbosity at which the description is to
# be displayed.
# Optionally, a series of text strings can be provided, delimited by '|',
# allowing multiple descriptions to be provided, each with a different
# minimum verbosity setting.
# This parameter is optional. If the N: prefix is omitted, it is
# equivalent to "3:". Sample values: "5:Cool command here:",
# and "3:Regular verbosity message|4:Higher verbosity message."
# and "This is a very|long description."
# $3 - honorNoOpFlag. Pass in 1 to mean "Yes, honor the $NoOp setting
# and display (but don't run) commands if $NoOp is set." Otherwise
# $NoOp is ignored, and the command is always run.
# This parameter is optional; the default value is 1.
# $4 - alwaysShowOutputFlag. If set to 1, show output regardless of $VERBOSITY
# value. Otherwise, only show output if VERBOSITY > 4.
# This parameter is optional; the default value is 0.
# $5 - grepString. If set, this changes the exit code behavior.
# If the specified string exists in the output, a 0 is returned, else 1.
# Strings suitable for use with 'egrep' are allowed.
#
# Description:
# Display an optional description of a command, and then run the
# command. This is affected by $NoOp and $VERBOSITY. If $NoOp is
# set, the command is shown, but not run, provided $honorNoOpFlag is 1.
# The description is not shown if $VERBOSITY < 3.
#
# The variables CMDLAST and CMDEXITCODE are set each time runCmd is called.
# CMDLAST contains the last command run. CMDEXITCODE contains its exit code.
#
# Output is shown if either $AlwaysShowOutputFlag is 1 or $VERBOSITY >= 4.
#------------------------------------------------------------------------------
function run () {
dbg "CALL: run ($*)"
local cmd=${1:-}
local desc=${2:-}
local -i honorNoOpFlag=${3:-1}
local -i alwaysShowOutputFlag=${4:-0}
local grepString=${5:-}
local cmdScript=$P4U_TMPDIR/cmd.sh
local cmdOut=$P4U_TMPDIR/script.out
local -i grepExit
# shellcheck disable=SC2034
CMDLAST="$cmd"
CMDEXITCODE=0
if [[ -n "$desc" ]]; then
# Descriptions intended to be multi-line contain a '|' char.
# Each entry may contain an optional 'N:' prefix where N is the
# verbosity level at or above which the message is displayed.
echo "$desc" | tr '|' '\n' | while read -r text; do
if [[ $text =~ ^[0-9]+: ]]; then
descVerbosity=${text%%:*}
text=${text#"$descVerbosity:"}
if [[ $VERBOSITY -ge $descVerbosity ]]; then
echo -e "$text"
fi
else
msg "$desc"
fi
done
fi
if [[ $honorNoOpFlag -eq 1 && $NoOp -eq 1 ]]; then
msg "NO-OP: Would run: \"$cmd\"\n"
else
vmsg "Running: \"$cmd\"."
echo -e "#!/bin/bash\n$cmd\n" > "$cmdScript"
chmod +x "$cmdScript"
$cmdScript > "$cmdOut" 2>&1
CMDEXITCODE=$?
if [[ -n "$grepString" ]]; then
# shellcheck disable=SC2196
egrep "$grepString" "$cmdOut" > /dev/null 2>&1
grepExit=$?
CMDEXITCODE="$grepExit"
fi
if [[ $alwaysShowOutputFlag -eq 1 ]]; then
cat "$cmdOut"
else
[[ $VERBOSITY -gt 3 ]] && cat "$cmdOut"
fi
# Be clean and tidy.
/bin/rm -f "$cmdScript" "$cmdOut"
# If a grep was requested, return the exit code from the egrep,
# otherwise return the exit code of the command executed. In
# any case, $CMDEXITCODE contains the exit code of the command.
if [[ -n "$grepString" ]]; then
return $grepExit
else
return $CMDEXITCODE
fi
fi
return 0
}
#------------------------------------------------------------------------------
# Function: rrun
#
# Short: Run a command with on a remote host optional description, honoring
# $VERBOSITY and $NoOp settings. Simpler than runRemoteCmd().
#
# Input:
# $1 - host. The remote host to run the command on.
# $2 - cmd. The command to run. The command is displayed first
# if $VERBOSITY > 3.
# $3 - desc. Text description of command to run.
# Optionally, the text string can be prefixed with 'N:', where N is
# a one-digit integer, the minimum verbosity at which the description is to
# be displayed.
# Optionally, a series of text strings can be provided, delimited by '|',
# allowing multiple descriptions to be provided, each with a different
# minimum verbosity setting.
# This parameter is optional. If the N: prefix is omitted, it is
# equivalent to "3:". Sample values: "5:Cool command here:"
# $4 - honorNoOpFlag. Pass in 1 to mean "Yes, honor the $NoOp setting
# and display (but don't run) commands if $NoOp is set." Otherwise
# $NoOp is ignored, and the command is always run.
# This parameter is optional; the default value is 1.
# $5 - alwaysShowOutputFlag. If set to 1, show output regardless of $VERBOSITY
# value. Otherwise, only show output if VERBOSITY > 4.
# This parameter is optional; the default value is 0.
# $6 - grepString. If set, this changes the exit code behavior.
# If the specified string exists in the output, a 0 is returned, else 1.
# Strings suitable for use with 'egrep' are allowed.
#
# Description:
# Display an optional description of a command, and then run the
# command. This is affected by $NoOp and $VERBOSITY. If $NoOp is
# set, the command is shown, but not run, provided $honorNoOpFlag is 1.
# The description is not shown if $VERBOSITY < 3.
#
# The variables RCMDLAST and RCMDEXITCODE are set each time runCmd is called.
# RCMDLAST contains the last command run. RCMDEXITCODE contains its exit code.
#
# Output is shown if either $AlwaysShowOutputFlag is 1 or $VERBOSITY >= 4.
#------------------------------------------------------------------------------
function rrun () {
dbg "CALL: rrun ($*)"
local host=${1:-Unset}
local cmd=${2:-Unset}
local desc=${3:-}
local -i honorNoOpFlag=${4:-1}
local -i alwaysShowOutputFlag=${5:-0}
local grepString=${6:-}
local rCmdScript="${P4TMP:-/tmp}/rcmd.$$.${RANDOM}${RANDOM}.sh"
local rCmdOut=$P4U_TMPDIR/rcmd.out
local -i grepExit
# shellcheck disable=SC2034
RCMDLAST="$cmd"
RCMDEXITCODE=0
if [[ -n "$desc" ]]; then
echo "$desc" | tr '|' '\n' | while read -r text; do
if [[ $text =~ ^[0-9]+: ]]; then
descVerbosity=${text%%:*}
text=${text#"$descVerbosity:"}
if [[ $VERBOSITY -ge $descVerbosity ]]; then
echo -e "$text"
fi
else
msg "$desc"
fi
done
fi
if [[ $honorNoOpFlag -eq 1 && $NoOp -eq 1 ]]; then
vmsg "NO-OP: Would run: \"$cmd\" on host $host.\n"
else
vmsg "Running: \"$cmd\" on host $host."
echo -e "#!/bin/bash\n$cmd\n" > "$rCmdScript"
chmod +wx "$rCmdScript"
if ! scp -pq "$rCmdScript" "$host:${P4TMP:-/tmp}/."; then
RCMDEXITCODE=-1
errmsg "rrun(): Failed to copy temp command script to $host."
return 1
fi
ssh -q -n "$host" "$rCmdScript" > "$rCmdOut" 2>&1
RCMDEXITCODE=$?
if [[ -n "$grepString" ]]; then
# shellcheck disable=SC2196
egrep "$grepString" "$rCmdOut" > /dev/null 2>&1
grepExit=$?
RCMDEXITCODE="$grepExit"
fi
if [[ $alwaysShowOutputFlag -eq 1 ]]; then
cat "$rCmdOut"
else
[[ $VERBOSITY -gt 3 ]] && cat "$rCmdOut"
fi
# Be clean and tidy.
/bin/rm -f "$rCmdScript" "$rCmdOut"
# If a grep was requested, return the exit code from the egrep,
# otherwise return the exit code of the command remotely executed.
# In any case, $RCMDEXITCODE contains the exit code of the command.
if [[ -n "$grepString" ]]; then
return $grepExit
else
return $RCMDEXITCODE
fi
fi
return 0
}
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #1 | 32135 | C. Thomas Tyler |
Released SDP 2025.1.32133 (2025/10/29). Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'. |
||
| //guest/perforce_software/sdp/dev/Server/Unix/p4/common/lib/run.lib | |||||
| #1 | 32044 | C. Thomas Tyler |
Slow Refactoring: "Moving" log_functions.sh from bin to lib directory, and changing to .lib extension per coming SDP Coding Standard for bash. The "slow refactoring" means for this change, the original log_functions.sh will remain in the bin directory, and a new logging.lib file will be added in the lib directory. The removal of the file in bin will occur separately. This is intended to balance allowing progress while preventing potential disruption to customers who may have supplemental automation relying on the current names. New libs: ps.lib, logging.lib, run.lib We may also allow legacy exceptions since customer-side custom scripts may have dependencies on backup_functions.sh and other *.sh libraries in the bin directory. Unrelated minor fixes in p4verify.sh. |
||