2016-02-15 88 views
0

我正在为Linux终端编写一个shell脚本。我希望能够将变量输入到提示中。例如Linux shell脚本:允许用户在输入中使用变量

test.sh:

test="Monkey in the middle..." 
read -p "Enter input: " input 
echo $input 

输出:

Enter input: $test 
$test 

我希望能够输入 “$测试”(读-p)提示段时的脚本,并且在末尾有脚本回声“中间的猴子......”,而不是像现在这样回显“$ test”。

我该怎么做呢?



UPDATE:(!非常感谢贡献者和评论家)

使用提供给我在这里和this thread答案,我设法拼凑出这行很努力以及对我来说:

newvariable="$(eval echo $input)" 

是的,建议,我被警告过一次,使用eval可能构成安全风险。记住,如果你选择这个解决方案。

+1

如此疲惫的大脑不应该编程。我将删除评论,但是当您使用'eval'时,问题会变得严重。既然你选择了'eval'加命令替换,保护自己不受意外插入的影响应该成为首要任务(并且会非常棘手 - 我不认为我会确保我能够正确地完成它)。谨防!你被警告过。用户可能会是恶毒的,有时会是偶然的。 –

+0

@JonathanLeffler感谢您的警告。我正在shell中创建一个buckup脚本,我将最终与任何想要使用它的人分享。它们可以输入到提示符中的变量将简单地允许它们将20个字符长的字符串(例如日期/时间戳和PC /平台的名称)替换为2-3个字符长的变量,以便它们不必在每次运行时键入它们剧本。除非用户决定对自己的系统执行攻击,否则对系统的风险是不存在的。 – thebunnyrules

+0

@JonathanLeffler你不是第一个警告我使用eval的人。据我自己的知识,使用它有哪些安全风险?我唯一能想到的是用户可以输入有害的代码到提示中,但是为了做到这一点,他们需要以sudo的方式运行脚本,如果他们已经可以做到这一点,他们可以直接在bash中运行代码。有没有其他的威胁可以构成我没有想到的? – thebunnyrules

回答

1

这个问题有几个不同的答案。

如果您在实际使用bash,看看在bash(1)手册页和阅读参数扩展部分:

如果参数的第一个字符是一个感叹号 (!),它引入了一个可变间接级别。 Bash使用 从其余参数形成的变量的值为 变量的名称;这个变量然后被扩展,并且 该值用于其余的替换,而不是 参数本身的值。这被称为间接 扩展。此例外是下面描述的 ${!prefix*}${!name[@]}的扩展。感叹号 点必须立刻跟着左括号以 介绍间接。

这意味着,如果您有:

read $input 
echo "${!input}" 

且用户输入 “HOME”,你会看到的$HOME值。对于 例如,我的系统上:

Enter input: HOME 
/home/lars 

或者,你可以使用eval命令,它应该工作正常 任何的Bourne外壳般的环境:

EVAL [ARG ...]

参数被读取并连接成一个命令。 然后该命令由shell读取并执行,并且其退出 状态作为eval的值返回。如果没有指定参数时,或仅 空参数,EVAL返回0

您的代码可能是这样的:

read $input 
eval echo "\$$input" 

外壳将首先扩大$input的价值,从而使 所得的命令行 - 假定有人进入HOME在 响应于该提示 - 是:

eval echo $HOME 

Ť他\$只是将$\一起转义,以便在通过命令行传递第一个 期间,shell 不会将其解释为变量的开始。

但这里有一个问题,请考虑:

Enter input: ;date 
$ 
Sun Feb 14 21:13:33 EST 2016 

在这个例子中,分号导致shell执行命令, 这不一定是我们所期望的或需要的。您可以 更好的报价有所缓解此:

eval echo \""$input"\" 

这在上面的例子中的结果:

$ sh foo.sh 
Enter input: ;date 
$;date 

但这里的教训是“不要在安全性敏感 情况下使用eval。”

+0

非常感谢您的帮助。我最终使用了在你的答案的第二部分中提出的eval:newvariable =“$(eval echo $ input)”。 – thebunnyrules