问题 在变量中使用文件描述符或文件名重定向


在我的脚本中,我希望能够根据特定条件写入文件或stdout。我很好奇为什么这在我的脚本中不起作用:

out=\&1
echo "bird" 1>$out

我尝试了不同的引号组合,但我继续创建一个“&1”文件,而不是写入stdout。我该怎么做才能让我的工作方式如何?


7733
2017-11-04 23:56


起源

你的系统支持out = / dev / stdout吗? - mob


答案:


一个可能更安全的替代品 eval 是使用将目标复制到临时文件描述符中 exec (本例中的文件描述符3):

if somecondition; then exec 3> destfile; else exec 3>&1; fi

echo bird >&3

5
2017-11-05 00:09



+1,最好避免 eval。 - Dennis Williamson
@Dennis:我真的无法理解eval的陈词滥调......似乎是在stackoverflow中填写所有与bash相关的问题:)再次和千分之一次: eval 是一个工具,而不是一个风险...这就像说你必须避免Lisp,因为你可以将Lisp数据视为代码...... - Diego Sevilla
@Diego: eval 可以是一个有用的工具。它还存在严重的潜在安全风险。如果你避免它,你不必担心这一组特定的风险。它通常很容易避免。尽可能采用简单安全的路线。当你使用 eval 确保您确实需要它并正确清理输入并采取其他必要步骤来防止出现问题。看到 BashFAQ / 048 和 这个优秀的SO问题 (支持和反对)。另外,请注意我说“最好避免”而不是“不要使用”。 - Dennis Williamson
@Dennis:我同意你对“一般”eval使用的大部分看法。但是,在这种情况下,他正在控制所有代码。试图避免使用它是没有意义的 eval 在我完全控制的代码中...... - Diego Sevilla
@Diego:当exec更干净,更容易阅读时,为什么你会在这种情况下使用eval?我相信@Dennis的观点是,在没有明确的选择时你应该只使用eval。在这种情况下有一个更好的选择。 - jabbie


阐述迭戈的答案。改变stdout有条件的地方

if [ someCondition ] ; then
  # all output now goes to $file
  exec 1>$file
fi

echo "bird"

或者创建自己的文件描述符;

if [ someCondition ] ; then
  # 3 points to stdout
  exec 3>&1
else
  # 3 points to a file
  exec 3>$outfile
fi

echo "bird" >&3

改编自: csh编程被认为是有害的  - 检查一下更多的重定向技巧。或者阅读bash手册页。


2
2017-11-05 18:58



我无法在自己的脚本中使用它,因为某些原因我不得不使用完全可变扩展符号,例如: destfile="/some/path"; exec 3>${destfile} - Eliot


截至2015年,可以重定向到 >&${out}。例如。,

exec {out}>&1
echo "bird" 1>&${out}

2
2018-04-01 15:54





我很确定它与订单有关 bash 处理命令行。以下作品:

export out=\&1
eval "echo bird 1>${out}"

因为变量替换发生了 之前 评价。


1
2017-11-05 00:01





试试吧 eval。它应该通过解释的价值来工作 $out 本身:

out='&1'
eval "echo \"bird\" 1>$out"

会打印 bird 在标准输出上(如果更改,则为文件) out)。

请注意,您必须小心eval字符串中的内容。注意带有内部引号的反斜杠,以及变量 $out 在执行eval之前,它被取代(通过双引号)。


0
2017-11-05 00:01