Czy eval $ (nazwa pliku kota) jest taki sam jak nazwa pliku źródłowego?

9

Pracując nad niektórymi funkcjami bash, nie znałem source ...polecenia, więc użyłem eval $(cat ...)zamiast tego. Teraz zastanawiam się, czy powinienem zmieniać każde jego użycie, czy może to tylko ta sama funkcja?

Wygląda na to, że działają teraz tak samo, ale może później pojawią się mylące różnice, chcę tylko wiedzieć.

Benzoes
źródło

Odpowiedzi:

6

eval $(cat ...)nie działa we wszystkich przypadkach. Na przykład podziały wiersza są konwertowane na pojedynczą spację $(cat ...)przed przetworzeniem zawartości eval. To często łamie wieloliniowe instrukcje, takie jak pętle i dokumenty tutaj.

Wypróbuj na przykład następujący plik z obiema metodami:

for i in 1 2 3; do
 echo $i
done

cat<<EOF
a
b
c
EOF
Florian Diesch
źródło
4
Jeśli użyjesz cudzysłowu, białe znaki pozostaną nienaruszone:eval "$(cat file)"
glenn jackman
1
Tak, to też powinno działać. Ale jeśli i tak trzeba zmienić kod, wolę, sourceponieważ jest to polecenie stworzone specjalnie do tego.
Florian Diesch,
9

Jak już wspomniano w @glennjackman, będziesz chciał zacytować podstawienie polecenia, w przeciwnym razie dzielenie słów i rozwijanie nazw ścieżek zmodyfikuje zawartość przed jej ewaluacją. I chociaż oba wykonają polecenia z pliku, istnieją różnice.

  • Gdy źródła skryptu, różne specjalne zmienne powłoki zostanie zmodyfikowany, przede wszystkim BASH_SOURCE, BASH_LINENOi FUNCNAMEtablic. Są one przydatne do drukowania komunikatów o błędach i debugowania.

  • Możesz powrócić ze skryptu źródłowego za pomocą returnpolecenia ( help return). Dzięki eval nie uzyskasz tego efektu. Podobnie pułapka POWRÓT nie zostanie uruchomiona dla eval.

  • Pozyskując skrypt, możesz przekazać mu argumenty. Nie możesz tego zrobić z tym eval.

  • W przypadku eval podstawienie polecenia odczyta całą zawartość pliku do pamięci przed przekazaniem go do eval. Po jego źródle, bash będzie czytał z pliku w miarę jego działania.

geirha
źródło
1

Ładne podsumowanie tego, co robią źródła, eval i exec: http://www.unix.com/shell-programming-scripting/54347-bash-shell-exec-eval-source-looking-help-understand.html

Sądzę, że twoje użycie eval i source'owania pliku zrobi to samo. Nie jestem jednak do końca pewien, czy zmienne w indeksie będą zachowywać się tak samo w każdym przypadku. Zalecam użycie źródła, jeśli to możliwe, ponieważ jest to najprostsza droga i sprawia, że ​​kod jest bardziej czytelny.

Hinz
źródło
3
całkowicie styczny: bash ma skrót dla $(cat file)->$(< file)
glenn jackman