Ten jest nieco trudny. Informacje dostarczone przez Hauke są poprawne, wystarczy przeanalizować je pod kątem swojego przypadku użycia.
Najprostszym sposobem jest użycie $()
składni podczas ucieczki przed $
taką, że definicja zmiennej nie wykonuje polecenia zawartego $()
w momencie definicji. Zastrzeżenie polega na tym, że wynik końcowy musi być następnie ponownie oceniony (przez eval
) przez powłokę w czasie faktycznego wykonania, aby zagnieżdżone polecenie mogło zostać wykonane.
Przykład jest o wiele łatwiejszy, więc weź ten, który powinien postawić cię na właściwej drodze:
for((i=0;i<10;i++)); do
date +%s.%N # Print a timestamp (in format seconds.nanoseconds)
test="echo \$(date +%s.%N)" # Save a command to do the same
sleep 1 # Sleep for a second
eval "$test" # Evaluate the command saved in variable 'test'
echo # Print a new line before the next iteration
done
Oto przykładowe dane wyjściowe z powyższego przykładu (przycięte do jednej iteracji):
1398832186.133661344
1398832187.139076728
Zauważysz, że drugi znacznik czasu dla każdej pętli jest mniej więcej sekundę po pierwszej. I odwrotnie, jeśli wykonasz ten sam test bez uciekania się $
do test
definicji i usunięcia eval
, dwa znaczniki czasu będą prawie pasować.
Nie przyzwyczajaj się do używania eval
w większości sytuacji, ale jest to jedna z tych, w których nie znam dobrego sposobu na uniknięcie tego. Mam nadzieję, że to pomaga. Powodzenia!
$(...)
zgodnie z sugestią Hauke, ale odwrotny ukośnik jest kluczem.