To pass a filename with spaces to a shell script on macOS, quote the path as one argument when you run the script, then use "$1" inside the script. For example, ./process-file.sh "/Users/sam/Documents/Quarterly Report.pdf" passes one filename; without quotes, the shell splits it into multiple arguments. This method also works with paths containing other shell-sensitive characters when quoted correctly.

Run the script with the path as one argument

In Terminal, put double quotes around the complete filename or path, including its directories, and keep the script name separate:

./process-file.sh "/Users/sam/Documents/Quarterly Report.pdf"

A backslash before each space also works for a simple typed path: ./process-file.sh /Users/sam/Documents/Quarterly\ Report.pdf. Quoting the whole path is easier to read and less error-prone, especially when it contains several spaces. Quotes are shell syntax; they group the path into one argument and are not part of the filename received by the script. The shell performs word splitting after expansions, so an unquoted path can be split at spaces. Bash Reference Manual: Quoting

If the file is in the current directory, a relative path works too:

./process-file.sh "Quarterly Report.pdf"

The path must still point to an existing file from the directory where you run the command. If the script itself is not executable, invoke it with a shell instead, for example bash process-file.sh "/Users/sam/Documents/Quarterly Report.pdf". Either form passes the path as an argument; the script needs read permission for the file and must handle any other required permissions.

Use the argument safely inside the script

Save this as process-file.sh:

#!/bin/bash

if [ "$#" -ne 1 ]; then
  printf 'Usage: %s FILE\n' "$0" >&2
  exit 2
fi

file=$1
if [ ! -f "$file" ]; then
  printf 'Not a regular file: %s\n' "$file" >&2
  exit 1
fi

printf 'Received one file: %s\n' "$file"

The script checks that it received exactly one argument, checks that the path names a regular file, and prints the received path. $# is the number of arguments; $1 is the first. Keep variable expansions quoted—"$file"—when passing a path to a command or using it in a test. Otherwise the shell may split a value containing spaces into separate words and treat wildcard characters as filename patterns. The Bash manual documents positional parameters and the shell’s word-splitting and filename-expansion steps. Bash Reference Manual: Positional Parameters and Shell Expansions

To process multiple filenames, quote each path when invoking the script, and loop over "$@" so each argument remains distinct:

for file in "$@"; do
  printf 'Received: %s\n' "$file"
done

Do not use $* or an unquoted $@ for this purpose: these can combine or split argument values. If the script expects exactly one file, keep the one-argument check and pass one quoted path.

When AppleScript launches the shell command

An AppleScript do shell script command takes a text string containing shell code. If you concatenate a path directly into that command, a path such as /Users/sam/Quarterly Reports/report.pdf is interpreted as multiple shell words. Apple documents quoted form as the way to produce text safe for shell interpretation, including strings with spaces and embedded quote characters. Apple: Calling Command-Line Tools

For a known path, quote it with quoted form of before concatenating it:

set filePath to "/Users/sam/Quarterly Reports/report.pdf"
set safePath to quoted form of filePath
do shell script "/path/to/process-file.sh " & safePath

The resulting command gives the script one path argument. If the path comes from a file chooser, convert the chosen item to a POSIX path first, then quote it:

set filePath to POSIX path of (choose file)
do shell script "/path/to/process-file.sh " & quoted form of filePath

Apple’s AppleScript reference demonstrates this pattern for a chosen folder and notes that quoted form also handles embedded single quotes. AppleScript Language Guide: Commands Reference

Fix common failures

If the script reports that it received several arguments, check the command that launches it: the complete path should be inside one pair of quotes. If it receives a path with literal quote marks, check whether those marks were included in the filename string itself; shell quotes should group the argument, not become part of its value.

If the script receives the path correctly but a later command fails, check that command’s arguments too. Quoting the launch command does not automatically protect an unquoted variable inside the script: use forms such as some-command "$file". For AppleScript, do not add quotes around a path by hand; concatenate quoted form of the path to the shell command. This addresses shell parsing only. It does not make an invalid path exist, grant file access, or guarantee that the called program accepts the file.

Sources