gpt4 book ai didi

linux - 如何在 bash shell 中重定向命令输出?

转载 作者:太空宇宙 更新时间:2023-11-04 04:37:04 25 4
gpt4 key购买 nike

我在编写一个小的 bash 命令时遇到问题。基本上我想回显包装器命令并将实际命令的输出重定向到日志文件。

我的 .bashrc 中的类似内容不起作用 - 输出仍然到达控制台。

cmd="some_command >& output.log";
echo $cmd;
$cmd;

但是以下方法有效——输出被定向到日志文件中。

cmd = "some_command";
echo $cmd" >& output.log";
$cmd >& output.log;

第一种方法有什么问题?如何解决?

谢谢!

最佳答案

使用 eval 可以,但出于安全原因,这是不好的做法。当您需要在存储以供重用的代码中执行重定向时,正确的做法是定义一个函数:

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

这更安全,因为数组内容不会经过完整的 eval 传递。考虑一下您是否执行了 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 (关于为什么 eval 是危险的)。

关于linux - 如何在 bash shell 中重定向命令输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22024666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com