Chcę wiedzieć, czy istnieje sposób na umieszczenie ampersand w zmiennej i nadal używanie go do wysyłania procesu do tła.
To działa:
BCKGRND=yes
if [ "$BCKGRND" = "yes" ]; then
sleep 5 &
else
sleep 5
fi
Ale czy nie byłoby fajnie zrealizować te pięć linii za pomocą tylko jednej? Tak jak:
BCKGRND='&'
sleep 5 ${BCKGRND}
Ale to nie działa. Jeśli BCKGRND nie jest ustawiony, działa - ale gdy jest ustawiony, jest interpretowany jako dosłowne „&” i błędy.
bash
shell-script
variable
background-process
BrowncoatOkie
źródło
źródło
echo $!
Odpowiedzi:
Nie można użyć zmiennej do wywołania tła, ponieważ rozwinięcie zmiennej następuje po przeanalizowaniu wiersza polecenia dla operatorów sterujących (takich jak
&&
i&
).Jeszcze inną opcją byłoby zawinięcie wywołań w funkcję:
... a następnie ustaw zmienną zgodnie z potrzebami:
źródło
ed
? +1 w każdym razie, to najczystsze rozwiązanie.Możesz przerzucać i modyfikować „pierwszoplanowe”:
Ustaw
FOREGROUND
siętrue
lub opróżnić, aby uruchomić proces w tle. (UstawienieFOREGROUND
dotrue
uruchomienia w tle jest wprawdzie mylące! Odpowiednie nazwy zmiennych są pozostawione jako ćwiczenie dla czytelnika).źródło
set -m
zostanie użyty).Prawdopodobnie będziesz musiał użyć
eval
:eval
powoduje, że powłoka ponownie ocenia podane argumenty. Literał&
byłby zatem interpretowany jako&
na końcu polecenia, a nie jako argument polecenia, umieszczając polecenie w tle.źródło
eval
powinna zawierać ostrzeżenie, z którym należy postępować ostrożnie. Zobacz np. Tę odpowiedź ."$BCKGRND"
ewaluacją do pustego argumentu.eval
połączy swoje argumenty spacjami przed wykonaniem rzeczywistej oceny. Wystarczy spróbować:eval printf "'{%s}\n'" foo "" "" ""
.eval foo "" "" "" ""
jest całkowicie podobny doeval foo
, bez względu na to, coIFS
lub czym innym.eval 'sleep $TIMEOUT' "$BACKGROUND"
. W przeciwnym razie można uzyskać podwójne rozwinięcia, jeśli zmienna rozwija się do innej zmiennej lub zawiera znaki specjalne. Również zagnieżdżanie cytatów może być trudne.