GH-50796: [CI][Dev] Fix shellcheck errors in the ci/scripts/r_valgrind.sh (#50798)

### Rationale for this change

This is the sub issue #44748.

* SC2046: Quote this to prevent word splitting.
* SC2086: Double quote to prevent globbing and word splitting.
* SC2223: This default assignment may cause DoS due to globbing. Quote it.

```
shellcheck ci/scripts/r_valgrind.sh

In ci/scripts/r_valgrind.sh line 21:
: ${R_BIN:=RDvalgrind}
  ^------------------^ SC2223 (info): This default assignment may cause DoS due to globbing. Quote it.

In ci/scripts/r_valgrind.sh line 27:
pushd ${source_dir}
      ^-----------^ SC2086 (info): Double quote to prevent globbing and word splitting.

Did you mean:
pushd "${source_dir}"

In ci/scripts/r_valgrind.sh line 31:
${R_BIN} CMD INSTALL ${INSTALL_ARGS} arrow*.tar.gz
                     ^-------------^ SC2086 (info): Double quote to prevent globbing and word splitting.

Did you mean:
${R_BIN} CMD INSTALL "${INSTALL_ARGS}" arrow*.tar.gz

In ci/scripts/r_valgrind.sh line 42:
if [ $(grep -c "ERROR SUMMARY: 0 errors" testthat.out) != 1 ]; then
     ^-- SC2046 (warning): Quote this to prevent word splitting.

For more information:
  https://www.shellcheck.net/wiki/SC2046 -- Quote this to prevent word splitt...
  https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...
  https://www.shellcheck.net/wiki/SC2223 -- This default assignment may cause...
```

### What changes are included in this PR?

* SC2046: Quote variable to prevent word splitting.
* SC2086: Quote variable
* SC2223: Quote default variable assignments.

### Are these changes tested?

Yes.

### Are there any user-facing changes?

No.
* GitHub Issue: #50796

Lead-authored-by: Hiroyuki Sato <hiroysato@gmail.com>
Co-authored-by: Sutou Kouhei <kou@cozmixng.org>
Signed-off-by: Sutou Kouhei <kou@clear-code.com>
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 052eb8c..3cd6784 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -345,6 +345,7 @@
           ?^ci/scripts/r_revdepcheck\.sh$|
           ?^ci/scripts/r_sanitize\.sh$|
           ?^ci/scripts/r_test\.sh$|
+          ?^ci/scripts/r_valgrind\.sh$|
           ?^ci/scripts/release_test\.sh$|
           ?^ci/scripts/ruby_test\.sh$|
           ?^ci/scripts/rust_build\.sh$|
diff --git a/ci/scripts/r_valgrind.sh b/ci/scripts/r_valgrind.sh
index 0e40d79..63a6653 100755
--- a/ci/scripts/r_valgrind.sh
+++ b/ci/scripts/r_valgrind.sh
@@ -18,28 +18,32 @@
 
 set -ex
 
-: ${R_BIN:=RDvalgrind}
+: "${R_BIN:=RDvalgrind}"
 
-source_dir=${1}/r
+source_dir="${1}/r"
 
 export CMAKE_BUILD_TYPE=RelWithDebInfo
 
-pushd ${source_dir}
+pushd "${source_dir}"
+
+# Convert the space-separated options into a Bash array.
+# This avoids ShellCheck SC2086 and preserves argument boundaries.
+read -r -a R_INSTALL_ARGS <<< "${INSTALL_ARGS:-}"
 
 # build first so that any stray compiled files in r/src are ignored
-${R_BIN} CMD build --no-build-vignettes .
-${R_BIN} CMD INSTALL ${INSTALL_ARGS} arrow*.tar.gz
+"${R_BIN}" CMD build --no-build-vignettes .
+"${R_BIN}" CMD INSTALL "${R_INSTALL_ARGS[@]}" arrow*.tar.gz
 
 pushd tests
 
 # to generate suppression files run:
 # ${R_BIN} --vanilla -d "valgrind --tool=memcheck --leak-check=full --track-origins=yes --gen-suppressions=all --log-file=memcheck.log" -f testthat.R
-${R_BIN} --vanilla -d "valgrind --tool=memcheck --leak-check=full --track-origins=yes --suppressions=/${1}/ci/etc/valgrind-cran.supp" -f testthat.R |& tee testthat.out
+"${R_BIN}" --vanilla -d "valgrind --tool=memcheck --leak-check=full --track-origins=yes --suppressions=/${1}/ci/etc/valgrind-cran.supp" -f testthat.R |& tee testthat.out
 
 # valgrind --error-exitcode=1 should return an erroring exit code that we can catch,
 # but R eats that and returns 0, so we need to look at the output and make sure that
 # we have 0 errors instead.
-if [ $(grep -c "ERROR SUMMARY: 0 errors" testthat.out) != 1 ]; then
+if ! grep -q "ERROR SUMMARY: 0 errors" testthat.out; then
   cat testthat.out
   echo "Found Valgrind errors"
   exit 1