Pasar opciones/argumentos/parámetros con espacios del script a una función dentro

Pasar opciones/argumentos/parámetros con espacios del script a una función dentro

Hola a TODOS y gracias de antemano.

He buscado en el foro mi situación y no he podido encontrar una solución. Tengo un script al que le estoy pasando argumentos/opciones/parámetros en la línea de comando. Uno de los valores tiene un espacio, que he puesto entre comillas dobles. Quizás sería más fácil dar un ejemplo. Perdone mi uso de argumentos/opciones/parámetros.

$:  ./test1.ksh -n -b -d "Home Videos"

Mi problema es configurar una variable en "Videos caseros" y usarla en conjunto. En mi ejemplo, -d es para especificar un directorio. No todos los directorios tienen espacios, pero algunos en mi caso sí.

Este es un ejemplo del código que tengo y que no funciona como esperaba.

#!/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 $*

Cuando ejecuto esto, solo obtengo Inicio para el nombre del directorio en lugar de Videos caseros. Visto a continuación.

 $ ./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

Lo que estoy esperando y no he podido lograr que suceda es:

 $ ./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.

Cualquier ayuda que pueda obtener sobre esto será muy apreciada... Intenté escapar de las comillas dobles, sin éxito.

Gracias por su tiempo y esfuerzo para ayudarme a resolver esto.

Saludos, Daniel

Respuesta1

Usando $*o $@sin comillasnuncatiene sentido.

"$*"es la concatenación de los parámetros posicionales con el primer carácter (o byte dependiendo del shell) de $IFS, "$@"es la lista de parámetros posicionales.

Cuando no está entre comillas, es lo mismo pero sujeto a split+glob (o solo eliminación vacía con zsh) como cualquier otra expansión de parámetros sin comillas (algunos shells también separan argumentos $*incluso si $IFSestán vacíos).

Aquí quieres pasar la lista de argumentos.como esa tu función, entonces es:

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

Tenga en cuenta que con ksh88, $IFSdebe contener el carácter de espacio (lo que hace de forma predeterminada) para que funcione correctamente (un error heredado del shell Bourne, corregido en ksh93).

También tenga en cuenta que con algunas implementaciones de ksh(como versiones anteriores de zshemulación ksh),

export DirectoryName=$1

es un caso de invocación dividida+glob. exportes uno de esos comandos en shells tipo Korn que pueden evaluar el código de shellmediante evaluación aritmética en índices de matriz), entonces esuno de esos casos en los que es importante citar variables para evitar introducir vulnerabilidades de inyección de comandos.

Ejemplo:

$ (exec -a ksh zsh-4.0.1 -c 'export x=$a' ksh 'foo psvar[0`uname>&2`]')
Linux

Tenga en cuenta que [ $# -gt 0 ]es otra invocación split+glob que no tiene sentido (es menos probable que sea un problema al menos con el valor predeterminado de $IFS).

Respuesta2

¿Ha considerado utilizar el getoptscomando de shell incorporado para analizar sus argumentos (como lo sugiere, por ejemplo, @Stéphane Chazelas eneste comentario)? Eso le ahorraría gran parte de esta molestia.

En su caso, el código relevante sería el siguiente:

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

información relacionada