2013-08-13 11 views
8

Ostatni wiersz w tym skrypcie nie będzie działać jak oczekuję:Analizowanie zmienne łańcucha

myfile="afile.txt" 
mycmd='cat $myfile' 
eval $mycmd 
echo eval $mycmd 

Tutaj echo drukuje „eval cat $ myFile”. Jak mogę wydrukować "eval cat afile.txt"?

Odpowiedz

26

Weźmy wszystko krok po kroku:

Kiedy to zrobić:

mycmd='cat $myfile' 

Uniemożliwia interpolację powłoki $myfile. Zatem:

$ echo $mycmd 
cat $myfile 

Jeśli chcesz zezwolić na interpolację, można użyć cudzysłowia:

$ mycmd="echo $myfile" #Double quotes! 
$ echo "$mycmd" 
cat afile.txt 

To, oczywiście, zamarza interpretacja $mycmd kiedy zrobić eval.

$ myfile="afile.txt" 
$ mycmd="echo $myfile" 
$ echo $mycmd 
cat afile.txt 
$ eval $mycmd #Prints out afile.txt 
$ myfile=bfile.txt 
$ eval $mycmd #Still prints out afile.txt and not bfile.txt 

Porównaj to:

$ myfile="afile.txt" 
$ mycmd='cat $myfile' #Single quotes hide $myfile from the shell 
echo $mycmd 
cat $myfile    #Shell didn't change "$myfile", so it prints as a literal 
$ eval $mycmd   #Prints out afile.txt 
$ myfile=bfile.txt 
$ eval $mycmd   #Now prints out bfile.txt 

Co prawdopodobnie chcesz zrobić jest ocena $mycmd w instrukcji echo kiedy to echo:

$ echo $(eval "echo $mycmd") 
$ cat afile.txt 
$ myfile=bfile.txt 
$ echo $(eval "echo $mycmd") 
cat bfile.txt 
+0

To nie działa na : grep fatal 'find/var/log/-name 'current' – taco

1

Trzeba eval echa, a nie na odwrót:

eval echo "eval $mycmd" 

lub

eval echo eval "$mycmd" 

Myślę, że były to korzystne, ale przynajmniej podać zmienną ekspansję.

7

Można napisać:

eval echo eval $mycmd 

lub nieco bardziej wytrzymałe:

eval echo eval "$mycmd" 

To powiedziawszy, polecam unikanie eval w miarę możliwości; Zwykle jest bardzo delikatna, ponieważ w przetwarzaniu wiersza poleceń Bash jest wiele skomplikowanych kroków, a użycie eval zazwyczaj oznacza wykonanie tych kroków więcej niż raz. Ciężko jest śledzić, co się naprawdę dzieje.

1

Jeśli używasz bash, lepszym sposobem na to jest użycie tablic:

myfile="afile.txt" 
mycmd=(cat "$myfile") 
echo "${mycmd[@]}" 
"${mycmd[@]}"