#!/bin/bash
# Test script to demonstrate array expansion behavior
# Helper function to show what arguments a command receives
show_args() {
echo "Number of arguments: $#"
local i=1
for arg in "$@"; do
echo " Arg $i: [$arg]"
((i++))
done
echo ""
}
echo "================================================================================"
echo "TEST 1: Simple array - no spaces or special chars"
echo "================================================================================"
ChangesCmd1=(p4 -ztag -F %change% changes -s shelved)
echo "Array contents: ${ChangesCmd1[*]}"
echo ""
echo "UNQUOTED expansion: \${ChangesCmd1[@]}"
show_args ${ChangesCmd1[@]}
echo "QUOTED expansion: \"\${ChangesCmd1[@]}\""
show_args "${ChangesCmd1[@]}"
echo "================================================================================"
echo "TEST 2: Array with element containing spaces"
echo "================================================================================"
# Simulate P4BIN with a path containing spaces
ChangesCmd2=("/usr/local/my perforce/bin/p4" -ztag -F %change% changes -s shelved)
echo "Array contents: ${ChangesCmd2[*]}"
echo ""
echo "UNQUOTED expansion: \${ChangesCmd2[@]}"
show_args ${ChangesCmd2[@]}
echo "QUOTED expansion: \"\${ChangesCmd2[@]}\""
show_args "${ChangesCmd2[@]}"
echo "================================================================================"
echo "TEST 3: Array with date range parameter"
echo "================================================================================"
VerifySinceDate="2025/01/01"
ChangesCmd3=(p4 -ztag -F %change% changes -s shelved "@${VerifySinceDate},@now")
echo "Array contents: ${ChangesCmd3[*]}"
echo ""
echo "UNQUOTED expansion: \${ChangesCmd3[@]}"
show_args ${ChangesCmd3[@]}
echo "QUOTED expansion: \"\${ChangesCmd3[@]}\""
show_args "${ChangesCmd3[@]}"
echo "================================================================================"
echo "TEST 4: Array with parameter containing glob characters"
echo "================================================================================"
# Create a temporary directory with test files
mkdir -p /tmp/glob_test
touch /tmp/glob_test/file1.txt /tmp/glob_test/file2.txt
cd /tmp/glob_test || exit
# Array with a glob pattern as a parameter
ChangesCmd4=(ls -la "*.txt")
echo "Array contents: ${ChangesCmd4[*]}"
echo "Current directory contains: $(ls -1 *.txt | tr '\n' ' ')"
echo ""
echo "UNQUOTED expansion: \${ChangesCmd4[@]}"
show_args ${ChangesCmd4[@]}
echo "QUOTED expansion: \"\${ChangesCmd4[@]}\""
show_args "${ChangesCmd4[@]}"
cd - > /dev/null || exit
rm -rf /tmp/glob_test
echo "================================================================================"
echo "TEST 5: Complex real-world example (like in p4verify.sh)"
echo "================================================================================"
P4BIN="/opt/perforce/bin/p4"
RecentChangesToVerify="100"
VerifySinceDate="2024/12/01"
# Build array step by step like in p4verify.sh
ChangesCmd5=("$P4BIN" -ztag -F %change% changes -s shelved)
ChangesCmd5+=(-m "$RecentChangesToVerify")
ChangesCmd5+=("@${VerifySinceDate},@now")
echo "Array contents: ${ChangesCmd5[*]}"
echo ""
echo "UNQUOTED expansion: \${ChangesCmd5[@]}"
show_args ${ChangesCmd5[@]}
echo "QUOTED expansion: \"\${ChangesCmd5[@]}\""
show_args "${ChangesCmd5[@]}"
echo "================================================================================"
echo "TEST 6: What happens with a path containing spaces? (THE CRITICAL CASE)"
echo "================================================================================"
P4BIN="/Program Files/Perforce/p4"
RecentChangesToVerify="100"
# Build array like in p4verify.sh
ChangesCmd6=("$P4BIN" -ztag -F %change% changes -s shelved -m "$RecentChangesToVerify")
echo "Array contents: ${ChangesCmd6[*]}"
echo "Note: P4BIN path has a space in it"
echo ""
echo "UNQUOTED expansion: \${ChangesCmd6[@]}"
echo "This is WRONG - splits '/Program Files/Perforce/p4' into 3 arguments:"
show_args ${ChangesCmd6[@]}
echo "QUOTED expansion: \"\${ChangesCmd6[@]}\""
echo "This is CORRECT - keeps '/Program Files/Perforce/p4' as 1 argument:"
show_args "${ChangesCmd6[@]}"
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #1 | 32567 | bot_Claude_Anthropic |
p4verify.sh: Fix two array expansion issues; add array_expansion_test.sh 1. ChangesCmd expansion: change unquoted ${ChangesCmd[@]} to the quoted form "${ChangesCmd[@]}" so that array elements with spaces are preserved correctly. The now-unnecessary # shellcheck disable=SC2068 directive was removed since the quoted form does not trigger SC2068. 2. VerifyOnlyOption expansion: add ':-' default operator to all six occurrences of ${VerifyOnlyOption[*]} used in -n tests, i.e. "${VerifyOnlyOption[*]:-}", to prevent an 'unbound variable' error under 'set -u' when the array is empty on bash < 4.4. Add dev/Server/test/snippets/array_expansion_test.sh, a test script that demonstrates the quoted vs. unquoted array expansion behavior (spaces, glob chars, date-range parameters) that motivated fixes 1 and 2. #review-32568 @robert_cowham @tom_tyler |