
Olá a todos e obrigado antecipadamente.
Procurei no fórum a minha situação e não consegui encontrar uma solução. Eu tenho um script para o qual estou passando argumentos/opções/parâmetros na linha de comando. Um dos valores contém um espaço, que coloquei entre aspas duplas. Talvez seja mais fácil fornecer um exemplo. Perdoe meu uso de argumentos/opções/parâmetros.
$: ./test1.ksh -n -b -d "Home Videos"
Meu problema é definir uma variável como "Home Videos" e usá-la em conjunto. No meu exemplo, o -d serve para especificar um diretório. Nem todos os diretórios possuem espaços, mas alguns possuem no meu caso.
Este é um exemplo do código que tenho que não está funcionando como esperado.
#!/bin/ksh
Function1()
{
echo "Number of Args in Function1: $#"
echo "Function1 Args: $@"
SetArgs $*
}
SetArgs()
{
echo -e "\nNumber of Args in SetArgs: $#"
echo "SetArgs Args: $@"
while [ $# -gt 0 ]
do
case $1 in
-[dD])
shift
export DirectoryName=$1
;;
-[nN])
export Var1=No
shift
;;
-[bB])
export Var2=Backup
shift
;;
*)
shift
;;
esac
done
Function2
}
Function2()
{
echo "Directory Name: ${DirectoryName}"
}
Function1 $*
Quando executo isso, recebo apenas Home para DirectoryName em vez de Home Videos. Visto abaixo.
$ ./test1.ksh -n -b -d "Home Videos"
Number of Args in Function1: 5
Function1 Args: -n -b -d Home Videos
Number of Args in SetArgs: 5
SetArgs Args: -n -b -d Home Videos
Var1 is set to: No
Var2 is set to: Backup
Directory Name: Home
O que estou esperando e não consegui fazer acontecer é:
$ ./test1.ksh -n -b -d "Home Videos"
Number of Args in Function1: 4
Function1 Args: -n -b -d "Home Videos"
Number of Args in SetArgs: 4
SetArgs Args: -n -b -d "Home Videos"
Var1 is set to: No
Var2 is set to: Backup
Directory Name: Home Videos <-- Without double quotes in the final usage.
Qualquer ajuda que eu puder obter será muito apreciada... Tentei escapar das aspas duplas, sem sucesso.
Obrigado por seu tempo e esforços em me ajudar a descobrir isso.
Atenciosamente, Daniel
Responder1
Usando $*
ou $@
sem aspasnuncafaz sentido.
"$*"
é a concatenação dos parâmetros posicionais com o primeiro caractere (ou byte dependendo do shell) de $IFS
, "$@"
é a lista de parâmetros posicionais.
Quando sem aspas, é o mesmo, mas sujeito a split + glob (ou apenas remoção vazia com zsh
) como qualquer outra expansão de parâmetro sem aspas (alguns shells também separam argumentos $*
mesmo que $IFS
estejam vazios).
Aqui você quer passar a lista de argumentoscomo épara sua função, então é:
SetArgs "$@"
[...]
Function1 "$@"
Observe que com o ksh88, $IFS
ele deve conter o caractere de espaço (o que acontece por padrão) para que funcione corretamente (um bug herdado do shell Bourne, corrigido no ksh93).
Observe também que com algumas implementações de ksh
(como versões mais antigas de zsh
emulação ksh
),
export DirectoryName=$1
é um caso de invocação split+glob. export
é um daqueles comandos em shells do tipo Korn que podem avaliar o código do shellatravés da avaliação aritmética em índices de array), então éum daqueles casos em que é importante citar variáveis para evitar a introdução de vulnerabilidades de injeção de comando.
Exemplo:
$ (exec -a ksh zsh-4.0.1 -c 'export x=$a' ksh 'foo psvar[0`uname>&2`]')
Linux
Observe que [ $# -gt 0 ]
é outra invocação split+glob que não faz sentido (é menos provável que seja um problema, pelo menos com o valor padrão de $IFS
).
Responder2
Você já pensou em usar o getopts
comando shell integrado para analisar seus argumentos (como sugerido, por exemplo, por @Stéphane Chazelas emeste comentário)? Isso pouparia muito desse aborrecimento.
No seu caso, o código relevante seria o seguinte:
while getopts "nbd:" argname
do
case "$argname" in
n) Var1="No" ;;
b) Var2="Backup" ;;
d) DirectoryName ="$OPTARG" ;;
?) echo -e "usage is..."
exit 1 ;;
esac
done