2010-06-29 3 views
5

Esempio:restituire un singolo valore da una funzione di script di shell

#!/bin/sh 

a() { 
R=f 
ls -1 a* 
[ "$?" == "1" ] && { R=t; } 
echo $R 
} 

r=`a` 
echo $r 

$r contiene t o f ma anche l'uscita del comando ls.

Posso scrivere ls -1 a* >/dev/null 2>/dev/null, ma se c'è uno script più complesso che può portare a errori.

Esiste un modo per restituire un valore singolo da a()?

+0

'r = $ (a); echo $ r' potrebbe ovviamente essere sostituito con solo' a'. –

risposta

4

Una funzione di shell può restituire un valore numerico. Considerare 0 e 1, piuttosto che 'f' e 't'

#!/bin/sh 

a() { 
R=0 
ls -1 a* 
[ "$?" == "1" ] && { R=1; } 
return $R 
} 

a 
r=$? 
echo $r 

Questo sarà ancora scrivere in uscita dal ls -1 a* che probabilmente vuole ancora da smaltire, ma il valore di r sarà 0 o 1 e ha vinto includere l'output

Gli altri esempi di reindirizzamento dell'output da una riga o da un intero blocco sono buoni e, come altri hanno suggerito, è necessario conoscere altri modi per verificare le condizioni (ma assumevo che lo ls fosse una specie di arbitrario esempio)

+0

Perché non saltare l'intero business funky con '$ R' e basta eseguire' ls' e quindi 'return $?'? – Caleb

+0

@Caleb - questa risposta è una modifica allo script originale di PeterMmm per dimostrare come una funzione di shell può restituire un valore. Sono sicuro che questa intera funzione di esempio potrebbe essere eliminata, ma non so cosa potrebbe fare nel suo vero codice. –

0
a() { 
ls -1 a* > /dev/null 
[ "$?" == "0" ] && echo t || echo f 

} 

r=`a` 
echo $r 

Considerare di utilizzare [-f nomefile] e altri test di file.

1

non è necessario utilizzare ls per verificare i file che iniziano con a. Basta usare la shell

a() { 
    shopt -s nullglob 
    ret="f" 
    for file in a* 
    do 
    ret="t" 
    break 
    done 
    echo "$ret" 
} 
+0

Questo è un esempio, non la mia domanda. Come posso evitare di scrivere ovunque ">/dev/null 2>/dev/null" quando voglio avere un singolo valore/stringa da una funzione di script. – PeterMmm

1

Si può mettere un reindirizzamento su una lista di comandi:

 
{ 
    command1 
    command2 
} >/dev/null 

Se ad un certo punto nello script non si vuole alcun output di comandi successivi, è possibile reindirizzare uscita della shell con il exec incorporato:

 
echo interesting 
exec >/dev/null 
echo boring 

noti che questo dura fino alla fine dello script, non solo fino alla fine di una funzione. Questo si prende cura dei comandi dopo quello interessante ma non prima.

C'è un modo per annullare l'effetto di exec /dev/null, utilizzando le manipolazioni del descrittore di file. Non lo raccomando necessariamente, però, perché può essere difficile allenarsi in pratica. L'idea è quella di spostare qualsiasi cosa sia collegata allo standard output in un diverso descrittore, quindi reindirizzare l'output standard in un file diverso e, infine, riposizionare l'output standard originale sullo standard output.

 
{ 
    exec 3>&1   # duplicate fd 3 to fd 1 (standard output) 
    exec >/dev/null # connect standard output to /dev/null 
    echo boring 
    exec 1>&3   # connect standard output back to what was saved in fd 3 
    echo interesting 
    exec >/dev/null # connect standard output to /dev/null again 
    echo more boring 
} 3>/dev/null  # The braced list must have its fd 3 connected somewhere, 
        # even though nothing will actually be written to it.