problema do argumento da função de script bash [duplicado]

0

Não sei por que isso está gerando erro. Este é um código de teste emulando meu código real. Eu quero escrever um wrapper para find e quero permitir qualquer argumento, então estou envolvendo cada arg entre aspas simples.

#!/bin/bash

function find2 {

   ARGS="/usr/bin/find"
   while [[ $# -gt 0 ]]; do
      ARGS="$ARGS '$1'"
      shift
   done
   echo CALLING:  $ARGS
   $ARGS

}

find2 /tmp/test -name "hello.c"    # THIS IS THE DESIRED IMPLEMENTATION (doesn't work)

find '/tmp/test' '-name' 'hello.c'     # THIS IS FOR DEBUGGING (works)

Eu quero "find2" funcionar, mas não funciona. Eu recebo a seguinte saída:

CALLING: /usr/bin/find '/tmp/test' '-name' 'hello.c'
/usr/bin/find: '\'/tmp/test\'': No such file or directory
/usr/bin/find: '\'-name\'': No such file or directory
/usr/bin/find: '\'hello.c\'': No such file or directory

no entanto, se eu usar exatamente o mesmo comando (produzido por find2) diretamente, ele funciona bem:

/tmp/test/hello.c

Não tenho certeza do que está acontecendo.

    
por codechimp 16.03.2016 / 17:06

2 respostas

0

(no Bash) Você pode mudar para uma matriz de valores:

find2() {

    ARGS="/usr/bin/find"
    ARGS+=( "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"

}

find2 /tmp/test -name "hello.c"

Mas isso funciona e é bem mais simples:

find2() {
    ARGS=( "/usr/bin/find" "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"
}

find2 /tmp/test -name "hello.c"

Claro, o caminho direto também funciona (em qualquer shell com funções):

find2() {    /usr/bin/find "$@";   }

find2 /tmp/test -name "hello.c"

Por que o código original falhou?

Para "ver" o que o código está fazendo, você pode usar set -x ou better yet, substitua o echo por printf, desta forma:

find2() {

    ARGS="/usr/bin/find"
    ARGS+=( "$@" )
    printf '<%s> ' CALLING:  "${ARGS[@]}"; echo
    "${ARGS[@]}"

}

find2 /tmp/test -name "hello.c"

Quando você o executa, você vê:

$ ./script.sh
<CALLING:> </usr/bin/find> </tmp/test> <-name> <hello.c> 

Cada argumento é um elemento separado (observe a posição do < >).

No entanto, no seu código original (adicionando printf):

function find2 {

    ARGS="/usr/bin/find"
    while [[ $# -gt 0 ]]; do
        ARGS="$ARGS '$1'"
        shift
    done
    printf '<%s> ' CALLING:  "${ARGS[@]}"; echo
    $ARGS

}   

find2 /tmp/test -name "hello.c"

Você receberá, em execução:

$ ./script.sh
<CALLING:> </usr/bin/find '/tmp/test' '-name' 'hello.c'>

Todos os valores são uma longa linha de texto, não argumentos separados (observe a posição do < >).

    
por 16.03.2016 / 17:22
0

Se você alterar a linha ARGS="$ARGS '$1'" para ARGS="$ARGS $1" (removendo aspas simples), isso deve funcionar.

    
por 16.03.2016 / 17:14