Restituire un singolo valore da una funzione di script di shell
-
01-10-2019 - |
Domanda
Esempio:
#!/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
.
io possa scrivere ls -1 a* >/dev/null 2>/dev/null
, ma se c'è uno script più complesso che può essere portare a errori.
C'è un modo per restituire un singolo valore da a()
?
Soluzione
Una funzione 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
Questa emette ancora scrivere dal ls -1 a*
che probabilmente vuole ancora da smaltire, ma il valore di r
sarà 0 o 1 e non includerà l'uscita.
Gli altri esempi di reindirizzare l'output sia da una linea o di un blocco intero sono buoni, e, come altri hanno suggerito, si dovrebbe arrivare a conoscere altri modi per verificare le condizioni (ma mi stava assumendo il ls
era una sorta di un esempio arbitrario )
Altri suggerimenti
non c'è bisogno di usare ls
per controllare 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"
}
Si può mettere un reindirizzamento su una lista di comandi:
{ command1 command2 } >/dev/null
Se a un certo punto lo script non si vuole alcun output di comandi successivi, è possibile reindirizzare l'output della shell con il comando incorporato exec
:
echo interesting exec >/dev/null echo boring
Si noti che questo dura fino alla fine dello script, non solo fino alla fine di una funzione. Questo si prende cura dei comandi dopo l'interessante, ma non prima.
C'è un modo per ripristinare l'effetto di exec /dev/null
, utilizzando manipolazioni descrittore di file. Non consiglio necessariamente, però, perché può essere difficile da capire nella pratica. L'idea è quella di trasferire tutto ciò che è collegato all'uscita standard per un descrittore di diverso, quindi reindirizzare lo standard output in un file diverso, e, infine, riposizionare gli originali standard output 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.
a() {
ls -1 a* > /dev/null
[ "$?" == "0" ] && echo t || echo f
}
r=`a`
echo $r
Si consideri utilizzando [-f nomefile] e altri test di file come bene.