Do not use new bash features to make it work on old bash versions.

PiperOrigin-RevId: 667584295
diff --git a/centipede/puzzles/run_puzzle.sh b/centipede/puzzles/run_puzzle.sh
index 6089402..1d8be68 100755
--- a/centipede/puzzles/run_puzzle.sh
+++ b/centipede/puzzles/run_puzzle.sh
@@ -71,7 +71,7 @@
     --timeout_per_input=10 \
     --exit_on_crash \
     "$@" \
-    |& tee "${log}"
+    2>&1 | tee "${log}"
   then
     # Centipede must exit with failure.
     return 1
diff --git a/centipede/test_util.sh b/centipede/test_util.sh
index 426e0bf..ad8a113 100644
--- a/centipede/test_util.sh
+++ b/centipede/test_util.sh
@@ -64,17 +64,15 @@
 # an executable file.
 function centipede::maybe_set_var_to_executable_path() {
   local var_name="$1"
-  # NOTE: `local -n` creates a reference to the var named "$1".
-  local -n var_ref="$1"
   local path="$2"
-  if [[ -n "${var_ref+x}" ]]; then
-    echo "Not overriding ${var_name} -- already set to '${var_ref}'" >&2
+  if [[ -n "${!var_name:-}" ]]; then
+    echo "Not overriding ${var_name} -- already set to '${!var_name}'" >&2
   else
     echo "Setting ${var_name} to '${path}'" >&2
-    var_ref="${path}"
+    eval "$(printf "${var_name}=%q" "${path}")"
   fi
-  if ! [[ -x "${var_ref}" ]]; then
-    die "Path '${var_ref}' doesn't exist or is not executable"
+  if ! [[ -x "${!var_name}" ]]; then
+    die "Path '${!var_name}' doesn't exist or is not executable"
   fi
 }
 
@@ -83,17 +81,15 @@
 # TODO(ussuri): Reduce code duplication with the above.
 function centipede::maybe_set_var_to_built_executable_path() {
   local var_name="$1"
-  # NOTE: `local -n` creates a reference to the var named "$1".
-  local -n var_ref="$1"
   local bazel_build_cmd="$2"
-  if [[ -n "${var_ref+x}" ]]; then
-    echo "Not overriding ${var_name} -- already set to '${var_ref}'" >&2
+  if [[ -n "${!var_name:-}" ]]; then
+    echo "Not overriding ${var_name} -- already set to '${!var_name}'" >&2
   else
     echo "Setting ${var_name} to output of '${bazel_build_cmd}'" >&2
-    var_ref="$(set -e; ${bazel_build_cmd})"
+    eval "$(printf "${var_name}=%q" "$(set -e; ${bazel_build_cmd})")"
   fi
-  if ! [[ -x "${var_ref}" ]]; then
-    die "Path '${var_ref}' doesn't exist or is not executable"
+  if ! [[ -x "${!var_name}" ]]; then
+    die "Path '${!var_name}' doesn't exist or is not executable"
   fi
 }
 
@@ -108,7 +104,7 @@
   local -r file="$2"
   local -r expected_found="$3"
   # Make the shell option change below local.
-  local -
+  local -r saved_opts="$(set +o)"
   set -o pipefail
   if ! fileop ls "${file}" > /dev/null; then
     die "Expected file ${file} doesn't exist"
@@ -131,6 +127,7 @@
       die "^^^ File ${file} contains unexpected regex /${regex}/"
     fi
   fi
+  eval "${saved_opts}"
 }
 
 # Makes sure that string "$1" exists in file "$2". Works for local and CNS.
diff --git a/centipede/testing/data_only_dso_test.sh b/centipede/testing/data_only_dso_test.sh
index c3fc26e..6d4107e 100755
--- a/centipede/testing/data_only_dso_test.sh
+++ b/centipede/testing/data_only_dso_test.sh
@@ -38,7 +38,7 @@
 "${CENTIPEDE_BINARY}" --binary="${TARGET_BINARY}" --workdir="${WD}" \
   --exit_on_crash=1 --seed=1 --log_features_shards=1 \
   --symbolizer_path="${LLVM_SYMBOLIZER}" \
-  |& tee "${LOG}"
+  2>&1 | tee "${LOG}"
 
 echo "Fuzzing DONE"
 
diff --git a/centipede/testing/external_target_test.sh b/centipede/testing/external_target_test.sh
index ac6d8ec..70c431c 100755
--- a/centipede/testing/external_target_test.sh
+++ b/centipede/testing/external_target_test.sh
@@ -51,7 +51,7 @@
   "${CENTIPEDE_BINARY}" --binary="${TARGET_BINARY}" --workdir="${WD}" \
   --coverage_binary="${SERVER_BINARY}" --symbolizer_path="${LLVM_SYMBOLIZER}" \
   --exit_on_crash=1 --seed=1 --log_features_shards=1 \
-  |& tee "${LOG}" || true
+  2>&1 | tee "${LOG}" || true
 
 # Check that Centipede finds the crashing input.
 centipede::assert_regex_in_file "Input bytes.*: Secret" "${LOG}"