Passando opções/args/parâmetros com espaços do script para uma função dentro

Passando opções/args/parâmetros com espaços do script para uma função dentro

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 $IFSestejam vazios).

Aqui você quer passar a lista de argumentoscomo épara sua função, então é:

SetArgs "$@"
[...]
Function1 "$@"

Observe que com o ksh88, $IFSele 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 zshemulaçã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 getoptscomando 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

informação relacionada