您的位置:首页 > 服装鞋帽 > 男装 > Bash: Why use eval with variable expansion?

Bash: Why use eval with variable expansion?

luyued 发布于 2011-03-10 03:02   浏览 N 次  

Bash: Why use eval with variable expansion?

Problem

I don't understand why I have to use eval:

#!/bin/bash
cmd="date --date=\"1 days ago\""
$cmd # Doesn't work
eval $cmd # Works

Solution

Before the shell executes a command, it performs the following operations (check the manual for details):

  1. Syntax analysis (Parsing)
  2. Brace expansion
  3. Tilde expansion
  4. Parameter and variable expansion
  5. Command substitution
  6. Arithmetic expansion
  7. Word splitting
  8. Filename expansion
  9. Quote removal

It is important to realize that parsing takes place before parameter and command substitution. The result of a step n is subject to the next steps (n+), but the preceding steps (n-) are not re-executed. In other words: after for example variable expansion (step 4) the result is not re-parsed (step 1).

In the example of the command:

$cmd # cmd="date --date=\"1 days ago\""

the command date --date=\"1 days ago\" is the result of variable expansion (step 4). Quote removal (step 9) removes the backslashes and turns the command into date --date="1 days ago". But since parsing (step 1) already has taken place, "1 days ago" is not seen as 1 argument but as 3 separate arguments: "1, days and ago", which gives you the error message:

date: extra operand `ago"'
Try `date --help' for more information.

To force one more run through the parsing/expansion procedure, use:

eval $cmd

Now first $cmd is expanded (steps 1-9) to date --date="1 days ago". Then eval causes the expanded string to be re-parsed again (steps 1-9), resulting in the correct command:

date --date="1 days ago"
Wed Nov 29 08:11:46 CET 2006

类别:默认分类 查看评论
广告赞助商