Jaki jest poprawny sposób wywołania jakiegoś polecenia przechowywanego w zmiennej?
Czy są jakieś różnice między 1 a 2?Jak wykonać polecenie zapisane w zmiennej?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
Jaki jest poprawny sposób wywołania jakiegoś polecenia przechowywanego w zmiennej?
Czy są jakieś różnice między 1 a 2?Jak wykonać polecenie zapisane w zmiennej?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
Powłoki uniksowe wykonują serię przekształceń na każdym wierszu wejścia przed ich wykonaniem. Dla większości muszli wygląda mniej więcej tak (wzięte z bash
podręcznika):
Korzystanie $cmd
bezpośrednio zostaje ona zastąpiona przez polecenia w fazie ekspansji parametr, a następnie przechodzi wszystkie następujące transformacje.
Korzystanie eval "$cmd"
nic nie robi aż fazie usuwania cytat, gdzie $cmd
zwracany jest jak jest, i przekazany jako parametr do eval
, którego funkcją jest ponownie uruchomić cały łańcuch przed wykonaniem.
Zasadniczo są one takie same w większości przypadków i różnią się, gdy polecenie używa kroków transformacji do rozszerzenia parametrów. Na przykład użycie rozszerzenia nawiasu klamrowego:
$ cmd="echo foo{bar,baz}"
$ $cmd
foo{bar,baz}
$ eval "$cmd"
foobar foobaz
Jak zrobić "eval" $ cmd "' bez pisania 'eval'?' $ ($ Cmd) '?' $ {$ Cmd} '? –
@StevenLu, żaden z nich nie jest równoważny - celowo więc:' 'eval 'operacja analizuje dane jako składnię, dlatego jest bardzo wrażliwa na bezpieczeństwo, a wykonywanie jej w sposób niejawny byłoby bardzo złą formą. –
myślę yu umieścić `symbole wokół zmiennej (jednego z ~ jeśli Shift wciśnięty)
Spowoduje to uruchomienie wyjścia polecenia, które np. w przypadku ls -l wygeneruje komunikat taki jak "total" polecenie nie znaleziono "(ponieważ total ... jest częścią wyjścia ls -l, np.) Więc to nie jest to, czego chcesz. –
Jeśli po prostu zrobić eval $cmd
gdy robimy cmd="ls -l"
(interaktywnie iw skrypcie) otrzymujemy pożądany rezultat. W twoim przypadku masz potok z grep bez wzorca, więc część grep zakończy się niepowodzeniem z komunikatem o błędzie. Po prostu $cmd
wygeneruje komunikat "nie znaleziono polecenia" (lub tego typu). Więc spróbuj użyć eval i użyj zakończonego polecenia, a nie takiego, który generuje komunikat o błędzie.
To był tylko błąd drukarski Powinien być "wyjątek grep" –
następnie użyć eval, a nie $ cmd przez siebie, ponieważ prawdopodobnie nie będzie działać (nie w moich testach, pod bash i zsh) .Jest to, co eval miał zrobić ... –
Zobacz [BashFAQ/050] (http://mywiki.wooledge.org/BashFAQ/050). –