Para passar um nome de arquivo com espaços para um shell script no macOS, coloque o caminho entre aspas como um único argumento ao executar o script e, em seguida, use "$1" dentro do script. Por exemplo, ./process-file.sh "/Users/sam/Documents/Quarterly Report.pdf" passa um único nome de arquivo; sem aspas, o shell o divide em múltiplos argumentos. Esse método também funciona com caminhos que contêm outros caracteres sensíveis ao shell quando colocados entre aspas corretamente.
Execute o script com o caminho como um único argumento
No Terminal, coloque aspas duplas em volta do nome de arquivo completo ou do caminho, incluindo seus diretórios, e mantenha o nome do script separado:
./process-file.sh "/Users/sam/Documents/Quarterly Report.pdf"
Uma barra invertida antes de cada espaço também funciona para um caminho digitado simples: ./process-file.sh /Users/sam/Documents/Quarterly\ Report.pdf. Colocar todo o caminho entre aspas é mais fácil de ler e menos propenso a erros, especialmente quando contém vários espaços. As aspas são sintaxe do shell; elas agrupam o caminho em um único argumento e não fazem parte do nome do arquivo recebido pelo script. O shell realiza a divisão de palavras (word splitting) após as expansões, portanto, um caminho sem aspas pode ser dividido nos espaços. Bash Reference Manual: Quoting
Se o arquivo estiver no diretório atual, um caminho relativo também funciona:
./process-file.sh "Quarterly Report.pdf"
O caminho ainda deve apontar para um arquivo existente a partir do diretório onde você executa o comando. Se o script em si não for executável, invoque-o usando um shell, por exemplo bash process-file.sh "/Users/sam/Documents/Quarterly Report.pdf". Qualquer uma das formas passa o caminho como um argumento; o script precisa de permissão de leitura para o arquivo e deve lidar com quaisquer outras permissões necessárias.
Use o argumento com segurança dentro do script
Salve isto como 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"
O script verifica se recebeu exatamente um argumento, verifica se o caminho aponta para um arquivo comum e imprime o caminho recebido. $# é o número de argumentos; $1 é o primeiro. Mantenha as expansões de variáveis entre aspas—"$file"—ao passar um caminho para um comando ou ao usá-lo em um teste. Caso contrário, o shell pode dividir um valor que contém espaços em palavras separadas e tratar caracteres curinga como padrões de nomes de arquivos. O manual do Bash documenta parâmetros posicionais e as etapas de divisão de palavras e expansão de nomes de arquivos do shell. Bash Reference Manual: Positional Parameters and Shell Expansions
Para processar múltiplos nomes de arquivos, coloque cada caminho entre aspas ao invocar o script e itere sobre "$@" para que cada argumento permaneça distinto:
for file in "$@"; do
printf 'Received: %s\n' "$file"
done
Não use $* nem $@ sem aspas para essa finalidade: eles podem combinar ou dividir os valores dos argumentos. Se o script espera exatamente um arquivo, mantenha a verificação de argumento único e passe um único caminho entre aspas.
Quando o AppleScript inicializa o comando de shell
Um comando AppleScript do shell script recebe uma cadeia de texto contendo código shell. Se você concatenar um caminho diretamente nesse comando, um caminho como /Users/sam/Quarterly Reports/report.pdf será interpretado como múltiplas palavras do shell. A Apple documenta quoted form como a maneira de produzir texto seguro para interpretação do shell, incluindo strings com espaços e caracteres de aspas incorporados. Apple: Calling Command-Line Tools
Para um caminho conhecido, coloque-o entre aspas com quoted form of antes de concatená-lo:
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
O comando resultante fornece ao script um argumento de caminho. Se o caminho vier de um seletor de arquivos, converta o item escolhido para um caminho POSIX primeiro e, em seguida, coloque-o entre aspas:
set filePath to POSIX path of (choose file)
do shell script "/path/to/process-file.sh " & quoted form of filePath
A referência de AppleScript da Apple demonstra esse padrão para uma pasta selecionada e observa que quoted form também lida com aspas simples incorporadas. AppleScript Language Guide: Commands Reference
Corrija falhas comuns
Se o script relatar que recebeu vários argumentos, verifique o comando que o inicializa: o caminho completo deve estar dentro de um par de aspas. Se ele receber um caminho com aspas literais, verifique se essas marcas foram incluídas na própria string do nome do arquivo; as aspas do shell devem agrupar o argumento, e não se tornar parte do seu valor.
Se o script receber o caminho corretamente, mas um comando posterior falhar, verifique também os argumentos desse comando. Colocar o comando de inicialização entre aspas não protege automaticamente uma variável sem aspas dentro do script: use formatos como some-command "$file". Para o AppleScript, não adicione aspas manualmente ao redor de um caminho; concatene quoted form of do caminho ao comando do shell. Isso resolve apenas a análise sintática (parsing) do shell. Não faz com que um caminho inválido passe a existir, não concede acesso ao arquivo e não garante que o programa chamado aceite o arquivo.
Fontes
Bash Reference Manual: Quoting — GNU Project
Bash Reference Manual — GNU Project
Mac Automation Scripting Guide: Calling Command-Line Tools — Apple
Commands Reference — Apple