Isso daria a saída que você pede:
eval "for arg in $ARGS; do echo \"\$arg\";done"
Mas eval só deve ser usado como último recurso. A razão pela qual sua quetsion é difícil de responder é que o formato da sua variável ARGS é mal projetado.
Uma série de palavras separadas por espaços em branco, com espaços em branco dentro de palavras protegidas por um mecanismo de citações, é o formato básico de um comando shell. Já que você tem que aprender este formato para poder escrever um script de shell, torna-se tentador usá-lo para as estruturas de dados gerenciadas pelo seu shell script, então você pega a construção shell-like "a b" c
e a coloca em um shell variável.
Isso geralmente é uma má ideia. Não há nenhuma razão para as strings no seu shell script parecerem com as linhas de comando do shell, e a única maneira de manipular uma string contendo palavras separadas por espaços em branco e talvez citadas é construir seu próprio parser fora das operações de string primitivas, ou perguntar o shell para fazer isso com eval.
Mas quando você usa eval, você não apenas pega o divisor de palavras e o removedor de citações, você também obtém todo o resto do analisador do shell: substituição de comando, substituição de parâmetro, redirecionamento de entrada / saída e outras coisas você provavelmente não quer.
Use uma matriz. Este script baseado em array funciona em zsh, ksh e bash:
ARGS=("a b" c)
for arg in "${ARGS[@]}"; do
echo "$arg"
done
É muito mais limpo que eval. Se você está programando para um sistema antigo que não possui zsh, ksh ou bash, considere aprender o awk. O shell POSIX mínimo não é uma boa linguagem para scripts complicados o suficiente para precisar de matrizes.
Uma pequena elaboração sobre parte da resposta de ormaaj: POSIX sh tem uma única variável de matriz: $@
, que é a matriz de "parâmetros posicionais" (argumentos de linha de comando). Você pode acessar (ler, não gravar) seus elementos individuais como $1
, $2
, $3
, etc. Você pode substituir a matriz inteira pelo comando set
. Para o seu script de exemplo, essa funcionalidade é quase insuficiente. Isso funciona em qualquer shell da família Bourne:
set -- "a b" c
for arg; do
echo "$arg"
done
Eu adicionei uma demonstração do recurso de bônus: for arg
sem um in
é equivalente a for arg in "$@"
, que faz um loop sobre a matriz $@
.