![](/img/trans.png)
[英]How to give the output of a command as a reference to a variable in bash shell
[英]how to redirect command output in bash shell?
我在编写小bash命令时遇到问题。 基本上,我想回显wrapper命令并将真实命令的输出重定向到日志文件。
我的.bashrc中的类似内容不起作用-输出仍然进入控制台。
cmd="some_command >& output.log";
echo $cmd;
$cmd;
但是下面的工作-输出直接进入日志文件。
cmd = "some_command";
echo $cmd" >& output.log";
$cmd >& output.log;
第一种方法有什么问题? 如何解决?
谢谢!
使用eval
可以工作,但是出于安全原因,这是不好的做法。 当您需要在存储以供重用的代码内执行重定向时,Right Thing是定义一个函数:
cmd() { some_command &> output.log; } # define it
declare -p cmd # print it
cmd # run it
如果你不需要重定向,那么正确的做法是一个数组:
cmd=( something 'with spaces' 'in args' ) # define it
printf '%q ' "${cmd[@]}"; echo # print it
"${cmd[@]}" # run it
这是更安全的,因为数组内容不会经过完整的评估传递。 考虑一下您是否使用cmd="something-with $filename"
和filename
包含$(rm -rf /)
。 如果使用eval
,它将运行rm
命令!
为了提供一个更具体的示例,如果以root身份运行,这将使您的系统更加流畅:
# !!! I AM DANGEROUS DO NOT RUN ME !!!
evil_filename='/tmp/foo $(rm -rf /)'
cmd="echo $evil_filename" # define it (BROKEN!)
eval "$cmd" # run it (DANGEROUS!)
另一方面,这将是安全的:
evil_filename='/tmp/foo $(rm -rf /)'
cmd=( echo "$evil_filename" ) # define it (OK!)
printf '%q ' "${cmd[@]}"; echo # print it (OK!)
"${cmd[@]}" # run it (OK!)
...并且即使您省略了一些引号也仍然是安全的-这样做会出错,但仍不会破坏系统:
# I'm broken, but not in a way that damages system security
evil_filename='/tmp/foo $(rm -rf /)'
cmd=( echo $evil_filename ) # define it (BROKEN!)
${cmd[@]} # run it (BROKEN!)
这也是安全的:
evil_filename='/tmp/foo $(rm -rf /)'
cmd() { echo "$1"; } # define it (OK!)
cmd "$evil_filename" # run it (OK!)
有关更深入的讨论,请参阅BashFAQ#50 (关于正确存储命令序列以供重用)和BashFAQ#48 (关于为什么评估很危险)。
第一种方法有什么问题?
当您在变量中包含重定向运算符时,shell不会将其视为特殊字符。 而是将它们视为有关程序的参数。
一种解决方案是利用eval
:
cmd="some command >& output.log";
eval $cmd;
顺便说一句,以下是错误的:
cmd = "some command";
变量分配中不能在=
周围有空格。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.