![](/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.