You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash中如何存储stdin/stdout文件句柄到变量?报错求解

问题描述

编写了如下bash脚本:

STDIN='&0'
if some-condition; then
  STDIN=some-filename
fi

run-command <${STDIN}

运行时出现错误:&0: No such file or directory,针对STDOUT也存在类似问题,尝试过eval但未解决,请问如何修改才能让脚本正常运行?

解决方案

bash中,重定向里的&0(或&1)是文件描述符引用,属于shell语法元素,不能当作普通文件名赋值给变量后再用于重定向——shell会把它当成普通字符串去查找对应文件,这就是报错的原因。以下是几种可行的修改方式:

方式一:直接通过条件分支处理重定向

这是最直观且安全的写法,直接在不同条件下执行带对应重定向的命令:

处理STDIN的情况

if some-condition; then
  run-command < some-filename
else
  run-command  # 默认就从stdin读取,无需额外写<&0
fi

如果明确要显式指定从stdin读取,也可以写run-command <&0,效果和默认一致。

处理STDOUT的情况

if some-condition; then
  run-command > some-filename
else
  run-command >&1  # 或者直接run-command,默认输出到stdout
fi

方式二:用exec复用文件描述符(适合多次使用同一输入/输出源)

如果脚本中需要多次使用这个输入/输出源,可以用exec复制文件描述符,后续命令统一引用该描述符:

处理STDIN的情况

# 复制目标输入到文件描述符3
if some-condition; then
  exec 3< some-filename
else
  exec 3<&0  # 复制stdin到fd3
fi

# 后续所有需要用该输入的命令都可以用<&3
run-command <&3
# another-command <&3

exec 3<&-  # 用完后关闭文件描述符3

处理STDOUT的情况

# 复制目标输出到文件描述符3
if some-condition; then
  exec 3> some-filename
else
  exec 3>&1  # 复制stdout到fd3
fi

# 后续所有需要用该输出的命令都可以用>&3
run-command >&3
# another-command >&3

exec 3>&-  # 用完后关闭文件描述符3

方式三:使用eval(需注意安全风险)

如果一定要通过变量控制重定向,需要把完整的重定向表达式存在变量中,再用eval执行——之前的错误是因为只存了&0,没有包含重定向符号:

处理STDIN的情况

STDIN_REDIRECT=""
if some-condition; then
  STDIN_REDIRECT="< some-filename"
fi

eval "run-command ${STDIN_REDIRECT}"

处理STDOUT的情况

STDOUT_REDIRECT=""
if some-condition; then
  STDOUT_REDIRECT="> some-filename"
fi

eval "run-command ${STDOUT_REDIRECT}"

⚠️ 注意:eval存在安全风险,如果文件名包含空格、特殊字符(如$、*),可能导致意外执行恶意代码,因此优先推荐前两种方式。


内容的提问来源于stack exchange,提问作者Noel Yap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:55:23