Estou com um pouco de dificuldade em seguir a sua pergunta, e acho que tanto o problema concreto quanto a estranha formulação de sua pergunta derivam da mesma raiz, que é um modelo incorreto de como a análise de argumentos de comando funciona.
Um comando não recebe uma string como argumento, mas uma lista de strings. Todas as citações são realizadas pelo shell.
Se você executar algum dos seguintes comandos do shell
mycommand "foo bar" wibble
mycommand 'foo bar' 'wibble'
mycommand ''''foo" "bar \wib\ble
mycommand foo\ bar \
"wibble"
(ou uma miríade de variantes), o comando é executado exatamente com os mesmos argumentos em todos os casos:
- o argumento 0 é
mycommand
;
- o argumento 1 é a string de 7 caracteres
foo bar
;
- o argumento 2 é a string de 6 caracteres
wibble
.
A construção do shell $1
não significa “pegue o valor do parâmetro 1”. Significa “pegar o valor do parâmetro 1, dividi-lo em partes separadas por espaços em branco, e interpretar cada peça como um padrão curinga e substituí-la pelos nomes dos arquivos correspondentes”. Sim, é um bocado cheio. Como um princípio geral de programação de shell, sempre coloca aspas duplas em torno de substituições de variáveis e comandos de comando : "$1"
, "$some_variable"
, "$(some_command)"
.
Aqui, dois erros fazem um certo, mas apenas em um caso limitado: você passa um único argumento para o shell script e divide em pedaços separados por espaços em branco para transformá-lo em uma lista de strings para passar como argumentos para o Script Perl. Esta é uma interface não intuitiva e limitada. Ele não permite que você tenha espaços nos argumentos para o script Perl, uma vez que os espaços já são usados para separar argumentos. Você não pode ter as duas coisas. Aspas não ajudam aqui: você pode passar um caractere de aspas no argumento para o shell script, e ele se tornará parte de um argumento para o script Perl. Por exemplo, se você executar um dos
check_api.sh "-C \"Test Internal Cluster\""
check_api.sh '-C "Test Internal Cluster"'
check_api.sh -C\ \"Test Internal Cluster\"
o script de shell é chamado com um único argumento -C "Test Internal Cluster"
e o script Perl é chamado com os 4 argumentos -C
, "Test
, Internal
e Cluster"
.
A correção é simples, mas requer a alteração da convenção de chamada para o script de shell. O que você tem agora é um bug, você precisa consertá-lo. Chame o script da maneira normal:
/usr/local/API/check_api.sh -D x.x.x.x -C Test_Internal_Cluster -u user -p pass -i 300 -l runtime -s list
/usr/local/API/check_api.sh -D x.x.x.x -C 'Test Internal Cluster' -u user -p pass -i 300 -l runtime -s list
/usr/local/API/check_api.sh -D x.x.x.x -C "Test Internal Cluster" -u user -p pass -i 300 -l runtime -s list
(os dois últimos são equivalentes, já que as aspas simples e duplas só fazem diferença quando \$'
aparecerem dentro de7) e consertam o script de shell para usar aspas duplas em torno das substituições de comandos.
if [ -x "$Api" ]
then
output=$("$Perl" "$Api" "$1")
exitstatus=$?
F1="${output%%:*}"; output="${output#*:}"
output="${output%%:*}"
F2="${output%%\|*}"; output="${output#*\|}"
F3="${output%%\|*}"
fi
Substitui o código awk por construções de shell equivalentes, supondo que a saída seja uma única linha.